mirror of
https://github.com/cirruslabs/orchard.git
synced 2026-10-17 20:25:50 +02:00
orchard ssh vm: introduce exec mode (#72)
* orchard ssh vm: introduce exec mode * Document "tart vm ssh" exec mode
This commit is contained in:
@@ -32,6 +32,8 @@ orchard list vms
|
||||
|
||||
### Accessing Virtual Machines
|
||||
|
||||
#### SSH
|
||||
|
||||
To SSH into a VM use the `orchard ssh` command:
|
||||
|
||||
```shell
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -70,6 +78,9 @@ 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)
|
||||
|
||||
@@ -77,6 +88,17 @@ func runSSHVM(cmd *cobra.Command, args []string) error {
|
||||
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
|
||||
@@ -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
|
||||
@@ -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"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user