Skip to content

Commit

Permalink
orchard ssh vm: introduce exec mode (#72)
Browse files Browse the repository at this point in the history
* orchard ssh vm: introduce exec mode

* Document "tart vm ssh" exec mode
  • Loading branch information
edigaryev committed Apr 5, 2023
1 parent 4eafec9 commit 316f785
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 4 deletions.
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ orchard list vms

### Accessing Virtual Machines

#### SSH

To SSH into a VM use the `orchard ssh` command:

```shell
Expand All @@ -40,6 +42,20 @@ orchard ssh vm ventura-base

You can specify the `--username` and `--password` flags to specify the username/password pair to SSH. By default, `admin`/`admin` is used.

You can also execute remote commands instead of spawning a login shell, similarly to the OpenSSH's `ssh` command:

```shell
orchard ssh vm ventura-base "uname -a"
```

You can execute scripts remotely this way, by telling the remote command-line interpreter to read from the standard input and using the redirection operator as follows:

```shell
orchard ssh vm ventura-base "bash -s" < script.sh
```

#### VNC

Similar to `ssh` command, you can use `vnc` command to open Screen Sharing into a remote VM:

```shell
Expand Down
29 changes: 25 additions & 4 deletions internal/command/ssh/vm.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ var wait uint16

func newSSHVMCommand() *cobra.Command {
command := &cobra.Command{
Use: "vm VM_NAME",
Use: "vm VM_NAME [COMMAND]",
Short: "SSH into the VM",
Args: cobra.ExactArgs(1),
Args: cobra.RangeArgs(1, 2),
RunE: runSSHVM,
}

Expand All @@ -39,8 +39,16 @@ func newSSHVMCommand() *cobra.Command {
}

func runSSHVM(cmd *cobra.Command, args []string) error {
// Required NAME argument
name := args[0]

// Optional [COMMAND] argument
var command string

if len(args) > 1 {
command = args[1]
}

client, err := client.New()
if err != nil {
return err
Expand Down Expand Up @@ -70,13 +78,27 @@ func runSSHVM(cmd *cobra.Command, args []string) error {
if err != nil {
return fmt.Errorf("%w: failed to establish an SSH connection: %v", ErrFailed, err)
}
defer func() {
_ = sshConn.Close()
}()

sshClient := ssh.NewClient(sshConn, chans, reqs)

sshSess, err := sshClient.NewSession()
if err != nil {
return fmt.Errorf("%w: failed to open an SSH session: %v", ErrFailed, err)
}
defer func() {
_ = sshSess.Close()
}()

if command != "" {
sshSess.Stdout = os.Stdout
sshSess.Stderr = os.Stderr
sshSess.Stdin = os.Stdin

return sshSess.Run(command)
}

// Switch controlling terminal into raw mode,
// otherwise ANSI escape sequences that allow
Expand Down Expand Up @@ -109,7 +131,6 @@ func runSSHVM(cmd *cobra.Command, args []string) error {
go func() {
_, _ = io.Copy(sshSessStdinPipe, os.Stdin)
_ = sshSessStdinPipe.Close()
_ = sshSess.Close()
}()

// Periodically adjust remote terminal size
Expand Down Expand Up @@ -176,7 +197,7 @@ func ChooseUsernameAndPassword(
}

// Fall back
fmt.Println("no credentials specified or found, trying default admin:admin credentials...")
_, _ = fmt.Fprintf(os.Stderr, "no credentials specified or found, trying default admin:admin credentials...")

return "admin", "admin"
}

0 comments on commit 316f785

Please sign in to comment.