Skip to content

feat(cli): allow SSH command to connect to running container #16726

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Feb 28, 2025

Conversation

johnstcn
Copy link
Member

@johnstcn johnstcn commented Feb 26, 2025

Fixes #16709 and #16420

Notes:

  • SFTP is currently not supported
  • Haven't tested X11 container forwarding
  • Haven't tested agent forwarding

@johnstcn johnstcn self-assigned this Feb 26, 2025
@johnstcn johnstcn changed the title feat(cli): allow SSH command to connect to running container [ci skip] feat(cli): allow SSH command to connect to running container Feb 27, 2025
@johnstcn johnstcn force-pushed the cj/cli-ssh-container branch from 3692436 to e599cef Compare February 27, 2025 09:16
@johnstcn johnstcn changed the title [ci skip] feat(cli): allow SSH command to connect to running container feat(cli): allow SSH command to connect to running container Feb 27, 2025
@johnstcn johnstcn force-pushed the cj/cli-ssh-container branch from 9780c67 to eec7378 Compare February 27, 2025 12:09
@johnstcn johnstcn force-pushed the cj/cli-ssh-container branch from eec7378 to 3dc994a Compare February 27, 2025 12:19
@johnstcn johnstcn marked this pull request as ready for review February 27, 2025 13:23
@johnstcn johnstcn requested review from mafredri and mtojek February 27, 2025 13:23
@@ -495,30 +526,35 @@ func (s *Server) fileTransferBlocked(session ssh.Session) bool {
return false
}

func (s *Server) sessionStart(logger slog.Logger, session ssh.Session, env []string, magicType MagicSessionType) (retErr error) {
func (s *Server) sessionStart(logger slog.Logger, session ssh.Session, env []string, magicType MagicSessionType, container, containerUser string) (retErr error) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

review: think it might be time to consider an opts struct?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It could be done, but no need to do that yet IMO. If this grows more then probably.

I'd actually want us to refactor the whole session handling and manage our own *session in session.go or some such. But that's a story for another time.

Comment on lines 332 to 344
for _, kv := range env {
if strings.HasPrefix(kv, "CODER_CONTAINER=") {
container = strings.TrimPrefix(kv, "CODER_CONTAINER=")
}

if strings.HasPrefix(kv, "CODER_CONTAINER_USER=") {
containerUser = strings.TrimPrefix(kv, "CODER_CONTAINER_USER=")
}
}

return container, containerUser, slices.DeleteFunc(env, func(kv string) bool {
return strings.HasPrefix(kv, "CODER_CONTAINER=") || strings.HasPrefix(kv, "CODER_CONTAINER_USER=")
})
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

review: inspired by the magic session stuff, this seems to be the only real way to smuggle info betweeen the client and the server.

Copy link
Member

@mtojek mtojek left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking forward to X11 testing!

// ContainerEnvironmentVariable is used to specify the target container for an SSH connection.
// This is stripped from any commands being executed.
// Only available if CODER_AGENT_DEVCONTAINERS_ENABLE=true.
ContainerEnvironmentVariable = "CODER_CONTAINER"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we be more specific about the container here? Is it only Devcontainer?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not forcing it to be :) It can be any container but the UI and coder show should only show devcontainers.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, so in theory a smart Coder user can run any container this way?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, in theory. This is still 'early access' so I'm choosing to not restrict things like this until it makes sense to do so.

Copy link
Member

@mafredri mafredri left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wish we could keep the container specific stuff out of agentssh package, but I don't see a way around it. Glad the invasion is relatively constrained. Nice work!

@@ -495,30 +526,35 @@ func (s *Server) fileTransferBlocked(session ssh.Session) bool {
return false
}

func (s *Server) sessionStart(logger slog.Logger, session ssh.Session, env []string, magicType MagicSessionType) (retErr error) {
func (s *Server) sessionStart(logger slog.Logger, session ssh.Session, env []string, magicType MagicSessionType, container, containerUser string) (retErr error) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It could be done, but no need to do that yet IMO. If this grows more then probably.

I'd actually want us to refactor the whole session handling and manage our own *session in session.go or some such. But that's a story for another time.

// ContainerUserEnvironmentVariable is used to specify the container user for
// an SSH connection.
// Only available if CODER_AGENT_DEVCONTAINERS_ENABLE=true.
ContainerUserEnvironmentVariable = "CODER_CONTAINER_USER"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need to change CODER_CONTAINER or CODER_CONTAINER_USER values, but should we prefix the varsity MagicSession like the other?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I personally dislike the MAGIC_ prefix as it doesn't really impart any information to the reader (except perhaps that it's mysterious and whimsical).

@johnstcn johnstcn merged commit ec44f06 into main Feb 28, 2025
30 checks passed
@johnstcn johnstcn deleted the cj/cli-ssh-container branch February 28, 2025 09:38
@github-actions github-actions bot locked and limited conversation to collaborators Feb 28, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Agent: allow SSH to running container
3 participants