From 252f4f3892d2d45a7f21dc4792dfecf9f9c7d816 Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Tue, 11 Jul 2023 10:55:08 -0400 Subject: [PATCH 1/7] feat: add custom coder bin path for ProxyCommand --- cli/configssh.go | 21 ++++++++++++++++++--- cli/configssh_test.go | 41 +++++++++++++++++++++++++++++++---------- 2 files changed, 49 insertions(+), 13 deletions(-) diff --git a/cli/configssh.go b/cli/configssh.go index f40fe484536b3..2cdf9d8cfd2f5 100644 --- a/cli/configssh.go +++ b/cli/configssh.go @@ -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,14 @@ func (r *RootCmd) configSSH() *clibase.Cmd { Description: "Specifies the path to an SSH config.", Value: clibase.StringOf(&sshConfigFile), }, + { + Flag: "coder-cli-path", + Env: "CODER_SSH_CONFIG_CLI_PATH", + Default: "", + Description: "Optional to specify the path for the coder cli uses in ProxyCommand. " + + "By default, the coder cli used is the same cli being invoked with 'config ssh'.", + Value: clibase.StringOf(&coderCliPath), + }, { Flag: "ssh-option", FlagShorthand: "o", diff --git a/cli/configssh_test.go b/cli/configssh_test.go index f502304373f80..110f37c7d6186 100644 --- a/cli/configssh_test.go +++ b/cli/configssh_test.go @@ -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-cli-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") + } } }) } From ee995276dc17223d2cd90712316348be8f7bd952 Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Tue, 11 Jul 2023 11:00:56 -0400 Subject: [PATCH 2/7] make gen --- cli/testdata/coder_config-ssh_--help.golden | 5 +++++ docs/cli/config-ssh.md | 9 +++++++++ 2 files changed, 14 insertions(+) diff --git a/cli/testdata/coder_config-ssh_--help.golden b/cli/testdata/coder_config-ssh_--help.golden index 857962b27141b..bb5ea24637e41 100644 --- a/cli/testdata/coder_config-ssh_--help.golden +++ b/cli/testdata/coder_config-ssh_--help.golden @@ -12,6 +12,11 @@ Add an SSH Host entry for your workspaces "ssh coder.workspace"  $ coder config-ssh --dry-run  Options + --coder-cli-path string, $CODER_SSH_CONFIG_CLI_PATH + Optional to specify the path for the coder cli uses in ProxyCommand. + By default, the coder cli used is the same cli being invoked with + 'config ssh'. + -n, --dry-run bool, $CODER_SSH_DRY_RUN Perform a trial run with no changes made, showing a diff at the end. diff --git a/docs/cli/config-ssh.md b/docs/cli/config-ssh.md index 6178e207e1d30..48c522fafcc86 100644 --- a/docs/cli/config-ssh.md +++ b/docs/cli/config-ssh.md @@ -25,6 +25,15 @@ coder config-ssh [flags] ## Options +### --coder-cli-path + +| | | +| ----------- | --------------------------------------- | +| Type | string | +| Environment | $CODER_SSH_CONFIG_CLI_PATH | + +Optional to specify the path for the coder cli uses in ProxyCommand. By default, the coder cli used is the same cli being invoked with 'config ssh'. + ### -n, --dry-run | | | From 45bd452eac36a3d2857885618bded0e29f63e80d Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Thu, 13 Jul 2023 07:47:21 -0400 Subject: [PATCH 3/7] force cli path to be absolute --- cli/configssh.go | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/cli/configssh.go b/cli/configssh.go index 2cdf9d8cfd2f5..85f6231459d4d 100644 --- a/cli/configssh.go +++ b/cli/configssh.go @@ -512,9 +512,15 @@ func (r *RootCmd) configSSH() *clibase.Cmd { Flag: "coder-cli-path", Env: "CODER_SSH_CONFIG_CLI_PATH", Default: "", - Description: "Optional to specify the path for the coder cli uses in ProxyCommand. " + + Description: "Optional to specify the absolute path for the coder cli uses in ProxyCommand. " + "By default, the coder cli used is the same cli being invoked with 'config ssh'.", - Value: clibase.StringOf(&coderCliPath), + Value: clibase.Validate(clibase.StringOf(&coderCliPath), func(value *clibase.String) error { + absolute := filepath.IsAbs(value.String()) + if !absolute { + return xerrors.Errorf("coder cli path must be an absolute path") + } + return nil + }), }, { Flag: "ssh-option", From d400d11c0792fc3684264e083828d91b3aaf0c53 Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Thu, 13 Jul 2023 07:48:54 -0400 Subject: [PATCH 4/7] Update text --- cli/configssh.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cli/configssh.go b/cli/configssh.go index 85f6231459d4d..70a82749e6839 100644 --- a/cli/configssh.go +++ b/cli/configssh.go @@ -512,8 +512,8 @@ func (r *RootCmd) configSSH() *clibase.Cmd { Flag: "coder-cli-path", Env: "CODER_SSH_CONFIG_CLI_PATH", Default: "", - Description: "Optional to specify the absolute path for the coder cli uses in ProxyCommand. " + - "By default, the coder cli used is the same cli being invoked with 'config ssh'.", + 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 { absolute := filepath.IsAbs(value.String()) if !absolute { From a7a435e7a8334454208266fb9b9127bc4da5c182 Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Thu, 13 Jul 2023 09:42:09 -0400 Subject: [PATCH 5/7] Rename flag --- cli/configssh.go | 4 ++-- cli/configssh_test.go | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cli/configssh.go b/cli/configssh.go index 70a82749e6839..52f2e2c33145f 100644 --- a/cli/configssh.go +++ b/cli/configssh.go @@ -509,8 +509,8 @@ func (r *RootCmd) configSSH() *clibase.Cmd { Value: clibase.StringOf(&sshConfigFile), }, { - Flag: "coder-cli-path", - Env: "CODER_SSH_CONFIG_CLI_PATH", + 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.", diff --git a/cli/configssh_test.go b/cli/configssh_test.go index 110f37c7d6186..34da7dd03fcc0 100644 --- a/cli/configssh_test.go +++ b/cli/configssh_test.go @@ -584,7 +584,7 @@ func TestConfigSSH_FileWriteAndOptionsFlow(t *testing.T) { { name: "Custom CLI Path", args: []string{ - "-y", "--coder-cli-path", "/foo/bar/coder", + "-y", "--coder-binary-path", "/foo/bar/coder", }, wantErr: false, echoResponse: &echo.Responses{ From d9e12859d8343374c82564b03ce98be55aced8fe Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Thu, 13 Jul 2023 10:40:38 -0400 Subject: [PATCH 6/7] make gen --- cli/testdata/coder_config-ssh_--help.golden | 8 ++++---- docs/cli/config-ssh.md | 12 ++++++------ 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/cli/testdata/coder_config-ssh_--help.golden b/cli/testdata/coder_config-ssh_--help.golden index bb5ea24637e41..8aa547ccb467f 100644 --- a/cli/testdata/coder_config-ssh_--help.golden +++ b/cli/testdata/coder_config-ssh_--help.golden @@ -12,10 +12,10 @@ Add an SSH Host entry for your workspaces "ssh coder.workspace"  $ coder config-ssh --dry-run  Options - --coder-cli-path string, $CODER_SSH_CONFIG_CLI_PATH - Optional to specify the path for the coder cli uses in ProxyCommand. - By default, the coder cli used is the same cli being invoked with - 'config ssh'. + --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. diff --git a/docs/cli/config-ssh.md b/docs/cli/config-ssh.md index 48c522fafcc86..9d5196c824827 100644 --- a/docs/cli/config-ssh.md +++ b/docs/cli/config-ssh.md @@ -25,14 +25,14 @@ coder config-ssh [flags] ## Options -### --coder-cli-path +### --coder-binary-path -| | | -| ----------- | --------------------------------------- | -| Type | string | -| Environment | $CODER_SSH_CONFIG_CLI_PATH | +| | | +| ----------- | ------------------------------------------ | +| Type | string | +| Environment | $CODER_SSH_CONFIG_BINARY_PATH | -Optional to specify the path for the coder cli uses in ProxyCommand. By default, the coder cli used is the same cli being invoked with 'config ssh'. +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 From de4d62863acca7fb8d2d626843a8fa3e56562394 Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Thu, 13 Jul 2023 13:10:59 -0400 Subject: [PATCH 7/7] Fix flag validation --- cli/configssh.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cli/configssh.go b/cli/configssh.go index 52f2e2c33145f..162c3c2a95855 100644 --- a/cli/configssh.go +++ b/cli/configssh.go @@ -515,6 +515,10 @@ func (r *RootCmd) configSSH() *clibase.Cmd { 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")