docs/commands/ssh.go

89 lines
1.9 KiB
Go

package commands
import (
"fmt"
"strings"
"github.com/docker/machine/log"
"github.com/docker/machine/state"
"github.com/codegangsta/cli"
)
func cmdSsh(c *cli.Context) {
args := c.Args()
name := args.First()
cmd := ""
if name == "" {
log.Fatal("Error: Please specify a machine name.")
}
certInfo := getCertPathInfo(c)
defaultStore, err := getDefaultStore(
c.GlobalString("storage-path"),
certInfo.CaCertPath,
certInfo.CaKeyPath,
)
if err != nil {
log.Fatal(err)
}
provider, err := newProvider(defaultStore)
if err != nil {
log.Fatal(err)
}
host, err := provider.Get(name)
if err != nil {
log.Fatal(err)
}
currentState, err := host.Driver.GetState()
if err != nil {
log.Fatal(err)
}
if currentState != state.Running {
log.Fatalf("Error: Cannot run SSH command: Host %q is not running", host.Name)
}
// Loop through the arguments and parse out a command which relies on
// flags if it exists, for instance an invocation of the form
// `docker-machine ssh dev -- df -h` would mandate this, otherwise we
// will accidentally trigger the codegangsta/cli help text because it
// thinks we are trying to specify codegangsta flags.
//
// TODO: I thought codegangsta/cli supported the flag parsing
// terminator manually, which would mitigate the need for this kind of
// hack. We should investigate.
for i, arg := range args {
if arg == "--" {
cmd = strings.Join(args[i+1:], " ")
break
}
}
// It is possible that the user has specified an appended command which
// does not rely on the flag parsing terminator, such as
// `docker-machine ssh dev ls`, so this block accounts for that case.
if len(cmd) == 0 {
cmd = strings.Join(args[1:], " ")
}
if len(c.Args()) == 1 {
err := host.CreateSSHShell()
if err != nil {
log.Fatal(err)
}
} else {
output, err := host.RunSSHCommand(cmd)
if err != nil {
log.Fatal(err)
}
fmt.Print(output)
}
}