Thanks to visit codestin.com
Credit goes to github.com

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

+12-1
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

+63
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

+4
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

+9
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)