20757: `arvados-client shell` uses settings.conf if present.
authorTom Clegg <tom@curii.com>
Fri, 25 Aug 2023 16:28:56 +0000 (12:28 -0400)
committerTom Clegg <tom@curii.com>
Fri, 25 Aug 2023 16:28:56 +0000 (12:28 -0400)
Arvados-DCO-1.1-Signed-off-by: Tom Clegg <tom@curii.com>

cmd/arvados-client/container_gateway.go
cmd/arvados-client/container_gateway_test.go

index 7b52cc3a646e4612167b9bd9694213cb427f0c8a..2baa8012eae6dcb49c9ac9f4bd06e29f46a948b1 100644 (file)
@@ -66,8 +66,11 @@ func (lc *logsCommand) tail(crUUID string, stdout, stderr io.Writer, follow bool
        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
        }
@@ -401,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
@@ -453,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) {
index 761a7c3ef50594484e5c44647661eddc971649b1..ec195569a6b212def135cc2967665b2a4107e648 100644 (file)
@@ -49,6 +49,20 @@ func (s *ClientSuite) TestShellGateway(c *check.C) {
        defer func() {
                c.Check(arvados.NewClientFromEnv().RequestAndDecode(nil, "POST", "database/reset", nil, nil), check.IsNil)
        }()
+       homedir := c.MkDir()
+       settings := "ARVADOS_API_HOST=" + os.Getenv("ARVADOS_API_HOST") + "\nARVADOS_API_TOKEN=" + arvadostest.ActiveTokenV2 + "\nARVADOS_API_HOST_INSECURE=true\n"
+       err := os.MkdirAll(homedir+"/.config/arvados", 0777)
+       c.Assert(err, check.IsNil)
+       err = os.WriteFile(homedir+"/.config/arvados/settings.conf", []byte(settings), 0777)
+       c.Assert(err, check.IsNil)
+
+       c.Logf("building arvados-client binary in %s", homedir)
+       cmd := exec.Command("go", "install", ".")
+       cmd.Env = append(os.Environ(), "GOBIN="+homedir)
+       cmd.Stdout = os.Stdout
+       cmd.Stderr = os.Stderr
+       c.Assert(cmd.Run(), check.IsNil)
+
        uuid := arvadostest.QueuedContainerUUID
        h := hmac.New(sha256.New, []byte(arvadostest.SystemRootToken))
        fmt.Fprint(h, uuid)
@@ -63,7 +77,7 @@ func (s *ClientSuite) TestShellGateway(c *check.C) {
                // container.
                Target: crunchrun.GatewayTargetStub{},
        }
-       err := gw.Start()
+       err = gw.Start()
        c.Assert(err, check.IsNil)
 
        rpcconn := rpc.NewConn("",
@@ -85,8 +99,13 @@ func (s *ClientSuite) TestShellGateway(c *check.C) {
        }})
        c.Assert(err, check.IsNil)
 
+       c.Log("connecting using ARVADOS_* env vars")
        var stdout, stderr bytes.Buffer
-       cmd := exec.Command("go", "run", ".", "shell", uuid, "-o", "controlpath=none", "-o", "userknownhostsfile="+c.MkDir()+"/known_hosts", "echo", "ok")
+       cmd = exec.Command(
+               homedir+"/arvados-client", "shell", uuid,
+               "-o", "controlpath=none",
+               "-o", "userknownhostsfile="+homedir+"/known_hosts",
+               "echo", "ok")
        cmd.Env = append(cmd.Env, os.Environ()...)
        cmd.Env = append(cmd.Env, "ARVADOS_API_TOKEN="+arvadostest.ActiveTokenV2)
        cmd.Stdout = &stdout
@@ -94,13 +113,16 @@ func (s *ClientSuite) TestShellGateway(c *check.C) {
        stdin, err := cmd.StdinPipe()
        c.Assert(err, check.IsNil)
        go fmt.Fprintln(stdin, "data appears on stdin, but stdin does not close; cmd should exit anyway, not hang")
-       time.AfterFunc(5*time.Second, func() {
+       timeout := time.AfterFunc(5*time.Second, func() {
                c.Errorf("timed out -- remote end is probably hung waiting for us to close stdin")
                stdin.Close()
        })
+       c.Logf("cmd.Args: %s", cmd.Args)
        c.Check(cmd.Run(), check.IsNil)
+       timeout.Stop()
        c.Check(stdout.String(), check.Equals, "ok\n")
 
+       c.Logf("setting up an http server")
        // Set up an http server, and try using "arvados-client shell"
        // to forward traffic to it.
        httpTarget := &httpserver.Server{}
@@ -120,22 +142,27 @@ func (s *ClientSuite) TestShellGateway(c *check.C) {
        _, forwardedPort, _ := net.SplitHostPort(ln.Addr().String())
        ln.Close()
 
+       c.Log("connecting using settings.conf file")
        stdout.Reset()
        stderr.Reset()
        ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(10*time.Second))
        defer cancel()
        cmd = exec.CommandContext(ctx,
-               "go", "run", ".", "shell", uuid,
+               homedir+"/arvados-client", "shell", uuid,
                "-L", forwardedPort+":"+httpTarget.Addr,
                "-o", "controlpath=none",
-               "-o", "userknownhostsfile="+c.MkDir()+"/known_hosts",
+               "-o", "userknownhostsfile="+homedir+"/known_hosts",
                "-N",
        )
-       c.Logf("cmd.Args: %s", cmd.Args)
-       cmd.Env = append(cmd.Env, os.Environ()...)
-       cmd.Env = append(cmd.Env, "ARVADOS_API_TOKEN="+arvadostest.ActiveTokenV2)
+       for _, kv := range os.Environ() {
+               if !strings.HasPrefix(kv, "ARVADOS_") && !strings.HasPrefix(kv, "HOME=") {
+                       cmd.Env = append(cmd.Env, kv)
+               }
+       }
+       cmd.Env = append(cmd.Env, "HOME="+homedir)
        cmd.Stdout = &stdout
        cmd.Stderr = &stderr
+       c.Logf("cmd.Args: %s", cmd.Args)
        cmd.Start()
 
        forwardedURL := fmt.Sprintf("http://localhost:%s/foo", forwardedPort)