Skip to content

Commit 8b43811

Browse files
committed
feat: --ssh-host-prefix flag for "coder ssh"
This adds a flag matching `--ssh-host-prefix` from `coder config-ssh` to `coder ssh`. By trimming a custom prefix from the argument, we can set up wildcard-based `Host` entries in SSH config for the IDE plugins (and eventually `coder config-ssh`). We also replace `--` in the argument with `/`, so ownership can be specified in wildcard-based SSH hosts like `<owner>--<workspace>`.
1 parent 20c36a6 commit 8b43811

File tree

4 files changed

+88
-1
lines changed

4 files changed

+88
-1
lines changed

cli/ssh.go

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ var (
5656
func (r *RootCmd) ssh() *serpent.Command {
5757
var (
5858
stdio bool
59+
hostPrefix string
5960
forwardAgent bool
6061
forwardGPG bool
6162
identityAgent string
@@ -180,7 +181,11 @@ func (r *RootCmd) ssh() *serpent.Command {
180181
parsedEnv = append(parsedEnv, [2]string{k, v})
181182
}
182183

183-
workspace, workspaceAgent, err := getWorkspaceAndAgent(ctx, inv, client, !disableAutostart, inv.Args[0])
184+
namedWorkspace := strings.TrimPrefix(inv.Args[0], hostPrefix)
185+
// Support "--" as a delimiter between owner and workspace name
186+
namedWorkspace = strings.ReplaceAll(namedWorkspace, "--", "/")
187+
188+
workspace, workspaceAgent, err := getWorkspaceAndAgent(ctx, inv, client, !disableAutostart, namedWorkspace)
184189
if err != nil {
185190
return err
186191
}
@@ -477,6 +482,12 @@ func (r *RootCmd) ssh() *serpent.Command {
477482
Description: "Specifies whether to emit SSH output over stdin/stdout.",
478483
Value: serpent.BoolOf(&stdio),
479484
},
485+
{
486+
Flag: "ssh-host-prefix",
487+
Env: "CODER_CONFIGSSH_SSH_HOST_PREFIX",
488+
Description: "Strip this prefix from the provided hostname to determine the workspace name.",
489+
Value: serpent.StringOf(&hostPrefix),
490+
},
480491
{
481492
Flag: "forward-agent",
482493
FlagShorthand: "A",

cli/ssh_test.go

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1482,6 +1482,69 @@ func TestSSH(t *testing.T) {
14821482
})
14831483
}
14841484
})
1485+
1486+
t.Run("SSHHostPrefix", func(t *testing.T) {
1487+
t.Parallel()
1488+
client, workspace, agentToken := setupWorkspaceForAgent(t)
1489+
_, _ = tGoContext(t, func(ctx context.Context) {
1490+
// Run this async so the SSH command has to wait for
1491+
// the build and agent to connect!
1492+
_ = agenttest.New(t, client.URL, agentToken)
1493+
<-ctx.Done()
1494+
})
1495+
1496+
clientOutput, clientInput := io.Pipe()
1497+
serverOutput, serverInput := io.Pipe()
1498+
defer func() {
1499+
for _, c := range []io.Closer{clientOutput, clientInput, serverOutput, serverInput} {
1500+
_ = c.Close()
1501+
}
1502+
}()
1503+
1504+
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
1505+
defer cancel()
1506+
1507+
user, err := client.User(ctx, codersdk.Me)
1508+
require.NoError(t, err)
1509+
1510+
inv, root := clitest.New(t, "ssh", "--stdio", "--ssh-host-prefix", "coder.dummy.com--", fmt.Sprintf("coder.dummy.com--%s--%s", user.Username, workspace.Name))
1511+
clitest.SetupConfig(t, client, root)
1512+
inv.Stdin = clientOutput
1513+
inv.Stdout = serverInput
1514+
inv.Stderr = io.Discard
1515+
1516+
cmdDone := tGo(t, func() {
1517+
err := inv.WithContext(ctx).Run()
1518+
assert.NoError(t, err)
1519+
})
1520+
1521+
conn, channels, requests, err := ssh.NewClientConn(&stdioConn{
1522+
Reader: serverOutput,
1523+
Writer: clientInput,
1524+
}, "", &ssh.ClientConfig{
1525+
// #nosec
1526+
HostKeyCallback: ssh.InsecureIgnoreHostKey(),
1527+
})
1528+
require.NoError(t, err)
1529+
defer conn.Close()
1530+
1531+
sshClient := ssh.NewClient(conn, channels, requests)
1532+
session, err := sshClient.NewSession()
1533+
require.NoError(t, err)
1534+
defer session.Close()
1535+
1536+
command := "sh -c exit"
1537+
if runtime.GOOS == "windows" {
1538+
command = "cmd.exe /c exit"
1539+
}
1540+
err = session.Run(command)
1541+
require.NoError(t, err)
1542+
err = sshClient.Close()
1543+
require.NoError(t, err)
1544+
_ = clientOutput.Close()
1545+
1546+
<-cmdDone
1547+
})
14851548
}
14861549

14871550
//nolint:paralleltest // This test uses t.Setenv, parent test MUST NOT be parallel.

cli/testdata/coder_ssh_--help.golden

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@ OPTIONS:
3939
-R, --remote-forward string-array, $CODER_SSH_REMOTE_FORWARD
4040
Enable remote port forwarding (remote_port:local_address:local_port).
4141

42+
--ssh-host-prefix string, $CODER_CONFIGSSH_SSH_HOST_PREFIX
43+
Strip this prefix from the provided hostname to determine the
44+
workspace name.
45+
4246
--stdio bool, $CODER_SSH_STDIO
4347
Specifies whether to emit SSH output over stdin/stdout.
4448

docs/reference/cli/ssh.md

Lines changed: 9 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy