feat: add custom coder bin path for ProxyCommand (#8425)

* feat: add custom coder bin path for ProxyCommand
* force cli path to be absolute (on non-windows)
This commit is contained in:
Steven Masley
2023-07-13 13:17:39 -04:00
committed by GitHub
parent 47d5806e2c
commit c2acc35d45
4 changed files with 73 additions and 13 deletions

View File

@ -198,6 +198,7 @@ func (r *RootCmd) configSSH() *clibase.Cmd {
dryRun bool dryRun bool
skipProxyCommand bool skipProxyCommand bool
forceUnixSeparators bool forceUnixSeparators bool
coderCliPath string
) )
client := new(codersdk.Client) client := new(codersdk.Client)
cmd := &clibase.Cmd{ cmd := &clibase.Cmd{
@ -233,10 +234,16 @@ func (r *RootCmd) configSSH() *clibase.Cmd {
// that it's possible to capture the diff. // that it's possible to capture the diff.
out = inv.Stderr out = inv.Stderr
} }
coderBinary, err := currentBinPath(out)
var err error
coderBinary := coderCliPath
if coderBinary == "" {
coderBinary, err = currentBinPath(out)
if err != nil { if err != nil {
return err return err
} }
}
escapedCoderBinary, err := sshConfigExecEscape(coderBinary, forceUnixSeparators) escapedCoderBinary, err := sshConfigExecEscape(coderBinary, forceUnixSeparators)
if err != nil { if err != nil {
return xerrors.Errorf("escape coder binary for ssh failed: %w", err) return xerrors.Errorf("escape coder binary for ssh failed: %w", err)
@ -501,6 +508,24 @@ func (r *RootCmd) configSSH() *clibase.Cmd {
Description: "Specifies the path to an SSH config.", Description: "Specifies the path to an SSH config.",
Value: clibase.StringOf(&sshConfigFile), Value: clibase.StringOf(&sshConfigFile),
}, },
{
Flag: "coder-binary-path",
Env: "CODER_SSH_CONFIG_BINARY_PATH",
Default: "",
Description: "Optionally specify the absolute path to the coder binary used in ProxyCommand. " +
"By default, the binary invoking this command ('config ssh') is used.",
Value: clibase.Validate(clibase.StringOf(&coderCliPath), func(value *clibase.String) error {
if runtime.GOOS == goosWindows {
// For some reason filepath.IsAbs() does not work on windows.
return nil
}
absolute := filepath.IsAbs(value.String())
if !absolute {
return xerrors.Errorf("coder cli path must be an absolute path")
}
return nil
}),
},
{ {
Flag: "ssh-option", Flag: "ssh-option",
FlagShorthand: "o", FlagShorthand: "o",

View File

@ -217,6 +217,7 @@ func TestConfigSSH_FileWriteAndOptionsFlow(t *testing.T) {
} }
type wantConfig struct { type wantConfig struct {
ssh string ssh string
regexMatch string
} }
type match struct { type match struct {
match, write string match, write string
@ -228,6 +229,7 @@ func TestConfigSSH_FileWriteAndOptionsFlow(t *testing.T) {
writeConfig writeConfig writeConfig writeConfig
wantConfig wantConfig wantConfig wantConfig
wantErr bool wantErr bool
echoResponse *echo.Responses
}{ }{
{ {
name: "Config file is created", name: "Config file is created",
@ -579,6 +581,20 @@ func TestConfigSSH_FileWriteAndOptionsFlow(t *testing.T) {
}, },
wantErr: true, wantErr: true,
}, },
{
name: "Custom CLI Path",
args: []string{
"-y", "--coder-binary-path", "/foo/bar/coder",
},
wantErr: false,
echoResponse: &echo.Responses{
Parse: echo.ParseComplete,
ProvisionApply: echo.ProvisionApplyWithAgent(""),
},
wantConfig: wantConfig{
regexMatch: "ProxyCommand /foo/bar/coder",
},
},
} }
for _, tt := range tests { for _, tt := range tests {
tt := tt tt := tt
@ -588,7 +604,7 @@ func TestConfigSSH_FileWriteAndOptionsFlow(t *testing.T) {
var ( var (
client = coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true}) client = coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
user = coderdtest.CreateFirstUser(t, client) user = coderdtest.CreateFirstUser(t, client)
version = coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil) version = coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, tt.echoResponse)
_ = coderdtest.AwaitTemplateVersionJob(t, client, version.ID) _ = coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
project = coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID) project = coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
workspace = coderdtest.CreateWorkspace(t, client, user.OrganizationID, project.ID) workspace = coderdtest.CreateWorkspace(t, client, user.OrganizationID, project.ID)
@ -627,10 +643,15 @@ func TestConfigSSH_FileWriteAndOptionsFlow(t *testing.T) {
<-done <-done
if tt.wantConfig.ssh != "" { if tt.wantConfig.ssh != "" || tt.wantConfig.regexMatch != "" {
got := sshConfigFileRead(t, sshConfigName) got := sshConfigFileRead(t, sshConfigName)
if tt.wantConfig.ssh != "" {
assert.Equal(t, tt.wantConfig.ssh, got) assert.Equal(t, tt.wantConfig.ssh, got)
} }
if tt.wantConfig.regexMatch != "" {
assert.Regexp(t, tt.wantConfig.regexMatch, got, "regex match")
}
}
}) })
} }
} }

View File

@ -12,6 +12,11 @@ Add an SSH Host entry for your workspaces "ssh coder.workspace"
 $ coder config-ssh --dry-run   $ coder config-ssh --dry-run 
Options Options
--coder-binary-path string, $CODER_SSH_CONFIG_BINARY_PATH
Optionally specify the absolute path to the coder binary used in
ProxyCommand. By default, the binary invoking this command ('config
ssh') is used.
-n, --dry-run bool, $CODER_SSH_DRY_RUN -n, --dry-run bool, $CODER_SSH_DRY_RUN
Perform a trial run with no changes made, showing a diff at the end. Perform a trial run with no changes made, showing a diff at the end.

View File

@ -25,6 +25,15 @@ coder config-ssh [flags]
## Options ## Options
### --coder-binary-path
| | |
| ----------- | ------------------------------------------ |
| Type | <code>string</code> |
| Environment | <code>$CODER_SSH_CONFIG_BINARY_PATH</code> |
Optionally specify the absolute path to the coder binary used in ProxyCommand. By default, the binary invoking this command ('config ssh') is used.
### -n, --dry-run ### -n, --dry-run
| | | | | |