Skip to content

Commit c707dca

Browse files
committed
Reconnecting to existing containers (fix #14)
1 parent e0bd11e commit c707dca

1 file changed

Lines changed: 31 additions & 7 deletions

File tree

client.go

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ type Client struct {
2626
Server *Server
2727
Pty, Tty *os.File
2828
Env Environment
29+
RemoteUser string
30+
ImageName string
2931
}
3032

3133
// NewClient initializes a new client
@@ -37,13 +39,16 @@ func NewClient(conn *ssh.ServerConn, chans <-chan ssh.NewChannel, reqs <-chan *s
3739
Chans: chans,
3840
Reqs: reqs,
3941
Server: server,
42+
ImageName: conn.User(),
43+
RemoteUser: "nobody",
4044
Env: Environment{
4145
"TERM": os.Getenv("TERM"),
4246
"DOCKER_HOST": os.Getenv("DOCKER_HOST"),
4347
"DOCKER_CERT_PATH": os.Getenv("DOCKER_CERT_PATH"),
4448
"DOCKER_TLS_VERIFY": os.Getenv("DOCKER_TLS_VERIFY"),
4549
},
4650
}
51+
4752
clientCounter++
4853

4954
logrus.Infof("NewClient (%d): User=%q, ClientVersion=%q", client.Idx, conn.User(), fmt.Sprintf("%x", conn.ClientVersion()))
@@ -116,12 +121,31 @@ func (c *Client) HandleChannelRequests(channel ssh.Channel, requests <-chan *ssh
116121
}
117122
ok = true
118123

119-
args := []string{"run"}
120-
args = append(args, c.Server.DockerRunArgs...)
121-
args = append(args, c.Conn.User(), c.Server.DefaultShell)
122-
logrus.Debugf("Executing 'docker %s'", strings.Join(args, " "))
123-
cmd := exec.Command("docker", args...)
124-
cmd.Env = c.Env.List()
124+
// checking if a container already exists for this user
125+
cmd := exec.Command("docker", "ps", "--filter=label=ssh2docker", "--filter=label=image:ubuntu", "--filter=label=user:nobody", "--quiet", "--no-trunc")
126+
buf, err := cmd.CombinedOutput()
127+
if err != nil {
128+
logrus.Warnf("docker ps ... failed: %v", err)
129+
continue
130+
}
131+
existingContainer := strings.TrimSpace(string(buf))
132+
133+
// Opening Docker process
134+
if existingContainer != "" {
135+
// Attaching to an existing container
136+
args := []string{"exec", "-it", existingContainer, c.Server.DefaultShell}
137+
logrus.Debugf("Executing 'docker %s'", strings.Join(args, " "))
138+
cmd = exec.Command("docker", args...)
139+
} else {
140+
// Creating and attaching to a new container
141+
args := []string{"run"}
142+
args = append(args, c.Server.DockerRunArgs...)
143+
args = append(args, "--label=ssh2docker", fmt.Sprintf("--label=user:%s", c.RemoteUser), fmt.Sprintf("--label=image:%s", c.ImageName))
144+
args = append(args, c.ImageName, c.Server.DefaultShell)
145+
logrus.Debugf("Executing 'docker %s'", strings.Join(args, " "))
146+
cmd = exec.Command("docker", args...)
147+
cmd.Env = c.Env.List()
148+
}
125149

126150
defer c.Tty.Close()
127151
cmd.Stdout = c.Tty
@@ -132,7 +156,7 @@ func (c *Client) HandleChannelRequests(channel ssh.Channel, requests <-chan *ssh
132156
Setsid: true,
133157
}
134158

135-
err := cmd.Start()
159+
err = cmd.Start()
136160
if err != nil {
137161
logrus.Warnf("cmd.Start failed: %v", err)
138162
continue

0 commit comments

Comments
 (0)