mirror of https://github.com/docker/docs.git
499 lines
9.6 KiB
Go
499 lines
9.6 KiB
Go
package main
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"os"
|
|
"reflect"
|
|
"strings"
|
|
"sync"
|
|
"text/tabwriter"
|
|
|
|
log "github.com/Sirupsen/logrus"
|
|
flag "github.com/docker/docker/pkg/mflag"
|
|
|
|
"github.com/docker/machine/drivers"
|
|
_ "github.com/docker/machine/drivers/azure"
|
|
_ "github.com/docker/machine/drivers/digitalocean"
|
|
_ "github.com/docker/machine/drivers/none"
|
|
_ "github.com/docker/machine/drivers/virtualbox"
|
|
)
|
|
|
|
type DockerCli struct{}
|
|
|
|
func (cli *DockerCli) getMethod(args ...string) (func(...string) error, bool) {
|
|
camelArgs := make([]string, len(args))
|
|
for i, s := range args {
|
|
if len(s) == 0 {
|
|
return nil, false
|
|
}
|
|
camelArgs[i] = strings.ToUpper(s[:1]) + strings.ToLower(s[1:])
|
|
}
|
|
methodName := "Cmd" + strings.Join(camelArgs, "")
|
|
method := reflect.ValueOf(cli).MethodByName(methodName)
|
|
if !method.IsValid() {
|
|
return nil, false
|
|
}
|
|
return method.Interface().(func(...string) error), true
|
|
}
|
|
|
|
func (cli *DockerCli) Cmd(args ...string) error {
|
|
if len(args) > 1 {
|
|
method, exists := cli.getMethod(args[:2]...)
|
|
if exists {
|
|
return method(args[2:]...)
|
|
}
|
|
}
|
|
if len(args) > 0 {
|
|
method, exists := cli.getMethod(args[0])
|
|
if !exists {
|
|
fmt.Println("Error: Command not found:", args[0])
|
|
return cli.CmdHelp()
|
|
}
|
|
return method(args[1:]...)
|
|
}
|
|
return cli.CmdHelp()
|
|
}
|
|
|
|
func (cli *DockerCli) Subcmd(name, signature, description string) *flag.FlagSet {
|
|
flags := flag.NewFlagSet(name, flag.ContinueOnError)
|
|
flags.Usage = func() {
|
|
options := ""
|
|
if flags.FlagCountUndeprecated() > 0 {
|
|
options = "[OPTIONS] "
|
|
}
|
|
fmt.Fprintf(os.Stderr, "\nUsage: machine %s %s%s\n\n%s\n\n", name, options, signature, description)
|
|
flags.PrintDefaults()
|
|
os.Exit(2)
|
|
}
|
|
return flags
|
|
}
|
|
|
|
func (cli *DockerCli) CmdHelp(args ...string) error {
|
|
if len(args) > 1 {
|
|
method, exists := cli.getMethod(args[:2]...)
|
|
if exists {
|
|
method("--help")
|
|
return nil
|
|
}
|
|
}
|
|
if len(args) > 0 {
|
|
method, exists := cli.getMethod(args[0])
|
|
if !exists {
|
|
fmt.Fprintf(os.Stderr, "Error: Command not found: %s\n", args[0])
|
|
} else {
|
|
method("--help")
|
|
return nil
|
|
}
|
|
}
|
|
|
|
flag.Usage()
|
|
|
|
return nil
|
|
}
|
|
|
|
func (cli *DockerCli) CmdLs(args ...string) error {
|
|
cmd := cli.Subcmd("ls", "", "List machines")
|
|
quiet := cmd.Bool([]string{"q", "-quiet"}, false, "Only display names")
|
|
|
|
if err := cmd.Parse(args); err != nil {
|
|
return err
|
|
}
|
|
|
|
store := NewStore()
|
|
|
|
hostList, err := store.List()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
w := tabwriter.NewWriter(os.Stdout, 5, 1, 3, ' ', 0)
|
|
|
|
if !*quiet {
|
|
fmt.Fprintln(w, "NAME\tACTIVE\tDRIVER\tSTATE\tURL")
|
|
}
|
|
|
|
wg := sync.WaitGroup{}
|
|
|
|
for _, host := range hostList {
|
|
host := host
|
|
if *quiet {
|
|
fmt.Fprintf(w, "%s\n", host.Name)
|
|
} else {
|
|
wg.Add(1)
|
|
go func() {
|
|
currentState, err := host.Driver.GetState()
|
|
if err != nil {
|
|
log.Errorf("error getting state for host %s: %s", host.Name, err)
|
|
}
|
|
|
|
url, err := host.GetURL()
|
|
if err != nil {
|
|
if err == drivers.ErrHostIsNotRunning {
|
|
url = ""
|
|
} else {
|
|
log.Errorf("error getting URL for host %s: %s", host.Name, err)
|
|
}
|
|
}
|
|
|
|
isActive, err := store.IsActive(&host)
|
|
if err != nil {
|
|
log.Errorf("error determining whether host %q is active: %s",
|
|
host.Name, err)
|
|
}
|
|
|
|
activeString := ""
|
|
if isActive {
|
|
activeString = "*"
|
|
}
|
|
|
|
fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s\n",
|
|
host.Name, activeString, host.Driver.DriverName(), currentState, url)
|
|
wg.Done()
|
|
}()
|
|
}
|
|
}
|
|
|
|
wg.Wait()
|
|
w.Flush()
|
|
|
|
return nil
|
|
}
|
|
|
|
func (cli *DockerCli) CmdCreate(args ...string) error {
|
|
cmd := cli.Subcmd("create", "NAME", "Create machines")
|
|
|
|
driverDesc := fmt.Sprintf(
|
|
"Driver to create machine with. Available drivers: %s",
|
|
strings.Join(drivers.GetDriverNames(), ", "),
|
|
)
|
|
|
|
driver := cmd.String([]string{"d", "-driver"}, "none", driverDesc)
|
|
|
|
createFlags := drivers.RegisterCreateFlags(cmd)
|
|
|
|
if err := cmd.Parse(args); err != nil {
|
|
return err
|
|
}
|
|
if cmd.NArg() != 1 {
|
|
cmd.Usage()
|
|
return nil
|
|
}
|
|
|
|
name := cmd.Arg(0)
|
|
|
|
store := NewStore()
|
|
|
|
driverCreateFlags, _ := createFlags[*driver]
|
|
host, err := store.Create(name, *driver, driverCreateFlags)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if err := store.SetActive(host); err != nil {
|
|
return err
|
|
}
|
|
log.Infof("%q has been created and is now the active machine. To point Docker at this machine, run: export DOCKER_HOST=$(machine url) DOCKER_AUTH=identity", name)
|
|
return nil
|
|
}
|
|
|
|
func (cli *DockerCli) CmdStart(args ...string) error {
|
|
cmd := cli.Subcmd("start", "NAME", "Start a machine")
|
|
if err := cmd.Parse(args); err != nil {
|
|
return err
|
|
}
|
|
if cmd.NArg() < 1 {
|
|
cmd.Usage()
|
|
return nil
|
|
}
|
|
|
|
store := NewStore()
|
|
|
|
host, err := store.Load(cmd.Arg(0))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return host.Start()
|
|
}
|
|
|
|
func (cli *DockerCli) CmdStop(args ...string) error {
|
|
cmd := cli.Subcmd("stop", "NAME", "Stop a machine")
|
|
if err := cmd.Parse(args); err != nil {
|
|
return err
|
|
}
|
|
if cmd.NArg() < 1 {
|
|
cmd.Usage()
|
|
return nil
|
|
}
|
|
|
|
store := NewStore()
|
|
|
|
host, err := store.Load(cmd.Arg(0))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return host.Stop()
|
|
}
|
|
|
|
func (cli *DockerCli) CmdRm(args ...string) error {
|
|
cmd := cli.Subcmd("rm", "NAME", "Remove a machine")
|
|
force := cmd.Bool([]string{"f", "-force"}, false, "Remove local configuration even if machine cannot be removed")
|
|
|
|
if err := cmd.Parse(args); err != nil {
|
|
return err
|
|
}
|
|
if cmd.NArg() < 1 {
|
|
cmd.Usage()
|
|
return nil
|
|
}
|
|
|
|
isError := false
|
|
|
|
store := NewStore()
|
|
for _, host := range cmd.Args() {
|
|
host := host
|
|
if err := store.Remove(host, *force); err != nil {
|
|
log.Errorf("Error removing machine %s: %s", host, err)
|
|
isError = true
|
|
}
|
|
}
|
|
if isError {
|
|
return fmt.Errorf("There was an error removing a machine. To force remove it, pass the -f option. Warning: this might leave it running on the provider.")
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (cli *DockerCli) CmdIp(args ...string) error {
|
|
cmd := cli.Subcmd("ip", "NAME", "Get the IP address of a machine")
|
|
if err := cmd.Parse(args); err != nil {
|
|
return err
|
|
}
|
|
if cmd.NArg() > 1 {
|
|
cmd.Usage()
|
|
return nil
|
|
}
|
|
|
|
var (
|
|
err error
|
|
host *Host
|
|
store = NewStore()
|
|
)
|
|
|
|
if cmd.NArg() == 1 {
|
|
host, err = store.Load(cmd.Arg(0))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
} else {
|
|
host, err = store.GetActive()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if host == nil {
|
|
os.Exit(1)
|
|
}
|
|
}
|
|
|
|
ip, err := host.Driver.GetIP()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
fmt.Println(ip)
|
|
|
|
return nil
|
|
}
|
|
|
|
func (cli *DockerCli) CmdUrl(args ...string) error {
|
|
cmd := cli.Subcmd("url", "NAME", "Get the URL of a machine")
|
|
if err := cmd.Parse(args); err != nil {
|
|
return err
|
|
}
|
|
if cmd.NArg() > 1 {
|
|
cmd.Usage()
|
|
return nil
|
|
}
|
|
|
|
var (
|
|
err error
|
|
host *Host
|
|
store = NewStore()
|
|
)
|
|
|
|
if cmd.NArg() == 1 {
|
|
host, err = store.Load(cmd.Arg(0))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
} else {
|
|
host, err = store.GetActive()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if host == nil {
|
|
os.Exit(1)
|
|
}
|
|
}
|
|
|
|
url, err := host.GetURL()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
fmt.Println(url)
|
|
|
|
return nil
|
|
}
|
|
|
|
func (cli *DockerCli) CmdRestart(args ...string) error {
|
|
cmd := cli.Subcmd("restart", "NAME", "Restart a machine")
|
|
if err := cmd.Parse(args); err != nil {
|
|
return err
|
|
}
|
|
if cmd.NArg() < 1 {
|
|
cmd.Usage()
|
|
return nil
|
|
}
|
|
|
|
store := NewStore()
|
|
|
|
host, err := store.Load(cmd.Arg(0))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return host.Driver.Restart()
|
|
}
|
|
|
|
func (cli *DockerCli) CmdKill(args ...string) error {
|
|
cmd := cli.Subcmd("kill", "NAME", "Kill a machine")
|
|
if err := cmd.Parse(args); err != nil {
|
|
return err
|
|
}
|
|
if cmd.NArg() < 1 {
|
|
cmd.Usage()
|
|
return nil
|
|
}
|
|
|
|
store := NewStore()
|
|
|
|
host, err := store.Load(cmd.Arg(0))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return host.Driver.Kill()
|
|
}
|
|
|
|
func (cli *DockerCli) CmdSsh(args ...string) error {
|
|
cmd := cli.Subcmd("ssh", "NAME [COMMAND ...]", "Log into or run a command on a machine with SSH")
|
|
if err := cmd.Parse(args); err != nil {
|
|
return err
|
|
}
|
|
|
|
if cmd.NArg() < 1 {
|
|
cmd.Usage()
|
|
return nil
|
|
}
|
|
|
|
i := 1
|
|
for i < len(os.Args) && os.Args[i-1] != cmd.Arg(0) {
|
|
i++
|
|
}
|
|
|
|
store := NewStore()
|
|
|
|
host, err := store.Load(cmd.Arg(0))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
sshCmd, err := host.Driver.GetSSHCommand(os.Args[i:]...)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
sshCmd.Stdin = os.Stdin
|
|
sshCmd.Stdout = os.Stdout
|
|
sshCmd.Stderr = os.Stderr
|
|
if err := sshCmd.Run(); err != nil {
|
|
return fmt.Errorf("%s", err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (cli *DockerCli) CmdActive(args ...string) error {
|
|
cmd := cli.Subcmd("active", "[NAME]", "Get or set the active machine")
|
|
if err := cmd.Parse(args); err != nil {
|
|
return err
|
|
}
|
|
|
|
store := NewStore()
|
|
|
|
if cmd.NArg() == 0 {
|
|
host, err := store.GetActive()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if host != nil {
|
|
fmt.Println(host.Name)
|
|
}
|
|
} else if cmd.NArg() == 1 {
|
|
host, err := store.Load(cmd.Arg(0))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if err := store.SetActive(host); err != nil {
|
|
return err
|
|
}
|
|
} else {
|
|
cmd.Usage()
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
func (cli *DockerCli) CmdInspect(args ...string) error {
|
|
cmd := cli.Subcmd("inspect", "[NAME]", "Get detailed information about a machine")
|
|
if err := cmd.Parse(args); err != nil {
|
|
return err
|
|
}
|
|
|
|
if cmd.NArg() == 0 {
|
|
cmd.Usage()
|
|
return nil
|
|
}
|
|
|
|
store := NewStore()
|
|
host, err := store.Load(cmd.Arg(0))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
prettyJson, err := json.MarshalIndent(host, "", " ")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
fmt.Println(string(prettyJson))
|
|
|
|
return nil
|
|
}
|
|
|
|
func (cli *DockerCli) CmdUpgrade(args ...string) error {
|
|
cmd := cli.Subcmd("upgrade", "[NAME]", "Upgrade a machine to the latest version of Docker")
|
|
if err := cmd.Parse(args); err != nil {
|
|
return err
|
|
}
|
|
|
|
if cmd.NArg() == 0 {
|
|
cmd.Usage()
|
|
return nil
|
|
}
|
|
|
|
store := NewStore()
|
|
host, err := store.Load(cmd.Arg(0))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return host.Driver.Upgrade()
|
|
}
|