21316: Merge commit '1416f698b72de4b09350d9c2fb25c1405c3247bc' into 21316-left-panel...
[arvados.git] / cmd / arvados-client / container_gateway.go
index 94375075c0fd6b68425d49b8351cfe8f1a026b0a..2baa8012eae6dcb49c9ac9f4bd06e29f46a948b1 100644 (file)
@@ -33,6 +33,7 @@ type logsCommand struct {
 
 func (lc logsCommand) RunCommand(prog string, args []string, stdin io.Reader, stdout, stderr io.Writer) int {
        f := flag.NewFlagSet(prog, flag.ContinueOnError)
+       follow := f.Bool("f", false, "follow: poll for new data until the container finishes")
        pollInterval := f.Duration("poll", time.Second*2, "minimum duration to wait before polling for new data")
        if ok, code := cmd.ParseFlags(f, prog, args, "container-request-uuid", stderr); !ok {
                return code
@@ -53,7 +54,7 @@ func (lc logsCommand) RunCommand(prog string, args []string, stdin io.Reader, st
                                InsecureSkipVerify: true}}
        }
 
-       err := lc.tailf(target, stdout, stderr, *pollInterval)
+       err := lc.tail(target, stdout, stderr, *follow, *pollInterval)
        if err != nil {
                fmt.Fprintln(stderr, err)
                return 1
@@ -61,12 +62,15 @@ func (lc logsCommand) RunCommand(prog string, args []string, stdin io.Reader, st
        return 0
 }
 
-func (lc *logsCommand) tailf(crUUID string, stdout, stderr io.Writer, pollInterval time.Duration) error {
+func (lc *logsCommand) tail(crUUID string, stdout, stderr io.Writer, follow bool, pollInterval time.Duration) error {
        ctx, cancel := context.WithCancel(context.Background())
        defer cancel()
 
-       rpcconn := rpcFromEnv()
-       err := lc.checkAPISupport(ctx, crUUID)
+       rpcconn, err := rpcFromEnv()
+       if err != nil {
+               return err
+       }
+       err = lc.checkAPISupport(ctx, crUUID)
        if err != nil {
                return err
        }
@@ -157,7 +161,7 @@ poll:
                        displayingUUID = cr.ContainerUUID
                        delay = 0
                        continue
-               } else if cr.State == arvados.ContainerRequestStateFinal {
+               } else if cr.State == arvados.ContainerRequestStateFinal || !follow {
                        break
                } else if len(newData) > 0 {
                        delay = pollInterval
@@ -400,12 +404,12 @@ Options:
                loginUsername = targetUUID[:i]
                targetUUID = targetUUID[i+1:]
        }
-       if os.Getenv("ARVADOS_API_HOST") == "" || os.Getenv("ARVADOS_API_TOKEN") == "" {
-               fmt.Fprintln(stderr, "fatal: ARVADOS_API_HOST and ARVADOS_API_TOKEN environment variables are not set")
+       rpcconn, err := rpcFromEnv()
+       if err != nil {
+               fmt.Fprintln(stderr, err)
                return 1
        }
-       rpcconn := rpcFromEnv()
-       targetUUID, err := resolveToContainerUUID(rpcconn, targetUUID)
+       targetUUID, err = resolveToContainerUUID(rpcconn, targetUUID)
        if err != nil {
                fmt.Fprintln(stderr, err)
                return 1
@@ -452,17 +456,20 @@ func shellescape(s string) string {
        return "'" + strings.Replace(s, "'", "'\\''", -1) + "'"
 }
 
-func rpcFromEnv() *rpc.Conn {
-       insecure := os.Getenv("ARVADOS_API_HOST_INSECURE")
+func rpcFromEnv() (*rpc.Conn, error) {
+       ac := arvados.NewClientFromEnv()
+       if ac.APIHost == "" || ac.AuthToken == "" {
+               return nil, fmt.Errorf("fatal: ARVADOS_API_HOST and ARVADOS_API_TOKEN environment variables are not set, and ~/.config/arvados/settings.conf is not readable")
+       }
        return rpc.NewConn("",
                &url.URL{
                        Scheme: "https",
-                       Host:   os.Getenv("ARVADOS_API_HOST"),
+                       Host:   ac.APIHost,
                },
-               insecure == "1" || insecure == "yes" || insecure == "true",
+               ac.Insecure,
                func(context.Context) ([]string, error) {
-                       return []string{os.Getenv("ARVADOS_API_TOKEN")}, nil
-               })
+                       return []string{ac.AuthToken}, nil
+               }), nil
 }
 
 func resolveToContainerUUID(rpcconn *rpc.Conn, targetUUID string) (string, error) {