diff --git a/components/local-app/cmd/workspace-ssh.go b/components/local-app/cmd/workspace-ssh.go index 065782e9ea6da6..bfb7d1337e26d8 100644 --- a/components/local-app/cmd/workspace-ssh.go +++ b/components/local-app/cmd/workspace-ssh.go @@ -15,7 +15,16 @@ var dryRun bool var workspaceSSHCmd = &cobra.Command{ Use: "ssh ", Short: "Connects to a workspace via SSH", - Args: cobra.ExactArgs(1), + Args: cobra.MinimumNArgs(1), + Example: ` # connect to workspace with current terminal session + $ gitpod workspace ssh + + # Execute simple command in the workspace + $ gitpod workspace ssh -- ls -la + + # Get all SSH features with --dry-run + $ $(gitpod workspace ssh --dry-run) -- ls -la + $ $(gitpod workspace ssh --dry-run) -t watch date`, RunE: func(cmd *cobra.Command, args []string) error { cmd.SilenceUsage = true @@ -26,7 +35,14 @@ var workspaceSSHCmd = &cobra.Command{ return err } - return helper.SSHConnectToWorkspace(cmd.Context(), gitpod, workspaceID, dryRun) + dashDashIndex := cmd.ArgsLenAtDash() + + sshArgs := []string{} + if dashDashIndex != -1 { + sshArgs = args[dashDashIndex:] + } + + return helper.SSHConnectToWorkspace(cmd.Context(), gitpod, workspaceID, dryRun, sshArgs...) }, } diff --git a/components/local-app/go.mod b/components/local-app/go.mod index 43f0566a9d3d2e..7ab761d6891bd0 100644 --- a/components/local-app/go.mod +++ b/components/local-app/go.mod @@ -88,7 +88,7 @@ require ( github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect golang.org/x/exp v0.0.0-20231006140011-7918f672742d // indirect golang.org/x/net v0.17.0 // indirect - golang.org/x/sys v0.13.0 + golang.org/x/sys v0.13.0 // indirect golang.org/x/text v0.13.0 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/genproto v0.0.0-20230913181813-007df8e322eb // indirect diff --git a/components/local-app/pkg/helper/workspace.go b/components/local-app/pkg/helper/workspace.go index 7cbcc2caa1d9d5..b8c46629071b63 100644 --- a/components/local-app/pkg/helper/workspace.go +++ b/components/local-app/pkg/helper/workspace.go @@ -93,7 +93,7 @@ func OpenWorkspaceInPreferredEditor(ctx context.Context, clnt *client.Gitpod, wo } // SSHConnectToWorkspace connects to the workspace via SSH -func SSHConnectToWorkspace(ctx context.Context, clnt *client.Gitpod, workspaceID string, runDry bool) error { +func SSHConnectToWorkspace(ctx context.Context, clnt *client.Gitpod, workspaceID string, runDry bool, sshArgs ...string) error { workspace, err := clnt.Workspaces.GetWorkspace(ctx, connect.NewRequest(&v1.GetWorkspaceRequest{WorkspaceId: workspaceID})) if err != nil { return err @@ -113,16 +113,20 @@ func SSHConnectToWorkspace(ctx context.Context, clnt *client.Gitpod, workspaceID ownerToken := token.Msg.Token host := WorkspaceSSHHost(wsInfo) + + command := exec.Command("ssh", fmt.Sprintf("%s#%s@%s", wsInfo.WorkspaceId, ownerToken, host), "-o", "StrictHostKeyChecking=no") + if len(sshArgs) > 0 { + slog.Debug("With additional SSH args and command", "with", sshArgs) + command.Args = append(command.Args, "--", strings.Join(sshArgs, " ")) + } if runDry { - fmt.Println("ssh", fmt.Sprintf("%s#%s@%s", wsInfo.WorkspaceId, ownerToken, host), "-o", "StrictHostKeyChecking=no") + fmt.Println(strings.Join(command.Args, " ")) return nil } - - slog.Debug("Connecting to" + wsInfo.Description) - command := exec.Command("ssh", fmt.Sprintf("%s#%s@%s", wsInfo.WorkspaceId, ownerToken, host), "-o", "StrictHostKeyChecking=no") command.Stdin = os.Stdin command.Stdout = os.Stdout command.Stderr = os.Stderr + slog.Debug("Connecting to", "context", wsInfo.Description) err = command.Run() if err != nil { return err