mirror of
https://github.com/coder/coder.git
synced 2025-07-09 11:45:56 +00:00
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:
@ -198,6 +198,7 @@ func (r *RootCmd) configSSH() *clibase.Cmd {
|
||||
dryRun bool
|
||||
skipProxyCommand bool
|
||||
forceUnixSeparators bool
|
||||
coderCliPath string
|
||||
)
|
||||
client := new(codersdk.Client)
|
||||
cmd := &clibase.Cmd{
|
||||
@ -233,10 +234,16 @@ func (r *RootCmd) configSSH() *clibase.Cmd {
|
||||
// that it's possible to capture the diff.
|
||||
out = inv.Stderr
|
||||
}
|
||||
coderBinary, err := currentBinPath(out)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
var err error
|
||||
coderBinary := coderCliPath
|
||||
if coderBinary == "" {
|
||||
coderBinary, err = currentBinPath(out)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
escapedCoderBinary, err := sshConfigExecEscape(coderBinary, forceUnixSeparators)
|
||||
if err != nil {
|
||||
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.",
|
||||
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",
|
||||
FlagShorthand: "o",
|
||||
|
@ -216,18 +216,20 @@ func TestConfigSSH_FileWriteAndOptionsFlow(t *testing.T) {
|
||||
ssh string
|
||||
}
|
||||
type wantConfig struct {
|
||||
ssh string
|
||||
ssh string
|
||||
regexMatch string
|
||||
}
|
||||
type match struct {
|
||||
match, write string
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args []string
|
||||
matches []match
|
||||
writeConfig writeConfig
|
||||
wantConfig wantConfig
|
||||
wantErr bool
|
||||
name string
|
||||
args []string
|
||||
matches []match
|
||||
writeConfig writeConfig
|
||||
wantConfig wantConfig
|
||||
wantErr bool
|
||||
echoResponse *echo.Responses
|
||||
}{
|
||||
{
|
||||
name: "Config file is created",
|
||||
@ -579,6 +581,20 @@ func TestConfigSSH_FileWriteAndOptionsFlow(t *testing.T) {
|
||||
},
|
||||
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 {
|
||||
tt := tt
|
||||
@ -588,7 +604,7 @@ func TestConfigSSH_FileWriteAndOptionsFlow(t *testing.T) {
|
||||
var (
|
||||
client = coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
|
||||
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)
|
||||
project = coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
|
||||
workspace = coderdtest.CreateWorkspace(t, client, user.OrganizationID, project.ID)
|
||||
@ -627,9 +643,14 @@ func TestConfigSSH_FileWriteAndOptionsFlow(t *testing.T) {
|
||||
|
||||
<-done
|
||||
|
||||
if tt.wantConfig.ssh != "" {
|
||||
if tt.wantConfig.ssh != "" || tt.wantConfig.regexMatch != "" {
|
||||
got := sshConfigFileRead(t, sshConfigName)
|
||||
assert.Equal(t, tt.wantConfig.ssh, got)
|
||||
if tt.wantConfig.ssh != "" {
|
||||
assert.Equal(t, tt.wantConfig.ssh, got)
|
||||
}
|
||||
if tt.wantConfig.regexMatch != "" {
|
||||
assert.Regexp(t, tt.wantConfig.regexMatch, got, "regex match")
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
5
cli/testdata/coder_config-ssh_--help.golden
vendored
5
cli/testdata/coder_config-ssh_--help.golden
vendored
@ -12,6 +12,11 @@ Add an SSH Host entry for your workspaces "ssh coder.workspace"
|
||||
[40m [0m[91;40m$ coder config-ssh --dry-run[0m[40m [0m
|
||||
|
||||
[1mOptions[0m
|
||||
--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
|
||||
Perform a trial run with no changes made, showing a diff at the end.
|
||||
|
||||
|
@ -25,6 +25,15 @@ coder config-ssh [flags]
|
||||
|
||||
## 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
|
||||
|
||||
| | |
|
||||
|
Reference in New Issue
Block a user