Skip to content

Commit 56538a9

Browse files
committed
fixup! feat(cli): add capability for SSH command to connect to a running container
1 parent 3dc994a commit 56538a9

File tree

3 files changed

+30
-8
lines changed

3 files changed

+30
-8
lines changed

agent/agentssh/agentssh.go

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,14 @@ const (
6161
// MagicSessionTypeEnvironmentVariable is used to track the purpose behind an SSH connection.
6262
// This is stripped from any commands being executed, and is counted towards connection stats.
6363
MagicSessionTypeEnvironmentVariable = "CODER_SSH_SESSION_TYPE"
64+
// ContainerEnvironmentVariable is used to specify the target container for an SSH connection.
65+
// This is stripped from any commands being executed.
66+
// Only available if CODER_AGENT_DEVCONTAINERS_ENABLE=true.
67+
ContainerEnvironmentVariable = "CODER_CONTAINER"
68+
// ContainerUserEnvironmentVariable is used to specify the container user for
69+
// an SSH connection.
70+
// Only available if CODER_AGENT_DEVCONTAINERS_ENABLE=true.
71+
ContainerUserEnvironmentVariable = "CODER_CONTAINER_USER"
6472
)
6573

6674
// MagicSessionType enums.
@@ -330,17 +338,17 @@ func (s *sessionCloseTracker) Close() error {
330338

331339
func extractContainerInfo(env []string) (container, containerUser string, filteredEnv []string) {
332340
for _, kv := range env {
333-
if strings.HasPrefix(kv, "CODER_CONTAINER=") {
334-
container = strings.TrimPrefix(kv, "CODER_CONTAINER=")
341+
if strings.HasPrefix(kv, ContainerEnvironmentVariable+"=") {
342+
container = strings.TrimPrefix(kv, ContainerEnvironmentVariable+"=")
335343
}
336344

337-
if strings.HasPrefix(kv, "CODER_CONTAINER_USER=") {
338-
containerUser = strings.TrimPrefix(kv, "CODER_CONTAINER_USER=")
345+
if strings.HasPrefix(kv, ContainerUserEnvironmentVariable+"=") {
346+
containerUser = strings.TrimPrefix(kv, ContainerUserEnvironmentVariable+"=")
339347
}
340348
}
341349

342350
return container, containerUser, slices.DeleteFunc(env, func(kv string) bool {
343-
return strings.HasPrefix(kv, "CODER_CONTAINER=") || strings.HasPrefix(kv, "CODER_CONTAINER_USER=")
351+
return strings.HasPrefix(kv, ContainerEnvironmentVariable+"=") || strings.HasPrefix(kv, ContainerUserEnvironmentVariable+"=")
344352
})
345353
}
346354

@@ -536,7 +544,6 @@ func (s *Server) sessionStart(logger slog.Logger, session ssh.Session, env []str
536544
ptyLabel = "yes"
537545
}
538546

539-
// plumb in envinfoer here to modify command for container exec?
540547
var ei usershell.EnvInfoer
541548
var err error
542549
if s.config.ExperimentalContainersEnabled && container != "" {

cli/ssh.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ import (
3434

3535
"cdr.dev/slog"
3636
"cdr.dev/slog/sloggers/sloghuman"
37+
"github.com/coder/coder/v2/agent/agentssh"
3738
"github.com/coder/coder/v2/cli/cliui"
3839
"github.com/coder/coder/v2/cli/cliutil"
3940
"github.com/coder/coder/v2/coderd/autobuild/notify"
@@ -476,8 +477,8 @@ func (r *RootCmd) ssh() *serpent.Command {
476477

477478
if container != "" {
478479
for k, v := range map[string]string{
479-
"CODER_CONTAINER": container,
480-
"CODER_CONTAINER_USER": containerUser,
480+
agentssh.ContainerEnvironmentVariable: container,
481+
agentssh.ContainerUserEnvironmentVariable: containerUser,
481482
} {
482483
if err := sshSession.Setenv(k, v); err != nil {
483484
return xerrors.Errorf("setenv: %w", err)

cli/ssh_test.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1994,6 +1994,20 @@ func TestSSH_Container(t *testing.T) {
19941994
err := inv.WithContext(ctx).Run()
19951995
require.ErrorContains(t, err, "container not found:")
19961996
})
1997+
1998+
t.Run("NotEnabled", func(t *testing.T) {
1999+
t.Parallel()
2000+
2001+
ctx := testutil.Context(t, testutil.WaitShort)
2002+
client, workspace, agentToken := setupWorkspaceForAgent(t)
2003+
_ = agenttest.New(t, client.URL, agentToken)
2004+
_ = coderdtest.NewWorkspaceAgentWaiter(t, client, workspace.ID).Wait()
2005+
2006+
inv, root := clitest.New(t, "ssh", workspace.Name, "-c", uuid.NewString())
2007+
clitest.SetupConfig(t, client, root)
2008+
err := inv.WithContext(ctx).Run()
2009+
require.ErrorContains(t, err, "container not found:")
2010+
})
19972011
}
19982012

19992013
// tGoContext runs fn in a goroutine passing a context that will be

0 commit comments

Comments
 (0)