1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: AGPL-3.0
15 "git.arvados.org/arvados.git/lib/config"
16 "git.arvados.org/arvados.git/lib/crunchrun"
17 "git.arvados.org/arvados.git/sdk/go/arvados"
18 "git.arvados.org/arvados.git/sdk/go/arvadostest"
19 "git.arvados.org/arvados.git/sdk/go/auth"
20 "git.arvados.org/arvados.git/sdk/go/ctxlog"
21 check "gopkg.in/check.v1"
24 var _ = check.Suite(&ContainerGatewaySuite{})
26 type ContainerGatewaySuite struct {
27 cluster *arvados.Cluster
34 func (s *ContainerGatewaySuite) TearDownSuite(c *check.C) {
35 // Undo any changes/additions to the user database so they
36 // don't affect subsequent tests.
37 arvadostest.ResetEnv()
38 c.Check(arvados.NewClientFromEnv().RequestAndDecode(nil, "POST", "database/reset", nil, nil), check.IsNil)
41 func (s *ContainerGatewaySuite) SetUpSuite(c *check.C) {
42 cfg, err := config.NewLoader(nil, ctxlog.TestLogger(c)).Load()
43 c.Assert(err, check.IsNil)
44 s.cluster, err = cfg.GetCluster("")
45 c.Assert(err, check.IsNil)
46 s.localdb = NewConn(s.cluster)
47 s.ctx = auth.NewContext(context.Background(), &auth.Credentials{Tokens: []string{arvadostest.ActiveTokenV2}})
49 s.ctrUUID = arvadostest.QueuedContainerUUID
51 h := hmac.New(sha256.New, []byte(s.cluster.SystemRootToken))
52 fmt.Fprint(h, s.ctrUUID)
53 authKey := fmt.Sprintf("%x", h.Sum(nil))
55 s.gw = &crunchrun.Gateway{
56 DockerContainerID: new(string),
57 ContainerUUID: s.ctrUUID,
59 Address: "localhost:0",
60 Log: ctxlog.TestLogger(c),
62 c.Assert(s.gw.Start(), check.IsNil)
63 rootctx := auth.NewContext(context.Background(), &auth.Credentials{Tokens: []string{s.cluster.SystemRootToken}})
64 _, err = s.localdb.ContainerUpdate(rootctx, arvados.UpdateOptions{
66 Attrs: map[string]interface{}{
67 "state": arvados.ContainerStateLocked}})
68 c.Assert(err, check.IsNil)
69 _, err = s.localdb.ContainerUpdate(rootctx, arvados.UpdateOptions{
71 Attrs: map[string]interface{}{
72 "state": arvados.ContainerStateRunning,
73 "gateway_address": s.gw.Address}})
74 c.Assert(err, check.IsNil)
77 func (s *ContainerGatewaySuite) TestConnect(c *check.C) {
78 c.Logf("connecting to %s", s.gw.Address)
79 sshconn, err := s.localdb.ContainerSSH(s.ctx, arvados.ContainerSSHOptions{UUID: s.ctrUUID})
80 c.Assert(err, check.IsNil)
81 c.Assert(sshconn.Conn, check.NotNil)
82 defer sshconn.Conn.Close()
84 done := make(chan struct{})
88 // Receive text banner
89 buf := make([]byte, 12)
90 _, err := io.ReadFull(sshconn.Conn, buf)
91 c.Check(err, check.IsNil)
92 c.Check(string(buf), check.Equals, "SSH-2.0-Go\r\n")
95 _, err = sshconn.Conn.Write([]byte("SSH-2.0-Fake\r\n"))
96 c.Check(err, check.IsNil)
99 _, err = io.ReadFull(sshconn.Conn, buf[:4])
100 c.Check(err, check.IsNil)
101 c.Check(buf[:4], check.DeepEquals, []byte{0, 0, 1, 0xfc})
103 // If we can get this far into an SSH handshake...
104 c.Log("success, tunnel is working")
108 case <-time.After(time.Second):
113 func (s *ContainerGatewaySuite) TestConnectFail(c *check.C) {
114 c.Log("trying with no token")
115 ctx := auth.NewContext(context.Background(), &auth.Credentials{})
116 _, err := s.localdb.ContainerSSH(ctx, arvados.ContainerSSHOptions{UUID: s.ctrUUID})
117 c.Check(err, check.ErrorMatches, `.* 401 .*`)
119 c.Log("trying with anonymous token")
120 ctx = auth.NewContext(context.Background(), &auth.Credentials{Tokens: []string{arvadostest.AnonymousToken}})
121 _, err = s.localdb.ContainerSSH(ctx, arvados.ContainerSSHOptions{UUID: s.ctrUUID})
122 c.Check(err, check.ErrorMatches, `.* 404 .*`)