From 007d83319d929e7fa7f850843af2a68fc193a058 Mon Sep 17 00:00:00 2001 From: Evan Hazlett Date: Mon, 9 Mar 2015 10:12:19 -0400 Subject: [PATCH 01/29] start on refactor for driver interface Signed-off-by: Evan Hazlett --- drivers/drivers.go | 68 ++++++++++++++--------------- drivers/none/none.go | 100 +++++++++++++++++++++---------------------- drivers/utils.go | 42 ------------------ ssh/ssh.go | 1 - 4 files changed, 79 insertions(+), 132 deletions(-) delete mode 100644 drivers/utils.go diff --git a/drivers/drivers.go b/drivers/drivers.go index 2562327464..68d565e8ea 100644 --- a/drivers/drivers.go +++ b/drivers/drivers.go @@ -3,7 +3,6 @@ package drivers import ( "errors" "fmt" - "os/exec" "sort" "github.com/codegangsta/cli" @@ -14,62 +13,57 @@ import ( // driver represent different ways hosts can be created (e.g. different // hypervisors, different cloud providers) type Driver interface { + // Create a host using the driver's config + Create() error + // DriverName returns the name of the driver as it is registered DriverName() string - // SetConfigFromFlags configures the driver with the object that was returned - // by RegisterCreateFlags - SetConfigFromFlags(flags DriverOptions) error - - // GetURL returns a Docker compatible host URL for connecting to this host - // e.g. tcp://1.2.3.4:2376 - GetURL() (string, error) - // GetIP returns an IP or hostname that this host is available at // e.g. 1.2.3.4 or docker-host-d60b70a14d3a.cloudapp.net GetIP() (string, error) + // GetSSHHostname returns hostname for use with ssh + GetSSHHostname() (string, error) + + // GetSSHKeyPath returns key path for use with ssh + GetSSHKeyPath() string + + // GetSSHPort returns port for use with ssh + GetSSHPort() (int, error) + + // GetSSHUsername returns username for use with ssh + GetSSHUsername() string + + // GetURL returns a Docker compatible host URL for connecting to this host + // e.g. tcp://1.2.3.4:2376 + GetURL() (string, error) + // GetState returns the state that the host is in (running, stopped, etc) GetState() (state.State, error) - // PreCreate allows for pre-create operations to make sure a driver is ready for creation - PreCreateCheck() error + // Kill stops a host forcefully + Kill() error - // Create a host using the driver's config - Create() error + // PreCreateCheck allows for pre-create operations to make sure a driver is ready for creation + PreCreateCheck() error // Remove a host Remove() error + // Restart a host. This may just call Stop(); Start() if the provider does not + // have any special restart behaviour. + Restart() error + + // SetConfigFromFlags configures the driver with the object that was returned + // by RegisterCreateFlags + SetConfigFromFlags(flags DriverOptions) error + // Start a host Start() error // Stop a host gracefully Stop() error - - // Restart a host. This may just call Stop(); Start() if the provider does not - // have any special restart behaviour. - Restart() error - - // Kill stops a host forcefully - Kill() error - - // StartDocker starts a Docker daemon on the machine - StartDocker() error - - // StopDocker stops a Docker daemon on the machine - StopDocker() error - - // Upgrade the version of Docker on the host to the latest version - Upgrade() error - - // GetDockerConfigDir returns the config directory for storing daemon configs - GetDockerConfigDir() string - - // GetSSHCommand returns a command for SSH pointing at the correct user, host - // and keys for the host with args appended. If no args are passed, it will - // initiate an interactive SSH session as if SSH were passed no args. - GetSSHCommand(args ...string) (*exec.Cmd, error) } // RegisteredDriver is used to register a driver with the Register function. diff --git a/drivers/none/none.go b/drivers/none/none.go index f65d9a1b2c..a14595d445 100644 --- a/drivers/none/none.go +++ b/drivers/none/none.go @@ -38,10 +38,58 @@ func NewDriver(machineName string, storePath string, caCert string, privateKey s return &Driver{}, nil } +func (d *Driver) Create() error { + return nil +} + func (d *Driver) DriverName() string { return "none" } +func (d *Driver) GetIP() (string, error) { + return "", nil +} + +func (d *Driver) GetSSHHostname() (string, error) { + return "", nil +} + +func (d *Driver) GetSSHKeyPath() string { + return "" +} + +func (d *Driver) GetSSHPort() int { + return 0 +} + +func (d *Driver) GetSSHUsername() string { + return "" +} + +func (d *Driver) GetURL() (string, error) { + return d.URL, nil +} + +func (d *Driver) GetState() (state.State, error) { + return state.None, nil +} + +func (d *Driver) Kill() error { + return fmt.Errorf("hosts without a driver cannot be killed") +} + +func (d *Driver) PreCreateCheck() error { + return nil +} + +func (d *Driver) Remove() error { + return nil +} + +func (d *Driver) Restart() error { + return fmt.Errorf("hosts without a driver cannot be restarted") +} + func (d *Driver) SetConfigFromFlags(flags drivers.DriverOptions) error { url := flags.String("url") @@ -57,26 +105,6 @@ func (d *Driver) SetConfigFromFlags(flags drivers.DriverOptions) error { return nil } -func (d *Driver) GetURL() (string, error) { - return d.URL, nil -} - -func (d *Driver) GetIP() (string, error) { - return "", nil -} - -func (d *Driver) GetState() (state.State, error) { - return state.None, nil -} - -func (d *Driver) PreCreateCheck() error { - return nil -} - -func (d *Driver) Create() error { - return nil -} - func (d *Driver) Start() error { return fmt.Errorf("hosts without a driver cannot be started") } @@ -84,35 +112,3 @@ func (d *Driver) Start() error { func (d *Driver) Stop() error { return fmt.Errorf("hosts without a driver cannot be stopped") } - -func (d *Driver) Remove() error { - return nil -} - -func (d *Driver) Restart() error { - return fmt.Errorf("hosts without a driver cannot be restarted") -} - -func (d *Driver) Kill() error { - return fmt.Errorf("hosts without a driver cannot be killed") -} - -func (d *Driver) StartDocker() error { - return fmt.Errorf("hosts without a driver cannot start docker") -} - -func (d *Driver) StopDocker() error { - return fmt.Errorf("hosts without a driver cannot stop docker") -} - -func (d *Driver) GetDockerConfigDir() string { - return "" -} - -func (d *Driver) Upgrade() error { - return fmt.Errorf("hosts without a driver cannot be upgraded") -} - -func (d *Driver) GetSSHCommand(args ...string) (*exec.Cmd, error) { - return nil, fmt.Errorf("hosts without a driver do not support SSH") -} diff --git a/drivers/utils.go b/drivers/utils.go deleted file mode 100644 index 2e6204848b..0000000000 --- a/drivers/utils.go +++ /dev/null @@ -1,42 +0,0 @@ -package drivers - -import ( - "fmt" - "os" - "path" - "path/filepath" - - "github.com/docker/machine/utils" -) - -func PublicKeyPath() string { - return filepath.Join(utils.GetDockerDir(), "public-key.json") -} - -func AddPublicKeyToAuthorizedHosts(d Driver, authorizedKeysPath string) error { - f, err := os.Open(PublicKeyPath()) - if err != nil { - return err - } - defer f.Close() - - // Use path.Join here, want to create unix path even when running on Windows. - cmdString := fmt.Sprintf("mkdir -p %q && cat > %q", authorizedKeysPath, - path.Join(authorizedKeysPath, "docker-host.json")) - cmd, err := d.GetSSHCommand(cmdString) - if err != nil { - return err - } - cmd.Stdin = f - return cmd.Run() -} - -func PublicKeyExists() (bool, error) { - _, err := os.Stat(PublicKeyPath()) - if err == nil { - return true, nil - } else if os.IsNotExist(err) { - return false, nil - } - return false, err -} diff --git a/ssh/ssh.go b/ssh/ssh.go index 080dd1236b..2f96fac736 100644 --- a/ssh/ssh.go +++ b/ssh/ssh.go @@ -11,7 +11,6 @@ import ( ) func GetSSHCommand(host string, port int, user string, sshKey string, args ...string) *exec.Cmd { - defaultSSHArgs := []string{ "-o", "IdentitiesOnly=yes", "-o", "StrictHostKeyChecking=no", From ae439188a0b559bb04d3eedb55b1b9e95ef5bb29 Mon Sep 17 00:00:00 2001 From: Evan Hazlett Date: Mon, 9 Mar 2015 10:30:21 -0400 Subject: [PATCH 02/29] use GetSSHAddress based on feedback from @sthulb Signed-off-by: Evan Hazlett --- drivers/drivers.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/drivers.go b/drivers/drivers.go index 68d565e8ea..84440820a8 100644 --- a/drivers/drivers.go +++ b/drivers/drivers.go @@ -19,12 +19,15 @@ type Driver interface { // DriverName returns the name of the driver as it is registered DriverName() string + // GetDockerPort returns the port specified for Docker + GetDockerPort() int + // GetIP returns an IP or hostname that this host is available at // e.g. 1.2.3.4 or docker-host-d60b70a14d3a.cloudapp.net GetIP() (string, error) // GetSSHHostname returns hostname for use with ssh - GetSSHHostname() (string, error) + GetSSHAddress() (string, error) // GetSSHKeyPath returns key path for use with ssh GetSSHKeyPath() string From b8ef936e9033d94d54c8b67b14c967192577f9da Mon Sep 17 00:00:00 2001 From: Evan Hazlett Date: Mon, 9 Mar 2015 10:50:48 -0400 Subject: [PATCH 03/29] add AuthorizePort and DeauthorizePort Signed-off-by: Evan Hazlett --- drivers/amazonec2/amazonec2.go | 22 ++++++++++++++++++---- drivers/drivers.go | 14 +++++++++++--- 2 files changed, 29 insertions(+), 7 deletions(-) diff --git a/drivers/amazonec2/amazonec2.go b/drivers/amazonec2/amazonec2.go index 5a9586f6af..2692fe28e7 100644 --- a/drivers/amazonec2/amazonec2.go +++ b/drivers/amazonec2/amazonec2.go @@ -8,7 +8,7 @@ import ( "io/ioutil" "net/url" "os/exec" - "path" + "path/filepath" "strconv" "strings" @@ -65,6 +65,7 @@ type Driver struct { SwarmDiscovery string storePath string keyPath string + sshPort int } type CreateFlags struct { @@ -413,6 +414,19 @@ func (d *Driver) GetState() (state.State, error) { return state.None, nil } +func (d *Driver) GetSSHAddress() (string, error) { + // TODO: use @nathanleclaire retry func here (ehazlett) + return d.GetIP() +} + +func (d *Driver) GetSSHPort() (int, error) { + return d.sshPort, nil +} + +func (d *Driver) GetSSHUsername() string { + return "ubuntu" +} + func (d *Driver) Start() error { if err := d.getClient().StartInstance(d.InstanceId); err != nil { return err @@ -509,7 +523,7 @@ func (d *Driver) Upgrade() error { } func (d *Driver) GetSSHCommand(args ...string) (*exec.Cmd, error) { - return ssh.GetSSHCommand(d.IPAddress, 22, "ubuntu", d.sshKeyPath(), args...), nil + return ssh.GetSSHCommand(d.IPAddress, d.GetSSHPort(), "ubuntu", d.sshKeyPath(), args...), nil } func (d *Driver) getClient() *amz.EC2 { @@ -517,8 +531,8 @@ func (d *Driver) getClient() *amz.EC2 { return amz.NewEC2(auth, d.Region) } -func (d *Driver) sshKeyPath() string { - return path.Join(d.storePath, "id_rsa") +func (d *Driver) GetSSHKeyPath() string { + return filepath.Join(d.storePath, "id_rsa") } func (d *Driver) publicSSHKeyPath() string { diff --git a/drivers/drivers.go b/drivers/drivers.go index 84440820a8..059d1307de 100644 --- a/drivers/drivers.go +++ b/drivers/drivers.go @@ -9,19 +9,27 @@ import ( "github.com/docker/machine/state" ) +type Port struct { + Protocol string + Port int +} + // Driver defines how a host is created and controlled. Different types of // driver represent different ways hosts can be created (e.g. different // hypervisors, different cloud providers) type Driver interface { + // AuthorizePort authorizes a port for machine access + AuthorizePort(port Port) error + // Create a host using the driver's config Create() error + // DeauthorizePort removes a port for machine access + DeauthorizePort(port Port) error + // DriverName returns the name of the driver as it is registered DriverName() string - // GetDockerPort returns the port specified for Docker - GetDockerPort() int - // GetIP returns an IP or hostname that this host is available at // e.g. 1.2.3.4 or docker-host-d60b70a14d3a.cloudapp.net GetIP() (string, error) From bc78e0081ef525c32892932be8b18f5f147a2f82 Mon Sep 17 00:00:00 2001 From: Evan Hazlett Date: Mon, 9 Mar 2015 10:51:59 -0400 Subject: [PATCH 04/29] enable port ranges for authorize/deauthorize Signed-off-by: Evan Hazlett --- drivers/drivers.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/drivers.go b/drivers/drivers.go index 059d1307de..3ad1329a8a 100644 --- a/drivers/drivers.go +++ b/drivers/drivers.go @@ -19,13 +19,13 @@ type Port struct { // hypervisors, different cloud providers) type Driver interface { // AuthorizePort authorizes a port for machine access - AuthorizePort(port Port) error + AuthorizePort(ports []Port) error // Create a host using the driver's config Create() error // DeauthorizePort removes a port for machine access - DeauthorizePort(port Port) error + DeauthorizePort(ports []Port) error // DriverName returns the name of the driver as it is registered DriverName() string From 95a95a4c763f7b17c24ea55a6ebac54e2e788a30 Mon Sep 17 00:00:00 2001 From: Evan Hazlett Date: Mon, 9 Mar 2015 12:23:14 -0400 Subject: [PATCH 05/29] added GetHypervisorType Signed-off-by: Evan Hazlett --- drivers/drivers.go | 11 +++++++++-- hypervisor/hypervisor.go | 25 +++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 2 deletions(-) create mode 100644 hypervisor/hypervisor.go diff --git a/drivers/drivers.go b/drivers/drivers.go index 3ad1329a8a..cb9cdc28cd 100644 --- a/drivers/drivers.go +++ b/drivers/drivers.go @@ -6,6 +6,7 @@ import ( "sort" "github.com/codegangsta/cli" + "github.com/docker/machine/hypervisor" "github.com/docker/machine/state" ) @@ -19,13 +20,13 @@ type Port struct { // hypervisors, different cloud providers) type Driver interface { // AuthorizePort authorizes a port for machine access - AuthorizePort(ports []Port) error + AuthorizePort(ports []*Port) error // Create a host using the driver's config Create() error // DeauthorizePort removes a port for machine access - DeauthorizePort(ports []Port) error + DeauthorizePort(ports []*Port) error // DriverName returns the name of the driver as it is registered DriverName() string @@ -34,6 +35,9 @@ type Driver interface { // e.g. 1.2.3.4 or docker-host-d60b70a14d3a.cloudapp.net GetIP() (string, error) + // GetMachineName returns the name of the machine + GetMachineName() string + // GetSSHHostname returns hostname for use with ssh GetSSHAddress() (string, error) @@ -53,6 +57,9 @@ type Driver interface { // GetState returns the state that the host is in (running, stopped, etc) GetState() (state.State, error) + // GetHypervisorType returns whether the instance is local/remote + GetHypervisorType() hypervisor.HypervisorType + // Kill stops a host forcefully Kill() error diff --git a/hypervisor/hypervisor.go b/hypervisor/hypervisor.go new file mode 100644 index 0000000000..545312d318 --- /dev/null +++ b/hypervisor/hypervisor.go @@ -0,0 +1,25 @@ +package hypervisor + +// HypervisorType represents the type of hypervisor a machine is using +type HypervisorType int + +const ( + None HypervisorType = iota + Local + Remote +) + +var hypervisorTypes = []string{ + "", + "Local", + "Remote", +} + +// Given a type, returns its string representation +func (h HypervisorType) String() string { + if int(h) >= 0 && int(h) < len(hypervisorTypes) { + return hypervisorTypes[h] + } else { + return "" + } +} From 21d83d4a4f464fc80ad48f1e45e452b705d3fdd4 Mon Sep 17 00:00:00 2001 From: Evan Hazlett Date: Mon, 9 Mar 2015 12:49:05 -0400 Subject: [PATCH 06/29] refactor GetSSHCommand, StartDocker, StopDocker, Upgrade into host Signed-off-by: Evan Hazlett --- host.go | 210 ++++++++++++++++++++++++++++++++++++++++++++------- host_test.go | 16 +++- 2 files changed, 194 insertions(+), 32 deletions(-) diff --git a/host.go b/host.go index 43e5d08806..5f010d51c1 100644 --- a/host.go +++ b/host.go @@ -9,6 +9,7 @@ import ( "net" "net/url" "os" + "os/exec" "path" "path/filepath" "regexp" @@ -18,13 +19,16 @@ import ( log "github.com/Sirupsen/logrus" "github.com/docker/machine/drivers" + "github.com/docker/machine/hypervisor" + "github.com/docker/machine/ssh" "github.com/docker/machine/utils" ) var ( - validHostNameChars = `[a-zA-Z0-9\-\.]` - validHostNamePattern = regexp.MustCompile(`^` + validHostNameChars + `+$`) - ErrInvalidHostname = errors.New("Invalid hostname specified") + validHostNameChars = `[a-zA-Z0-9\-\.]` + validHostNamePattern = regexp.MustCompile(`^` + validHostNameChars + `+$`) + ErrInvalidHostname = errors.New("Invalid hostname specified") + ErrUnknownHypervisorType = errors.New("Unknown hypervisor type") ) const ( @@ -106,6 +110,18 @@ func ValidateHostName(name string) (string, error) { return name, nil } +func (h *Host) GetDockerConfigDir() (string, error) { + // TODO: this will be refactored in https://github.com/docker/machine/issues/699 + switch h.Driver.GetHypervisorType() { + case hypervisor.Local: + return "/var/lib/boot2docker", nil + case hypervisor.Remote: + return "/etc/default", nil + default: + return "", ErrUnknownHypervisorType + } +} + func (h *Host) ConfigureSwarm(discovery string, master bool, host string, addr string) error { d := h.Driver @@ -122,7 +138,11 @@ func (h *Host) ConfigureSwarm(discovery string, master bool, host string, addr s addr = fmt.Sprintf("%s:2376", ip) } - basePath := d.GetDockerConfigDir() + basePath, err := h.GetDockerConfigDir() + if err != nil { + return err + } + tlsCaCert := path.Join(basePath, "ca.pem") tlsCert := path.Join(basePath, "server.pem") tlsKey := path.Join(basePath, "server-key.pem") @@ -142,7 +162,7 @@ func (h *Host) ConfigureSwarm(discovery string, master bool, host string, addr s return err } - cmd, err := d.GetSSHCommand(fmt.Sprintf("sudo docker pull %s", swarmDockerImage)) + cmd, err := h.GetSSHCommand(fmt.Sprintf("sudo docker pull %s", swarmDockerImage)) if err != nil { return err } @@ -150,12 +170,17 @@ func (h *Host) ConfigureSwarm(discovery string, master bool, host string, addr s return err } + dockerDir, err := h.GetDockerConfigDir() + if err != nil { + return err + } + // if master start master agent if master { log.Debug("launching swarm master") log.Debugf("master args: %s", masterArgs) - cmd, err = d.GetSSHCommand(fmt.Sprintf("sudo docker run -d -p %s:%s --restart=always --name swarm-agent-master -v %s:%s %s manage %s", - port, port, d.GetDockerConfigDir(), d.GetDockerConfigDir(), swarmDockerImage, masterArgs)) + cmd, err = h.GetSSHCommand(fmt.Sprintf("sudo docker run -d -p %s:%s --restart=always --name swarm-agent-master -v %s:%s %s manage %s", + port, port, dockerDir, dockerDir, swarmDockerImage, masterArgs)) if err != nil { return err } @@ -167,8 +192,63 @@ func (h *Host) ConfigureSwarm(discovery string, master bool, host string, addr s // start node agent log.Debug("launching swarm node") log.Debugf("node args: %s", nodeArgs) - cmd, err = d.GetSSHCommand(fmt.Sprintf("sudo docker run -d --restart=always --name swarm-agent -v %s:%s %s join %s", - d.GetDockerConfigDir(), d.GetDockerConfigDir(), swarmDockerImage, nodeArgs)) + cmd, err = h.GetSSHCommand(fmt.Sprintf("sudo docker run -d --restart=always --name swarm-agent -v %s:%s %s join %s", + dockerDir, dockerDir, swarmDockerImage, nodeArgs)) + if err != nil { + return err + } + if err := cmd.Run(); err != nil { + return err + } + + return nil +} + +func (h *Host) StartDocker() error { + log.Debug("Starting Docker...") + + var ( + cmd *exec.Cmd + err error + ) + + switch h.Driver.GetHypervisorType() { + case hypervisor.Local: + cmd, err = h.GetSSHCommand("sudo /etc/init.d/docker start") + case hypervisor.Remote: + cmd, err = h.GetSSHCommand("sudo service docker start") + default: + return ErrUnknownHypervisorType + } + + if err != nil { + return err + } + + if err := cmd.Run(); err != nil { + return err + } + + return nil +} + +func (h *Host) StopDocker() error { + log.Debug("Stopping Docker...") + + var ( + cmd *exec.Cmd + err error + ) + + switch h.Driver.GetHypervisorType() { + case hypervisor.Local: + cmd, err = h.GetSSHCommand("if [ -e /var/run/docker.pid ]; then sudo /etc/init.d/docker stop ; fi") + case hypervisor.Remote: + cmd, err = h.GetSSHCommand("sudo service docker stop") + default: + return ErrUnknownHypervisorType + } + if err != nil { return err } @@ -242,11 +322,16 @@ func (h *Host) ConfigureAuth() error { return fmt.Errorf("error generating server cert: %s", err) } - if err := d.StopDocker(); err != nil { + if err := h.StopDocker(); err != nil { return err } - cmd, err := d.GetSSHCommand(fmt.Sprintf("sudo mkdir -p %s", d.GetDockerConfigDir())) + dockerDir, err := h.GetDockerConfigDir() + if err != nil { + return err + } + + cmd, err := h.GetSSHCommand(fmt.Sprintf("sudo mkdir -p %s", dockerDir)) if err != nil { return err } @@ -262,21 +347,21 @@ func (h *Host) ConfigureAuth() error { // due to windows clients, we cannot use filepath.Join as the paths // will be mucked on the linux hosts - machineCaCertPath := path.Join(d.GetDockerConfigDir(), "ca.pem") + machineCaCertPath := path.Join(dockerDir, "ca.pem") serverCert, err := ioutil.ReadFile(serverCertPath) if err != nil { return err } - machineServerCertPath := path.Join(d.GetDockerConfigDir(), "server.pem") + machineServerCertPath := path.Join(dockerDir, "server.pem") serverKey, err := ioutil.ReadFile(serverKeyPath) if err != nil { return err } - machineServerKeyPath := path.Join(d.GetDockerConfigDir(), "server-key.pem") + machineServerKeyPath := path.Join(dockerDir, "server-key.pem") - cmd, err = d.GetSSHCommand(fmt.Sprintf("echo \"%s\" | sudo tee -a %s", string(caCert), machineCaCertPath)) + cmd, err = h.GetSSHCommand(fmt.Sprintf("echo \"%s\" | sudo tee -a %s", string(caCert), machineCaCertPath)) if err != nil { return err } @@ -284,7 +369,7 @@ func (h *Host) ConfigureAuth() error { return err } - cmd, err = d.GetSSHCommand(fmt.Sprintf("echo \"%s\" | sudo tee -a %s", string(serverKey), machineServerKeyPath)) + cmd, err = h.GetSSHCommand(fmt.Sprintf("echo \"%s\" | sudo tee -a %s", string(serverKey), machineServerKeyPath)) if err != nil { return err } @@ -292,7 +377,7 @@ func (h *Host) ConfigureAuth() error { return err } - cmd, err = d.GetSSHCommand(fmt.Sprintf("echo \"%s\" | sudo tee -a %s", string(serverCert), machineServerCertPath)) + cmd, err = h.GetSSHCommand(fmt.Sprintf("echo \"%s\" | sudo tee -a %s", string(serverCert), machineServerCertPath)) if err != nil { return err } @@ -318,9 +403,12 @@ func (h *Host) ConfigureAuth() error { dockerPort = dPort } - cfg := h.generateDockerConfig(dockerPort, machineCaCertPath, machineServerKeyPath, machineServerCertPath) + cfg, err := h.generateDockerConfig(dockerPort, machineCaCertPath, machineServerKeyPath, machineServerCertPath) + if err != nil { + return err + } - cmd, err = d.GetSSHCommand(fmt.Sprintf("echo \"%s\" | sudo tee -a %s", cfg.EngineConfig, cfg.EngineConfigPath)) + cmd, err = h.GetSSHCommand(fmt.Sprintf("echo \"%s\" | sudo tee -a %s", cfg.EngineConfig, cfg.EngineConfigPath)) if err != nil { return err } @@ -328,14 +416,14 @@ func (h *Host) ConfigureAuth() error { return err } - if err := d.StartDocker(); err != nil { + if err := h.StartDocker(); err != nil { return err } return nil } -func (h *Host) generateDockerConfig(dockerPort int, caCertPath string, serverKeyPath string, serverCertPath string) *DockerConfig { +func (h *Host) generateDockerConfig(dockerPort int, caCertPath string, serverKeyPath string, serverCertPath string) (*DockerConfig, error) { d := h.Driver var ( daemonOpts string @@ -353,10 +441,15 @@ func (h *Host) generateDockerConfig(dockerPort int, caCertPath string, serverKey strings.Join(swarmLabels, " "), ) + dockerDir, err := h.GetDockerConfigDir() + if err != nil { + return nil, err + } + switch d.DriverName() { case "virtualbox", "vmwarefusion", "vmwarevsphere", "hyper-v": daemonOpts = fmt.Sprintf("-H tcp://0.0.0.0:%d", dockerPort) - daemonOptsCfg = path.Join(d.GetDockerConfigDir(), "profile") + daemonOptsCfg = path.Join(dockerDir, "profile") opts := fmt.Sprintf("%s %s", defaultDaemonOpts, daemonOpts) daemonCfg = fmt.Sprintf(`EXTRA_ARGS='%s' CACERT=%s @@ -373,7 +466,7 @@ DOCKER_TLS=no`, opts, caCertPath, serverKeyPath, serverCertPath) return &DockerConfig{ EngineConfig: daemonCfg, EngineConfigPath: daemonOptsCfg, - } + }, nil } func (h *Host) Create(name string) error { @@ -387,13 +480,13 @@ func (h *Host) Create(name string) error { return err } - // install docker - if err := h.Provision(); err != nil { + // save to store + if err := h.SaveConfig(); err != nil { return err } - // save to store - if err := h.SaveConfig(); err != nil { + // install docker + if err := h.Provision(); err != nil { return err } @@ -409,7 +502,7 @@ func (h *Host) Provision() error { // install docker - until cloudinit we use ubuntu everywhere so we // just install it using the docker repos - cmd, err := h.Driver.GetSSHCommand("if [ ! -e /usr/bin/docker ]; then curl -sSL https://get.docker.com | sh -; fi") + cmd, err := h.GetSSHCommand("if [ ! -e /usr/bin/docker ]; then curl -sSL https://get.docker.com | sh -; fi") if err != nil { return err } @@ -424,6 +517,64 @@ func (h *Host) Provision() error { return fmt.Errorf("error installing docker: %s\n%s\n", err, string(buf.Bytes())) } + if err := h.SetHostname(); err != nil { + return err + } + + return nil +} + +func (h *Host) GetSSHCommand(args ...string) (*exec.Cmd, error) { + addr, err := h.Driver.GetSSHAddress() + if err != nil { + return nil, err + } + + user := h.Driver.GetSSHUsername() + + port, err := h.Driver.GetSSHPort() + if err != nil { + return nil, err + } + + keyPath := h.Driver.GetSSHKeyPath() + + cmd := ssh.GetSSHCommand(addr, port, user, keyPath, args...) + return cmd, nil +} + +func (h *Host) SetHostname() error { + var ( + cmd *exec.Cmd + err error + ) + + switch h.Driver.GetHypervisorType() { + case hypervisor.Local: + cmd, err = h.GetSSHCommand(fmt.Sprintf( + "sudo hostname %s && echo \"%s\" | sudo tee /var/lib/boot2docker/etc/hostname", + h.Name, + h.Name, + )) + case hypervisor.Remote: + cmd, err = h.GetSSHCommand(fmt.Sprintf( + "echo \"127.0.0.1 %s\" | sudo tee -a /etc/hosts && sudo hostname %s && echo \"%s\" | sudo tee /etc/hostname", + h.Name, + h.Name, + h.Name, + )) + default: + return ErrUnknownHypervisorType + } + + if err != nil { + return err + } + + if err := cmd.Run(); err != nil { + return err + } + return nil } @@ -436,7 +587,8 @@ func (h *Host) Stop() error { } func (h *Host) Upgrade() error { - return h.Driver.Upgrade() + // TODO: refactor to provisioner + return fmt.Errorf("upgrade not implemented") } func (h *Host) Remove(force bool) error { diff --git a/host_test.go b/host_test.go index a84564bcd2..faf4317447 100644 --- a/host_test.go +++ b/host_test.go @@ -129,7 +129,10 @@ func TestGenerateDockerConfigNonLocal(t *testing.T) { serverCertPath := "/test/server-cert" engineConfigPath := "/etc/default/docker" - dockerCfg := host.generateDockerConfig(dockerPort, caCertPath, serverKeyPath, serverCertPath) + dockerCfg, err := host.generateDockerConfig(dockerPort, caCertPath, serverKeyPath, serverCertPath) + if err != nil { + t.Fatal(err) + } if dockerCfg.EngineConfigPath != engineConfigPath { t.Fatalf("expected engine path %s; received %s", engineConfigPath, dockerCfg.EngineConfigPath) @@ -170,8 +173,11 @@ func TestMachinePort(t *testing.T) { if err != nil { t.Fatal(err) } - cfg := host.generateDockerConfig(dockerPort, "", "", "") + cfg, err := host.generateDockerConfig(dockerPort, "", "", "") + if err != nil { + t.Fatal(err) + } re := regexp.MustCompile("--host=tcp://.*:(.+)") m := re.FindStringSubmatch(cfg.EngineConfig) if len(m) == 0 { @@ -210,7 +216,11 @@ func TestMachineCustomPort(t *testing.T) { if err != nil { t.Fatal(err) } - cfg := host.generateDockerConfig(dockerPort, "", "", "") + + cfg, err := host.generateDockerConfig(dockerPort, "", "", "") + if err != nil { + t.Fatal(err) + } re := regexp.MustCompile("--host=tcp://.*:(.+)") m := re.FindStringSubmatch(cfg.EngineConfig) From e43da502f3384d8d0a0c9c1833334922975ce58d Mon Sep 17 00:00:00 2001 From: Evan Hazlett Date: Mon, 9 Mar 2015 12:49:46 -0400 Subject: [PATCH 07/29] refactor commands.go to use host ssh and upgrade Signed-off-by: Evan Hazlett --- commands.go | 28 ++++++++++++++-------------- commands_test.go | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 14 deletions(-) diff --git a/commands.go b/commands.go index 0d063d558e..58b92fff56 100644 --- a/commands.go +++ b/commands.go @@ -16,18 +16,18 @@ import ( "github.com/docker/machine/drivers" _ "github.com/docker/machine/drivers/amazonec2" - _ "github.com/docker/machine/drivers/azure" - _ "github.com/docker/machine/drivers/digitalocean" - _ "github.com/docker/machine/drivers/google" - _ "github.com/docker/machine/drivers/hyperv" + //_ "github.com/docker/machine/drivers/azure" + //_ "github.com/docker/machine/drivers/digitalocean" + //_ "github.com/docker/machine/drivers/google" + //_ "github.com/docker/machine/drivers/hyperv" _ "github.com/docker/machine/drivers/none" - _ "github.com/docker/machine/drivers/openstack" - _ "github.com/docker/machine/drivers/rackspace" - _ "github.com/docker/machine/drivers/softlayer" - _ "github.com/docker/machine/drivers/virtualbox" - _ "github.com/docker/machine/drivers/vmwarefusion" - _ "github.com/docker/machine/drivers/vmwarevcloudair" - _ "github.com/docker/machine/drivers/vmwarevsphere" + //_ "github.com/docker/machine/drivers/openstack" + //_ "github.com/docker/machine/drivers/rackspace" + //_ "github.com/docker/machine/drivers/softlayer" + //_ "github.com/docker/machine/drivers/virtualbox" + //_ "github.com/docker/machine/drivers/vmwarefusion" + //_ "github.com/docker/machine/drivers/vmwarevcloudair" + //_ "github.com/docker/machine/drivers/vmwarevsphere" "github.com/docker/machine/state" "github.com/docker/machine/utils" ) @@ -554,9 +554,9 @@ func cmdSsh(c *cli.Context) { } if len(c.Args()) <= 1 { - sshCmd, err = host.Driver.GetSSHCommand() + sshCmd, err = host.GetSSHCommand() } else { - sshCmd, err = host.Driver.GetSSHCommand(c.Args()[1:]...) + sshCmd, err = host.GetSSHCommand(c.Args()[1:]...) } if err != nil { log.Fatal(err) @@ -578,7 +578,7 @@ func machineCommand(actionName string, machine *Host, errorChan chan<- error) { "stop": machine.Driver.Stop, "restart": machine.Driver.Restart, "kill": machine.Driver.Kill, - "upgrade": machine.Driver.Upgrade, + "upgrade": machine.Upgrade, } log.Debugf("command=%s machine=%s", actionName, machine.Name) diff --git a/commands_test.go b/commands_test.go index 51651a276f..1267533c31 100644 --- a/commands_test.go +++ b/commands_test.go @@ -12,6 +12,7 @@ import ( "github.com/codegangsta/cli" drivers "github.com/docker/machine/drivers" + "github.com/docker/machine/hypervisor" "github.com/docker/machine/state" ) @@ -23,6 +24,14 @@ func (d *FakeDriver) DriverName() string { return "fakedriver" } +func (d *FakeDriver) AuthorizePort(ports []*drivers.Port) error { + return nil +} + +func (d *FakeDriver) DeauthorizePort(ports []*drivers.Port) error { + return nil +} + func (d *FakeDriver) SetConfigFromFlags(flags drivers.DriverOptions) error { return nil } @@ -31,10 +40,34 @@ func (d *FakeDriver) GetURL() (string, error) { return "", nil } +func (d *FakeDriver) GetMachineName() string { + return "" +} + +func (d *FakeDriver) GetHypervisorType() hypervisor.HypervisorType { + return hypervisor.None +} + func (d *FakeDriver) GetIP() (string, error) { return "", nil } +func (d *FakeDriver) GetSSHAddress() (string, error) { + return "", nil +} + +func (d *FakeDriver) GetSSHKeyPath() string { + return "" +} + +func (d *FakeDriver) GetSSHPort() (int, error) { + return 0, nil +} + +func (d *FakeDriver) GetSSHUsername() string { + return "" +} + func (d *FakeDriver) GetState() (state.State, error) { return d.MockState, nil } From 0577f66f5db5349a6707e79af11e7db633100267 Mon Sep 17 00:00:00 2001 From: Evan Hazlett Date: Mon, 9 Mar 2015 12:50:40 -0400 Subject: [PATCH 08/29] initial work to get amazonec2 and none drivers to upgrade driver interface Signed-off-by: Evan Hazlett --- drivers/amazonec2/amazonec2.go | 109 +++++++++------------------------ drivers/none/none.go | 24 ++++++-- 2 files changed, 49 insertions(+), 84 deletions(-) diff --git a/drivers/amazonec2/amazonec2.go b/drivers/amazonec2/amazonec2.go index 2692fe28e7..154dbd9125 100644 --- a/drivers/amazonec2/amazonec2.go +++ b/drivers/amazonec2/amazonec2.go @@ -7,7 +7,6 @@ import ( "io" "io/ioutil" "net/url" - "os/exec" "path/filepath" "strconv" "strings" @@ -16,6 +15,7 @@ import ( "github.com/codegangsta/cli" "github.com/docker/machine/drivers" "github.com/docker/machine/drivers/amazonec2/amz" + "github.com/docker/machine/hypervisor" "github.com/docker/machine/ssh" "github.com/docker/machine/state" "github.com/docker/machine/utils" @@ -27,7 +27,6 @@ const ( defaultInstanceType = "t2.micro" defaultRootSize = 16 ipRange = "0.0.0.0/0" - dockerConfigDir = "/etc/docker" machineSecurityGroupName = "docker-machine" ) @@ -65,7 +64,7 @@ type Driver struct { SwarmDiscovery string storePath string keyPath string - sshPort int + SSHPort int } type CreateFlags struct { @@ -162,7 +161,25 @@ func GetCreateFlags() []cli.Flag { func NewDriver(machineName string, storePath string, caCert string, privateKey string) (drivers.Driver, error) { id := generateId() - return &Driver{Id: id, MachineName: machineName, storePath: storePath, CaCertPath: caCert, PrivateKeyPath: privateKey}, nil + return &Driver{ + Id: id, + MachineName: machineName, + storePath: storePath, + CaCertPath: caCert, + PrivateKeyPath: privateKey, + }, nil +} + +func (d *Driver) GetHypervisorType() hypervisor.HypervisorType { + return hypervisor.Remote +} + +func (d *Driver) AuthorizePort(ports []*drivers.Port) error { + return nil +} + +func (d *Driver) DeauthorizePort(ports []*drivers.Port) error { + return nil } func (d *Driver) SetConfigFromFlags(flags drivers.DriverOptions) error { @@ -192,6 +209,7 @@ func (d *Driver) SetConfigFromFlags(flags drivers.DriverOptions) error { d.SwarmMaster = flags.Bool("swarm-master") d.SwarmHost = flags.String("swarm-host") d.SwarmDiscovery = flags.String("swarm-discovery") + d.SSHPort = 22 if d.AccessKey == "" { return fmt.Errorf("amazonec2 driver requires the --amazonec2-access-key option") @@ -223,6 +241,10 @@ func (d *Driver) SetConfigFromFlags(flags drivers.DriverOptions) error { return nil } +func (d *Driver) GetMachineName() string { + return d.MachineName +} + func (d *Driver) DriverName() string { return driverName } @@ -347,8 +369,6 @@ func (d *Driver) Create() error { return err } - log.Info("Configuring Machine...") - log.Debug("Settings tags for instance") tags := map[string]string{ "Name": d.MachineName, @@ -358,21 +378,6 @@ func (d *Driver) Create() error { return err } - log.Debugf("Setting hostname: %s", d.MachineName) - cmd, err := d.GetSSHCommand(fmt.Sprintf( - "echo \"127.0.0.1 %s\" | sudo tee -a /etc/hosts && sudo hostname %s && echo \"%s\" | sudo tee /etc/hostname", - d.MachineName, - d.MachineName, - d.MachineName, - )) - - if err != nil { - return err - } - if err := cmd.Run(); err != nil { - return err - } - return nil } @@ -420,7 +425,7 @@ func (d *Driver) GetSSHAddress() (string, error) { } func (d *Driver) GetSSHPort() (int, error) { - return d.sshPort, nil + return d.SSHPort, nil } func (d *Driver) GetSSHUsername() string { @@ -474,58 +479,6 @@ func (d *Driver) Kill() error { return nil } -func (d *Driver) StartDocker() error { - log.Debug("Starting Docker...") - - cmd, err := d.GetSSHCommand("sudo service docker start") - if err != nil { - return err - } - if err := cmd.Run(); err != nil { - return err - } - - return nil -} - -func (d *Driver) StopDocker() error { - log.Debug("Stopping Docker...") - - cmd, err := d.GetSSHCommand("sudo service docker stop") - if err != nil { - return err - } - if err := cmd.Run(); err != nil { - return err - } - - return nil -} - -func (d *Driver) GetDockerConfigDir() string { - return dockerConfigDir -} - -func (d *Driver) Upgrade() error { - log.Debugf("Upgrading Docker") - - cmd, err := d.GetSSHCommand("sudo apt-get update && sudo apt-get install --upgrade lxc-docker") - if err != nil { - return err - - } - if err := cmd.Run(); err != nil { - return err - - } - - return cmd.Run() -} - -func (d *Driver) GetSSHCommand(args ...string) (*exec.Cmd, error) { - return ssh.GetSSHCommand(d.IPAddress, d.GetSSHPort(), "ubuntu", d.sshKeyPath(), args...), nil -} - func (d *Driver) getClient() *amz.EC2 { auth := amz.GetAuth(d.AccessKey, d.SecretKey, d.SessionToken) return amz.NewEC2(auth, d.Region) @@ -535,10 +488,6 @@ func (d *Driver) GetSSHKeyPath() string { return filepath.Join(d.storePath, "id_rsa") } -func (d *Driver) publicSSHKeyPath() string { - return d.sshKeyPath() + ".pub" -} - func (d *Driver) getInstance() (*amz.EC2Instance, error) { instance, err := d.getClient().GetInstance(d.InstanceId) if err != nil { @@ -569,11 +518,11 @@ func (d *Driver) waitForInstance() error { func (d *Driver) createKeyPair() error { - if err := ssh.GenerateSSHKey(d.sshKeyPath()); err != nil { + if err := ssh.GenerateSSHKey(d.GetSSHKeyPath()); err != nil { return err } - publicKey, err := ioutil.ReadFile(d.publicSSHKeyPath()) + publicKey, err := ioutil.ReadFile(d.GetSSHKeyPath() + ".pub") if err != nil { return err } diff --git a/drivers/none/none.go b/drivers/none/none.go index a14595d445..41d379c8b0 100644 --- a/drivers/none/none.go +++ b/drivers/none/none.go @@ -2,11 +2,11 @@ package none import ( "fmt" - "os/exec" "github.com/codegangsta/cli" "github.com/docker/docker/api" "github.com/docker/machine/drivers" + "github.com/docker/machine/hypervisor" "github.com/docker/machine/state" ) @@ -38,10 +38,18 @@ func NewDriver(machineName string, storePath string, caCert string, privateKey s return &Driver{}, nil } +func (d *Driver) AuthorizePort(ports []*drivers.Port) error { + return nil +} + func (d *Driver) Create() error { return nil } +func (d *Driver) DeauthorizePort(ports []*drivers.Port) error { + return nil +} + func (d *Driver) DriverName() string { return "none" } @@ -50,7 +58,11 @@ func (d *Driver) GetIP() (string, error) { return "", nil } -func (d *Driver) GetSSHHostname() (string, error) { +func (d *Driver) GetMachineName() string { + return "" +} + +func (d *Driver) GetSSHAddress() (string, error) { return "", nil } @@ -58,8 +70,8 @@ func (d *Driver) GetSSHKeyPath() string { return "" } -func (d *Driver) GetSSHPort() int { - return 0 +func (d *Driver) GetSSHPort() (int, error) { + return 0, nil } func (d *Driver) GetSSHUsername() string { @@ -74,6 +86,10 @@ func (d *Driver) GetState() (state.State, error) { return state.None, nil } +func (d *Driver) GetHypervisorType() hypervisor.HypervisorType { + return hypervisor.None +} + func (d *Driver) Kill() error { return fmt.Errorf("hosts without a driver cannot be killed") } From 2b6daa29ed5ab0c0f3f6884a21bc93bb78da4b72 Mon Sep 17 00:00:00 2001 From: Evan Hazlett Date: Mon, 9 Mar 2015 12:50:57 -0400 Subject: [PATCH 09/29] update integration test for virtualbox Signed-off-by: Evan Hazlett --- test/integration/driver-virtualbox.bats | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/test/integration/driver-virtualbox.bats b/test/integration/driver-virtualbox.bats index e7ba6b3e21..124b600a8d 100644 --- a/test/integration/driver-virtualbox.bats +++ b/test/integration/driver-virtualbox.bats @@ -31,6 +31,11 @@ function setup() { [ "$status" -eq 0 ] } +@test "$DRIVER: upgrade" { + run machine upgrade $NAME + [ "$status" -eq 0 ] +} + @test "$DRIVER: ls" { run machine ls [ "$status" -eq 0 ] From c76d1a253f55555e96fd482f059afce7ce67d018 Mon Sep 17 00:00:00 2001 From: Evan Hazlett Date: Mon, 9 Mar 2015 15:55:18 -0400 Subject: [PATCH 10/29] revert to GetSSHHostname based on feedback from @nathanleclaire Signed-off-by: Evan Hazlett --- commands_test.go | 2 +- drivers/amazonec2/amazonec2.go | 2 +- drivers/drivers.go | 2 +- drivers/none/none.go | 2 +- host.go | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/commands_test.go b/commands_test.go index 1267533c31..dc166d34b3 100644 --- a/commands_test.go +++ b/commands_test.go @@ -52,7 +52,7 @@ func (d *FakeDriver) GetIP() (string, error) { return "", nil } -func (d *FakeDriver) GetSSHAddress() (string, error) { +func (d *FakeDriver) GetSSHHostname() (string, error) { return "", nil } diff --git a/drivers/amazonec2/amazonec2.go b/drivers/amazonec2/amazonec2.go index 154dbd9125..8a69883cb7 100644 --- a/drivers/amazonec2/amazonec2.go +++ b/drivers/amazonec2/amazonec2.go @@ -419,7 +419,7 @@ func (d *Driver) GetState() (state.State, error) { return state.None, nil } -func (d *Driver) GetSSHAddress() (string, error) { +func (d *Driver) GetSSHHostname() (string, error) { // TODO: use @nathanleclaire retry func here (ehazlett) return d.GetIP() } diff --git a/drivers/drivers.go b/drivers/drivers.go index cb9cdc28cd..623be64bab 100644 --- a/drivers/drivers.go +++ b/drivers/drivers.go @@ -39,7 +39,7 @@ type Driver interface { GetMachineName() string // GetSSHHostname returns hostname for use with ssh - GetSSHAddress() (string, error) + GetSSHHostname() (string, error) // GetSSHKeyPath returns key path for use with ssh GetSSHKeyPath() string diff --git a/drivers/none/none.go b/drivers/none/none.go index 41d379c8b0..4f32148756 100644 --- a/drivers/none/none.go +++ b/drivers/none/none.go @@ -62,7 +62,7 @@ func (d *Driver) GetMachineName() string { return "" } -func (d *Driver) GetSSHAddress() (string, error) { +func (d *Driver) GetSSHHostname() (string, error) { return "", nil } diff --git a/host.go b/host.go index 5f010d51c1..5156c442e5 100644 --- a/host.go +++ b/host.go @@ -525,7 +525,7 @@ func (h *Host) Provision() error { } func (h *Host) GetSSHCommand(args ...string) (*exec.Cmd, error) { - addr, err := h.Driver.GetSSHAddress() + addr, err := h.Driver.GetSSHHostname() if err != nil { return nil, err } From 3347d1e82fb1f1f8507423d038f3fa35a48693ec Mon Sep 17 00:00:00 2001 From: Evan Hazlett Date: Mon, 9 Mar 2015 16:03:36 -0400 Subject: [PATCH 11/29] rename HypervisorType to ProviderType Signed-off-by: Evan Hazlett --- commands_test.go | 6 +++--- drivers/amazonec2/amazonec2.go | 8 ++++---- drivers/drivers.go | 6 +++--- drivers/none/none.go | 6 +++--- host.go | 26 +++++++++++++------------- hypervisor/hypervisor.go | 25 ------------------------- provider/provider.go | 25 +++++++++++++++++++++++++ 7 files changed, 51 insertions(+), 51 deletions(-) delete mode 100644 hypervisor/hypervisor.go create mode 100644 provider/provider.go diff --git a/commands_test.go b/commands_test.go index dc166d34b3..6c8321a8b6 100644 --- a/commands_test.go +++ b/commands_test.go @@ -12,7 +12,7 @@ import ( "github.com/codegangsta/cli" drivers "github.com/docker/machine/drivers" - "github.com/docker/machine/hypervisor" + "github.com/docker/machine/provider" "github.com/docker/machine/state" ) @@ -44,8 +44,8 @@ func (d *FakeDriver) GetMachineName() string { return "" } -func (d *FakeDriver) GetHypervisorType() hypervisor.HypervisorType { - return hypervisor.None +func (d *FakeDriver) GetProviderType() provider.ProviderType { + return provider.None } func (d *FakeDriver) GetIP() (string, error) { diff --git a/drivers/amazonec2/amazonec2.go b/drivers/amazonec2/amazonec2.go index 8a69883cb7..361189a724 100644 --- a/drivers/amazonec2/amazonec2.go +++ b/drivers/amazonec2/amazonec2.go @@ -15,7 +15,7 @@ import ( "github.com/codegangsta/cli" "github.com/docker/machine/drivers" "github.com/docker/machine/drivers/amazonec2/amz" - "github.com/docker/machine/hypervisor" + "github.com/docker/machine/provider" "github.com/docker/machine/ssh" "github.com/docker/machine/state" "github.com/docker/machine/utils" @@ -43,6 +43,7 @@ type Driver struct { Region string AMI string SSHKeyID int + SSHPort int KeyName string InstanceId string InstanceType string @@ -64,7 +65,6 @@ type Driver struct { SwarmDiscovery string storePath string keyPath string - SSHPort int } type CreateFlags struct { @@ -170,8 +170,8 @@ func NewDriver(machineName string, storePath string, caCert string, privateKey s }, nil } -func (d *Driver) GetHypervisorType() hypervisor.HypervisorType { - return hypervisor.Remote +func (d *Driver) GetProviderType() provider.ProviderType { + return provider.Remote } func (d *Driver) AuthorizePort(ports []*drivers.Port) error { diff --git a/drivers/drivers.go b/drivers/drivers.go index 623be64bab..d0627b5549 100644 --- a/drivers/drivers.go +++ b/drivers/drivers.go @@ -6,7 +6,7 @@ import ( "sort" "github.com/codegangsta/cli" - "github.com/docker/machine/hypervisor" + "github.com/docker/machine/provider" "github.com/docker/machine/state" ) @@ -57,8 +57,8 @@ type Driver interface { // GetState returns the state that the host is in (running, stopped, etc) GetState() (state.State, error) - // GetHypervisorType returns whether the instance is local/remote - GetHypervisorType() hypervisor.HypervisorType + // GetProviderType returns whether the instance is local/remote + GetProviderType() provider.ProviderType // Kill stops a host forcefully Kill() error diff --git a/drivers/none/none.go b/drivers/none/none.go index 4f32148756..1b8a275fb3 100644 --- a/drivers/none/none.go +++ b/drivers/none/none.go @@ -6,7 +6,7 @@ import ( "github.com/codegangsta/cli" "github.com/docker/docker/api" "github.com/docker/machine/drivers" - "github.com/docker/machine/hypervisor" + "github.com/docker/machine/provider" "github.com/docker/machine/state" ) @@ -86,8 +86,8 @@ func (d *Driver) GetState() (state.State, error) { return state.None, nil } -func (d *Driver) GetHypervisorType() hypervisor.HypervisorType { - return hypervisor.None +func (d *Driver) GetProviderType() provider.ProviderType { + return provider.None } func (d *Driver) Kill() error { diff --git a/host.go b/host.go index 5156c442e5..3b8528f6ce 100644 --- a/host.go +++ b/host.go @@ -19,7 +19,7 @@ import ( log "github.com/Sirupsen/logrus" "github.com/docker/machine/drivers" - "github.com/docker/machine/hypervisor" + "github.com/docker/machine/provider" "github.com/docker/machine/ssh" "github.com/docker/machine/utils" ) @@ -112,10 +112,10 @@ func ValidateHostName(name string) (string, error) { func (h *Host) GetDockerConfigDir() (string, error) { // TODO: this will be refactored in https://github.com/docker/machine/issues/699 - switch h.Driver.GetHypervisorType() { - case hypervisor.Local: + switch h.Driver.GetProviderType() { + case provider.Local: return "/var/lib/boot2docker", nil - case hypervisor.Remote: + case provider.Remote: return "/etc/default", nil default: return "", ErrUnknownHypervisorType @@ -212,10 +212,10 @@ func (h *Host) StartDocker() error { err error ) - switch h.Driver.GetHypervisorType() { - case hypervisor.Local: + switch h.Driver.GetProviderType() { + case provider.Local: cmd, err = h.GetSSHCommand("sudo /etc/init.d/docker start") - case hypervisor.Remote: + case provider.Remote: cmd, err = h.GetSSHCommand("sudo service docker start") default: return ErrUnknownHypervisorType @@ -240,10 +240,10 @@ func (h *Host) StopDocker() error { err error ) - switch h.Driver.GetHypervisorType() { - case hypervisor.Local: + switch h.Driver.GetProviderType() { + case provider.Local: cmd, err = h.GetSSHCommand("if [ -e /var/run/docker.pid ]; then sudo /etc/init.d/docker stop ; fi") - case hypervisor.Remote: + case provider.Remote: cmd, err = h.GetSSHCommand("sudo service docker stop") default: return ErrUnknownHypervisorType @@ -549,14 +549,14 @@ func (h *Host) SetHostname() error { err error ) - switch h.Driver.GetHypervisorType() { - case hypervisor.Local: + switch h.Driver.GetProviderType() { + case provider.Local: cmd, err = h.GetSSHCommand(fmt.Sprintf( "sudo hostname %s && echo \"%s\" | sudo tee /var/lib/boot2docker/etc/hostname", h.Name, h.Name, )) - case hypervisor.Remote: + case provider.Remote: cmd, err = h.GetSSHCommand(fmt.Sprintf( "echo \"127.0.0.1 %s\" | sudo tee -a /etc/hosts && sudo hostname %s && echo \"%s\" | sudo tee /etc/hostname", h.Name, diff --git a/hypervisor/hypervisor.go b/hypervisor/hypervisor.go deleted file mode 100644 index 545312d318..0000000000 --- a/hypervisor/hypervisor.go +++ /dev/null @@ -1,25 +0,0 @@ -package hypervisor - -// HypervisorType represents the type of hypervisor a machine is using -type HypervisorType int - -const ( - None HypervisorType = iota - Local - Remote -) - -var hypervisorTypes = []string{ - "", - "Local", - "Remote", -} - -// Given a type, returns its string representation -func (h HypervisorType) String() string { - if int(h) >= 0 && int(h) < len(hypervisorTypes) { - return hypervisorTypes[h] - } else { - return "" - } -} diff --git a/provider/provider.go b/provider/provider.go new file mode 100644 index 0000000000..713c62cad1 --- /dev/null +++ b/provider/provider.go @@ -0,0 +1,25 @@ +package provider + +// ProviderType represents the type of a provider for a machine +type ProviderType int + +const ( + None ProviderType = iota + Local + Remote +) + +var providerTypes = []string{ + "", + "Local", + "Remote", +} + +// Given a type, returns its string representation +func (t ProviderType) String() string { + if int(t) >= 0 && int(t) < len(providerTypes) { + return providerTypes[t] + } else { + return "" + } +} From 275cb37602a0be2283ff5ed389bf0319192e4f3d Mon Sep 17 00:00:00 2001 From: Evan Hazlett Date: Mon, 9 Mar 2015 17:53:30 -0400 Subject: [PATCH 12/29] virtualbox: update to new driver interface Signed-off-by: Evan Hazlett --- commands.go | 2 +- drivers/virtualbox/virtualbox.go | 114 +++++++++++++++---------------- 2 files changed, 57 insertions(+), 59 deletions(-) diff --git a/commands.go b/commands.go index 58b92fff56..7290206ecd 100644 --- a/commands.go +++ b/commands.go @@ -24,7 +24,7 @@ import ( //_ "github.com/docker/machine/drivers/openstack" //_ "github.com/docker/machine/drivers/rackspace" //_ "github.com/docker/machine/drivers/softlayer" - //_ "github.com/docker/machine/drivers/virtualbox" + _ "github.com/docker/machine/drivers/virtualbox" //_ "github.com/docker/machine/drivers/vmwarefusion" //_ "github.com/docker/machine/drivers/vmwarevcloudair" //_ "github.com/docker/machine/drivers/vmwarevsphere" diff --git a/drivers/virtualbox/virtualbox.go b/drivers/virtualbox/virtualbox.go index a59c3e0e57..07e85fd3b8 100644 --- a/drivers/virtualbox/virtualbox.go +++ b/drivers/virtualbox/virtualbox.go @@ -19,6 +19,7 @@ import ( log "github.com/Sirupsen/logrus" "github.com/codegangsta/cli" "github.com/docker/machine/drivers" + "github.com/docker/machine/provider" "github.com/docker/machine/ssh" "github.com/docker/machine/state" "github.com/docker/machine/utils" @@ -31,6 +32,7 @@ const ( type Driver struct { MachineName string + SSHUser string SSHPort int Memory int DiskSize int @@ -83,6 +85,38 @@ func NewDriver(machineName string, storePath string, caCert string, privateKey s return &Driver{MachineName: machineName, storePath: storePath, CaCertPath: caCert, PrivateKeyPath: privateKey}, nil } +func (d *Driver) AuthorizePort(ports []*drivers.Port) error { + return nil +} + +func (d *Driver) DeauthorizePort(ports []*drivers.Port) error { + return nil +} + +func (d *Driver) GetMachineName() string { + return d.MachineName +} + +func (d *Driver) GetSSHHostname() (string, error) { + return "localhost", nil +} + +func (d *Driver) GetSSHKeyPath() string { + return filepath.Join(d.storePath, "id_rsa") +} + +func (d *Driver) GetSSHPort() (int, error) { + return d.SSHPort, nil +} + +func (d *Driver) GetSSHUsername() string { + return d.SSHUser +} + +func (d *Driver) GetProviderType() provider.ProviderType { + return provider.Local +} + func (d *Driver) DriverName() string { return "virtualbox" } @@ -105,6 +139,7 @@ func (d *Driver) SetConfigFromFlags(flags drivers.DriverOptions) error { d.SwarmMaster = flags.Bool("swarm-master") d.SwarmHost = flags.String("swarm-host") d.SwarmDiscovery = flags.String("swarm-discovery") + d.SSHUser = "docker" return nil } @@ -172,7 +207,7 @@ func (d *Driver) Create() error { log.Infof("Creating SSH key...") - if err := ssh.GenerateSSHKey(d.sshKeyPath()); err != nil { + if err := ssh.GenerateSSHKey(d.GetSSHKeyPath()); err != nil { return err } @@ -321,20 +356,6 @@ func (d *Driver) Create() error { return err } - cmd, err := d.GetSSHCommand(fmt.Sprintf( - "sudo hostname %s && echo \"%s\" | sudo tee /var/lib/boot2docker/etc/hostname", - d.MachineName, - d.MachineName, - )) - if err != nil { - return err - - } - if err := cmd.Run(); err != nil { - return err - - } - return nil } @@ -465,6 +486,24 @@ func (d *Driver) setMachineNameIfNotSet() { } } +// getSSHCommand returns a command suitable for ssh +func (d *Driver) getSSHCommand(args ...string) (*exec.Cmd, error) { + host, err := d.GetSSHHostname() + if err != nil { + return nil, err + } + + port, err := d.GetSSHPort() + if err != nil { + return nil, err + } + + user := d.GetSSHUsername() + keyPath := d.GetSSHKeyPath() + + return ssh.GetSSHCommand(host, port, user, keyPath, args...), nil +} + func (d *Driver) GetIP() (string, error) { // DHCP is used to get the IP, so virtualbox hosts don't have IPs unless // they are running @@ -475,8 +514,7 @@ func (d *Driver) GetIP() (string, error) { if s != state.Running { return "", drivers.ErrHostIsNotRunning } - - cmd, err := d.GetSSHCommand("ip addr show dev eth1") + cmd, err := d.getSSHCommand("ip addr show dev eth1") if err != nil { return "", err } @@ -502,48 +540,8 @@ func (d *Driver) GetIP() (string, error) { return "", fmt.Errorf("No IP address found %s", out) } -func (d *Driver) GetSSHCommand(args ...string) (*exec.Cmd, error) { - return ssh.GetSSHCommand("localhost", d.SSHPort, "docker", d.sshKeyPath(), args...), nil -} - -func (d *Driver) StartDocker() error { - log.Debug("Starting Docker...") - - cmd, err := d.GetSSHCommand("sudo /etc/init.d/docker start") - if err != nil { - return err - } - if err := cmd.Run(); err != nil { - return err - } - - return nil -} - -func (d *Driver) StopDocker() error { - log.Debug("Stopping Docker...") - - cmd, err := d.GetSSHCommand("if [ -e /var/run/docker.pid ]; then sudo /etc/init.d/docker stop ; fi") - if err != nil { - return err - } - if err := cmd.Run(); err != nil { - return err - } - - return nil -} - -func (d *Driver) GetDockerConfigDir() string { - return dockerConfigDir -} - -func (d *Driver) sshKeyPath() string { - return filepath.Join(d.storePath, "id_rsa") -} - func (d *Driver) publicSSHKeyPath() string { - return d.sshKeyPath() + ".pub" + return d.GetSSHKeyPath() + ".pub" } func (d *Driver) diskPath() string { From 6e81ba9fe715308ccaa247b3baf465c0d5b7032c Mon Sep 17 00:00:00 2001 From: Evan Hazlett Date: Mon, 9 Mar 2015 20:52:53 -0400 Subject: [PATCH 13/29] virtualbox: finished driver updates Signed-off-by: Evan Hazlett --- drivers/virtualbox/virtualbox.go | 25 ------------------------- host.go | 2 +- 2 files changed, 1 insertion(+), 26 deletions(-) diff --git a/drivers/virtualbox/virtualbox.go b/drivers/virtualbox/virtualbox.go index 07e85fd3b8..21e53f84f4 100644 --- a/drivers/virtualbox/virtualbox.go +++ b/drivers/virtualbox/virtualbox.go @@ -428,31 +428,6 @@ func (d *Driver) Kill() error { return vbm("controlvm", d.MachineName, "poweroff") } -func (d *Driver) Upgrade() error { - log.Infof("Stopping machine...") - if err := d.Stop(); err != nil { - return err - } - - b2dutils := utils.NewB2dUtils("", "") - isoURL, err := b2dutils.GetLatestBoot2DockerReleaseURL() - if err != nil { - return err - } - - log.Infof("Downloading boot2docker...") - if err := b2dutils.DownloadISO(d.storePath, "boot2docker.iso", isoURL); err != nil { - return err - } - - log.Infof("Starting machine...") - if err := d.Start(); err != nil { - return err - } - - return nil -} - func (d *Driver) GetState() (state.State, error) { stdout, stderr, err := vbmOutErr("showvminfo", d.MachineName, "--machinereadable") diff --git a/host.go b/host.go index 3b8528f6ce..7ff301a995 100644 --- a/host.go +++ b/host.go @@ -588,7 +588,7 @@ func (h *Host) Stop() error { func (h *Host) Upgrade() error { // TODO: refactor to provisioner - return fmt.Errorf("upgrade not implemented") + return fmt.Errorf("centralized upgrade coming in the provisioner") } func (h *Host) Remove(force bool) error { From 51aa826e1452ed958e7f7c702bb42e56c95e7e0b Mon Sep 17 00:00:00 2001 From: Evan Hazlett Date: Mon, 9 Mar 2015 22:20:47 -0400 Subject: [PATCH 14/29] digitalocean: update to driver interface Signed-off-by: Evan Hazlett --- commands.go | 2 +- drivers/digitalocean/digitalocean.go | 37 +++++++++++++++++++++++ test/integration/driver-digitalocean.bats | 1 + 3 files changed, 39 insertions(+), 1 deletion(-) diff --git a/commands.go b/commands.go index 7290206ecd..fad11d7fbd 100644 --- a/commands.go +++ b/commands.go @@ -17,7 +17,7 @@ import ( "github.com/docker/machine/drivers" _ "github.com/docker/machine/drivers/amazonec2" //_ "github.com/docker/machine/drivers/azure" - //_ "github.com/docker/machine/drivers/digitalocean" + _ "github.com/docker/machine/drivers/digitalocean" //_ "github.com/docker/machine/drivers/google" //_ "github.com/docker/machine/drivers/hyperv" _ "github.com/docker/machine/drivers/none" diff --git a/drivers/digitalocean/digitalocean.go b/drivers/digitalocean/digitalocean.go index 7c8f9ef7d7..c759352a79 100644 --- a/drivers/digitalocean/digitalocean.go +++ b/drivers/digitalocean/digitalocean.go @@ -12,6 +12,7 @@ import ( "github.com/codegangsta/cli" "github.com/digitalocean/godo" "github.com/docker/machine/drivers" + "github.com/docker/machine/provider" "github.com/docker/machine/ssh" "github.com/docker/machine/state" ) @@ -29,6 +30,8 @@ type Driver struct { IPAddress string Region string SSHKeyID int + SSHUser string + SSHPort int Size string IPv6 bool Backups bool @@ -98,6 +101,38 @@ func NewDriver(machineName string, storePath string, caCert string, privateKey s return &Driver{MachineName: machineName, storePath: storePath, CaCertPath: caCert, PrivateKeyPath: privateKey}, nil } +func (d *Driver) AuthorizePort(ports []*drivers.Port) error { + return nil +} + +func (d *Driver) DeauthorizePort(ports []*drivers.Port) error { + return nil +} + +func (d *Driver) GetMachineName() string { + return d.MachineName +} + +func (d *Driver) GetSSHHostname() (string, error) { + return d.GetIP() +} + +func (d *Driver) GetSSHKeyPath() string { + return filepath.Join(d.storePath, "id_rsa") +} + +func (d *Driver) GetSSHPort() (int, error) { + return d.SSHPort, nil +} + +func (d *Driver) GetSSHUsername() string { + return d.SSHUser +} + +func (d *Driver) GetProviderType() provider.ProviderType { + return provider.Remote +} + func (d *Driver) DriverName() string { return "digitalocean" } @@ -113,6 +148,8 @@ func (d *Driver) SetConfigFromFlags(flags drivers.DriverOptions) error { d.SwarmMaster = flags.Bool("swarm-master") d.SwarmHost = flags.String("swarm-host") d.SwarmDiscovery = flags.String("swarm-discovery") + d.SSHUser = "root" + d.SSHPort = 22 if d.AccessToken == "" { return fmt.Errorf("digitalocean driver requires the --digitalocean-access-token option") diff --git a/test/integration/driver-digitalocean.bats b/test/integration/driver-digitalocean.bats index 86b582301f..511e15d7dd 100644 --- a/test/integration/driver-digitalocean.bats +++ b/test/integration/driver-digitalocean.bats @@ -95,6 +95,7 @@ export MACHINE_STORAGE_PATH=/tmp/machine-bats-test-$DRIVER } @test "$DRIVER: remove" { + run sleep 20 run machine rm -f $NAME [ "$status" -eq 0 ] } From 52a3019d00e943b9f9157560a899f18239a3d32d Mon Sep 17 00:00:00 2001 From: Evan Hazlett Date: Mon, 9 Mar 2015 22:53:21 -0400 Subject: [PATCH 15/29] azure: updated to driver interface; refactored common GetSSHCommandFromDriver for those that need it Signed-off-by: Evan Hazlett --- commands.go | 2 +- drivers/azure/azure.go | 305 +++++++++++++------------------ drivers/drivers.go | 19 ++ drivers/virtualbox/virtualbox.go | 20 +- host.go | 2 + 5 files changed, 153 insertions(+), 195 deletions(-) diff --git a/commands.go b/commands.go index fad11d7fbd..0b65108a1a 100644 --- a/commands.go +++ b/commands.go @@ -16,7 +16,7 @@ import ( "github.com/docker/machine/drivers" _ "github.com/docker/machine/drivers/amazonec2" - //_ "github.com/docker/machine/drivers/azure" + _ "github.com/docker/machine/drivers/azure" _ "github.com/docker/machine/drivers/digitalocean" //_ "github.com/docker/machine/drivers/google" //_ "github.com/docker/machine/drivers/hyperv" diff --git a/drivers/azure/azure.go b/drivers/azure/azure.go index 8af46b119c..3a311494cd 100644 --- a/drivers/azure/azure.go +++ b/drivers/azure/azure.go @@ -16,6 +16,7 @@ import ( "github.com/codegangsta/cli" "github.com/docker/docker/utils" "github.com/docker/machine/drivers" + "github.com/docker/machine/provider" "github.com/docker/machine/ssh" "github.com/docker/machine/state" ) @@ -31,9 +32,9 @@ type Driver struct { PublishSettingsFilePath string Location string Size string - UserName string UserPassword string Image string + SSHUser string SSHPort int DockerPort int CaCertPath string @@ -51,7 +52,7 @@ func init() { }) } -// GetCreateFlags registers the flags this driver adds to +// GetCreateFlags registers the flags this d adds to // "docker hosts create" func GetCreateFlags() []cli.Flag { return []cli.Flag{ @@ -111,16 +112,48 @@ func GetCreateFlags() []cli.Flag { } func NewDriver(machineName string, storePath string, caCert string, privateKey string) (drivers.Driver, error) { - driver := &Driver{MachineName: machineName, storePath: storePath, CaCertPath: caCert, PrivateKeyPath: privateKey} - return driver, nil + d := &Driver{MachineName: machineName, storePath: storePath, CaCertPath: caCert, PrivateKeyPath: privateKey} + return d, nil } -func (driver *Driver) DriverName() string { +func (d *Driver) AuthorizePort(ports []*drivers.Port) error { + return nil +} + +func (d *Driver) DeauthorizePort(ports []*drivers.Port) error { + return nil +} + +func (d *Driver) GetMachineName() string { + return d.MachineName +} + +func (d *Driver) GetSSHHostname() (string, error) { + return d.GetIP() +} + +func (d *Driver) GetSSHKeyPath() string { + return filepath.Join(d.storePath, "id_rsa") +} + +func (d *Driver) GetSSHPort() (int, error) { + return d.SSHPort, nil +} + +func (d *Driver) GetSSHUsername() string { + return d.SSHUser +} + +func (d *Driver) GetProviderType() provider.ProviderType { + return provider.Remote +} + +func (d *Driver) DriverName() string { return "azure" } -func (driver *Driver) SetConfigFromFlags(flags drivers.DriverOptions) error { - driver.SubscriptionID = flags.String("azure-subscription-id") +func (d *Driver) SetConfigFromFlags(flags drivers.DriverOptions) error { + d.SubscriptionID = flags.String("azure-subscription-id") cert := flags.String("azure-subscription-cert") publishSettings := flags.String("azure-publish-settings-file") @@ -131,51 +164,51 @@ func (driver *Driver) SetConfigFromFlags(flags drivers.DriverOptions) error { if _, err := os.Stat(cert); os.IsNotExist(err) { return err } - driver.SubscriptionCert = cert + d.SubscriptionCert = cert } if publishSettings != "" { if _, err := os.Stat(publishSettings); os.IsNotExist(err) { return err } - driver.PublishSettingsFilePath = publishSettings + d.PublishSettingsFilePath = publishSettings } - if (driver.SubscriptionID == "" || driver.SubscriptionCert == "") && driver.PublishSettingsFilePath == "" { + if (d.SubscriptionID == "" || d.SubscriptionCert == "") && d.PublishSettingsFilePath == "" { return fmt.Errorf("Please specify azure subscription params using options: --azure-subscription-id and --azure-subscription-cert or --azure-publish-settings-file") } if image == "" { - driver.Image = "b39f27a8b8c64d52b05eac6a62ebad85__Ubuntu-14_04_1-LTS-amd64-server-20140927-en-us-30GB" + d.Image = "b39f27a8b8c64d52b05eac6a62ebad85__Ubuntu-14_04_1-LTS-amd64-server-20140927-en-us-30GB" } else { - driver.Image = image + d.Image = image } - driver.Location = flags.String("azure-location") - driver.Size = flags.String("azure-size") + d.Location = flags.String("azure-location") + d.Size = flags.String("azure-size") if strings.ToLower(username) == "docker" { return fmt.Errorf("'docker' is not valid user name for docker host. Please specify another user name") } - driver.UserName = username - driver.UserPassword = flags.String("azure-password") - driver.DockerPort = flags.Int("azure-docker-port") - driver.SSHPort = flags.Int("azure-ssh-port") - driver.SwarmMaster = flags.Bool("swarm-master") - driver.SwarmHost = flags.String("swarm-host") - driver.SwarmDiscovery = flags.String("swarm-discovery") + d.SSHUser = username + d.UserPassword = flags.String("azure-password") + d.DockerPort = flags.Int("azure-docker-port") + d.SSHPort = flags.Int("azure-ssh-port") + d.SwarmMaster = flags.Bool("swarm-master") + d.SwarmHost = flags.String("swarm-host") + d.SwarmDiscovery = flags.String("swarm-discovery") return nil } -func (driver *Driver) PreCreateCheck() error { - if err := driver.setUserSubscription(); err != nil { +func (d *Driver) PreCreateCheck() error { + if err := d.setUserSubscription(); err != nil { return err } // check azure DNS to make sure name is available - available, response, err := vmClient.CheckHostedServiceNameAvailability(driver.MachineName) + available, response, err := vmClient.CheckHostedServiceNameAvailability(d.MachineName) if err != nil { return err } @@ -187,83 +220,69 @@ func (driver *Driver) PreCreateCheck() error { return nil } -func (driver *Driver) Create() error { - if err := driver.setUserSubscription(); err != nil { +func (d *Driver) Create() error { + if err := d.setUserSubscription(); err != nil { return err } log.Info("Creating Azure machine...") - vmConfig, err := vmClient.CreateAzureVMConfiguration(driver.MachineName, driver.Size, driver.Image, driver.Location) + vmConfig, err := vmClient.CreateAzureVMConfiguration(d.MachineName, d.Size, d.Image, d.Location) if err != nil { return err } log.Debug("Generating certificate for Azure...") - if err := driver.generateCertForAzure(); err != nil { + if err := d.generateCertForAzure(); err != nil { return err } log.Debug("Adding Linux provisioning...") - vmConfig, err = vmClient.AddAzureLinuxProvisioningConfig(vmConfig, driver.UserName, driver.UserPassword, driver.azureCertPath(), driver.SSHPort) + user := d.GetSSHUsername() + port, err := d.GetSSHPort() + if err != nil { + return err + } + vmConfig, err = vmClient.AddAzureLinuxProvisioningConfig(vmConfig, user, d.UserPassword, d.azureCertPath(), port) if err != nil { return err } log.Debug("Authorizing ports...") - if err := driver.addDockerEndpoint(vmConfig); err != nil { + if err := d.addDockerEndpoint(vmConfig); err != nil { return err } log.Debug("Creating VM...") - if err := vmClient.CreateAzureVM(vmConfig, driver.MachineName, driver.Location); err != nil { + if err := vmClient.CreateAzureVM(vmConfig, d.MachineName, d.Location); err != nil { return err } log.Info("Waiting for SSH...") - log.Debugf("Host: %s SSH Port: %d", driver.getHostname(), driver.SSHPort) + log.Debugf("Host: %s SSH Port: %d", d.getHostname(), d.SSHPort) - if err := ssh.WaitForTCP(fmt.Sprintf("%s:%d", driver.getHostname(), driver.SSHPort)); err != nil { + if err := ssh.WaitForTCP(fmt.Sprintf("%s:%d", d.getHostname(), d.SSHPort)); err != nil { return err } return nil } -func (driver *Driver) runSSHCommand(command string, retries int) error { - cmd, err := driver.GetSSHCommand(command) - if err != nil { - return err - } - if err := cmd.Run(); err != nil { - if err.Error() == "exit status 255" { - if retries == 0 { - return err - } - return driver.runSSHCommand(command, retries-1) - } - - return err - } - - return nil -} - -func (driver *Driver) GetURL() (string, error) { - url := fmt.Sprintf("tcp://%s:%v", driver.getHostname(), driver.DockerPort) +func (d *Driver) GetURL() (string, error) { + url := fmt.Sprintf("tcp://%s:%v", d.getHostname(), d.DockerPort) return url, nil } -func (driver *Driver) GetIP() (string, error) { - return driver.getHostname(), nil +func (d *Driver) GetIP() (string, error) { + return d.getHostname(), nil } -func (driver *Driver) GetState() (state.State, error) { - err := driver.setUserSubscription() +func (d *Driver) GetState() (state.State, error) { + err := d.setUserSubscription() if err != nil { return state.Error, err } - dockerVM, err := vmClient.GetVMDeployment(driver.MachineName, driver.MachineName) + dockerVM, err := vmClient.GetVMDeployment(d.MachineName, d.MachineName) if err != nil { if strings.Contains(err.Error(), "Code: ResourceNotFound") { return state.Error, fmt.Errorf("Azure host was not found. Please check your Azure subscription.") @@ -285,13 +304,13 @@ func (driver *Driver) GetState() (state.State, error) { return state.None, nil } -func (driver *Driver) Start() error { - err := driver.setUserSubscription() +func (d *Driver) Start() error { + err := d.setUserSubscription() if err != nil { return err } - vmState, err := driver.GetState() + vmState, err := d.GetState() if err != nil { return err } @@ -300,29 +319,29 @@ func (driver *Driver) Start() error { return nil } - log.Debugf("starting %s", driver.MachineName) + log.Debugf("starting %s", d.MachineName) - err = vmClient.StartRole(driver.MachineName, driver.MachineName, driver.MachineName) + err = vmClient.StartRole(d.MachineName, d.MachineName, d.MachineName) if err != nil { return err } - err = driver.waitForSSH() + err = d.waitForSSH() if err != nil { return err } - err = driver.waitForDocker() + err = d.waitForDocker() if err != nil { return err } return nil } -func (driver *Driver) Stop() error { - err := driver.setUserSubscription() +func (d *Driver) Stop() error { + err := d.setUserSubscription() if err != nil { return err } - vmState, err := driver.GetState() + vmState, err := d.GetState() if err != nil { return err } @@ -331,21 +350,21 @@ func (driver *Driver) Stop() error { return nil } - log.Debugf("stopping %s", driver.MachineName) + log.Debugf("stopping %s", d.MachineName) - err = vmClient.ShutdownRole(driver.MachineName, driver.MachineName, driver.MachineName) + err = vmClient.ShutdownRole(d.MachineName, d.MachineName, d.MachineName) if err != nil { return err } return nil } -func (driver *Driver) Remove() error { - err := driver.setUserSubscription() +func (d *Driver) Remove() error { + err := d.setUserSubscription() if err != nil { return err } - available, _, err := vmClient.CheckHostedServiceNameAvailability(driver.MachineName) + available, _, err := vmClient.CheckHostedServiceNameAvailability(d.MachineName) if err != nil { return err } @@ -353,9 +372,9 @@ func (driver *Driver) Remove() error { return nil } - log.Debugf("removing %s", driver.MachineName) + log.Debugf("removing %s", d.MachineName) - err = vmClient.DeleteHostedService(driver.MachineName) + err = vmClient.DeleteHostedService(d.MachineName) if err != nil { return err } @@ -363,12 +382,12 @@ func (driver *Driver) Remove() error { return nil } -func (driver *Driver) Restart() error { - err := driver.setUserSubscription() +func (d *Driver) Restart() error { + err := d.setUserSubscription() if err != nil { return err } - vmState, err := driver.GetState() + vmState, err := d.GetState() if err != nil { return err } @@ -376,29 +395,29 @@ func (driver *Driver) Restart() error { return fmt.Errorf("Host is already stopped, use start command to run it") } - log.Debugf("restarting %s", driver.MachineName) + log.Debugf("restarting %s", d.MachineName) - err = vmClient.RestartRole(driver.MachineName, driver.MachineName, driver.MachineName) + err = vmClient.RestartRole(d.MachineName, d.MachineName, d.MachineName) if err != nil { return err } - err = driver.waitForSSH() + err = d.waitForSSH() if err != nil { return err } - err = driver.waitForDocker() + err = d.waitForDocker() if err != nil { return err } return nil } -func (driver *Driver) Kill() error { - err := driver.setUserSubscription() +func (d *Driver) Kill() error { + err := d.setUserSubscription() if err != nil { return err } - vmState, err := driver.GetState() + vmState, err := d.GetState() if err != nil { return err } @@ -407,102 +426,40 @@ func (driver *Driver) Kill() error { return nil } - log.Debugf("killing %s", driver.MachineName) + log.Debugf("killing %s", d.MachineName) - err = vmClient.ShutdownRole(driver.MachineName, driver.MachineName, driver.MachineName) + err = vmClient.ShutdownRole(d.MachineName, d.MachineName, d.MachineName) if err != nil { return err } return nil } -func (d *Driver) StartDocker() error { - log.Debug("Starting Docker...") - - cmd, err := d.GetSSHCommand("sudo service docker start") - if err != nil { - return err - } - if err := cmd.Run(); err != nil { - return err - } - - return nil -} - -func (d *Driver) StopDocker() error { - log.Debug("Stopping Docker...") - - cmd, err := d.GetSSHCommand("sudo service docker stop") - if err != nil { - return err - } - if err := cmd.Run(); err != nil { - return err - } - - return nil -} - func (d *Driver) GetDockerConfigDir() string { return dockerConfigDir } -func (driver *Driver) GetSSHCommand(args ...string) (*exec.Cmd, error) { - err := driver.setUserSubscription() - if err != nil { - return nil, err - } - - vmState, err := driver.GetState() - if err != nil { - return nil, err - } - - if vmState == state.Stopped { - return nil, fmt.Errorf("Azure host is stopped. Please start it before using ssh command.") - } - - return ssh.GetSSHCommand(driver.getHostname(), driver.SSHPort, driver.UserName, driver.sshKeyPath(), args...), nil -} - -func (driver *Driver) Upgrade() error { - log.Debugf("Upgrading Docker") - - cmd, err := driver.GetSSHCommand("sudo apt-get update && sudo apt-get install --upgrade lxc-docker") - if err != nil { - return err - - } - if err := cmd.Run(); err != nil { - return err - - } - - return cmd.Run() -} - func generateVMName() string { randomID := utils.TruncateID(utils.GenerateRandomID()) return fmt.Sprintf("docker-host-%s", randomID) } -func (driver *Driver) setUserSubscription() error { - if len(driver.PublishSettingsFilePath) != 0 { - err := azure.ImportPublishSettingsFile(driver.PublishSettingsFilePath) +func (d *Driver) setUserSubscription() error { + if len(d.PublishSettingsFilePath) != 0 { + err := azure.ImportPublishSettingsFile(d.PublishSettingsFilePath) if err != nil { return err } return nil } - err := azure.ImportPublishSettings(driver.SubscriptionID, driver.SubscriptionCert) + err := azure.ImportPublishSettings(d.SubscriptionID, d.SubscriptionCert) if err != nil { return err } return nil } -func (driver *Driver) addDockerEndpoint(vmConfig *vmClient.Role) error { +func (d *Driver) addDockerEndpoint(vmConfig *vmClient.Role) error { configSets := vmConfig.ConfigurationSets.ConfigurationSet if len(configSets) == 0 { return fmt.Errorf("no configuration set") @@ -514,17 +471,17 @@ func (driver *Driver) addDockerEndpoint(vmConfig *vmClient.Role) error { ep := vmClient.InputEndpoint{} ep.Name = "docker" ep.Protocol = "tcp" - ep.Port = driver.DockerPort - ep.LocalPort = driver.DockerPort + ep.Port = d.DockerPort + ep.LocalPort = d.DockerPort configSets[i].InputEndpoints.InputEndpoint = append(configSets[i].InputEndpoints.InputEndpoint, ep) - log.Debugf("added Docker endpoint (port %d) to configuration", driver.DockerPort) + log.Debugf("added Docker endpoint (port %d) to configuration", d.DockerPort) } return nil } -func (driver *Driver) waitForSSH() error { +func (d *Driver) waitForSSH() error { log.Infof("Waiting for SSH...") - err := ssh.WaitForTCP(fmt.Sprintf("%s:%v", driver.getHostname(), driver.SSHPort)) + err := ssh.WaitForTCP(fmt.Sprintf("%s:%v", d.getHostname(), d.SSHPort)) if err != nil { return err } @@ -532,10 +489,10 @@ func (driver *Driver) waitForSSH() error { return nil } -func (driver *Driver) waitForDocker() error { +func (d *Driver) waitForDocker() error { log.Infof("Waiting for docker daemon on host to be available...") maxRepeats := 48 - url := fmt.Sprintf("%s:%v", driver.getHostname(), driver.DockerPort) + url := fmt.Sprintf("%s:%v", d.getHostname(), d.DockerPort) success := waitForDockerEndpoint(url, maxRepeats) if !success { return fmt.Errorf("Can not run docker daemon on remote machine. Please try again.") @@ -561,12 +518,14 @@ func waitForDockerEndpoint(url string, maxRepeats int) bool { return true } -func (driver *Driver) generateCertForAzure() error { - if err := ssh.GenerateSSHKey(driver.sshKeyPath()); err != nil { +func (d *Driver) generateCertForAzure() error { + keyPath := d.GetSSHKeyPath() + + if err := ssh.GenerateSSHKey(keyPath); err != nil { return err } - cmd := exec.Command("openssl", "req", "-x509", "-key", driver.sshKeyPath(), "-nodes", "-days", "365", "-newkey", "rsa:2048", "-out", driver.azureCertPath(), "-subj", "/C=AU/ST=Some-State/O=InternetWidgitsPtyLtd/CN=\\*") + cmd := exec.Command("openssl", "req", "-x509", "-key", keyPath, "-nodes", "-days", "365", "-newkey", "rsa:2048", "-out", d.azureCertPath(), "-subj", "/C=AU/ST=Some-State/O=InternetWidgitsPtyLtd/CN=\\*") if err := cmd.Run(); err != nil { return err } @@ -574,18 +533,14 @@ func (driver *Driver) generateCertForAzure() error { return nil } -func (driver *Driver) sshKeyPath() string { - return filepath.Join(driver.storePath, "id_rsa") +func (d *Driver) publicSSHKeyPath() string { + return d.GetSSHKeyPath() + ".pub" } -func (driver *Driver) publicSSHKeyPath() string { - return driver.sshKeyPath() + ".pub" +func (d *Driver) azureCertPath() string { + return filepath.Join(d.storePath, "azure_cert.pem") } -func (driver *Driver) azureCertPath() string { - return filepath.Join(driver.storePath, "azure_cert.pem") -} - -func (driver *Driver) getHostname() string { - return driver.MachineName + ".cloudapp.net" +func (d *Driver) getHostname() string { + return d.MachineName + ".cloudapp.net" } diff --git a/drivers/drivers.go b/drivers/drivers.go index d0627b5549..46ad7eacdb 100644 --- a/drivers/drivers.go +++ b/drivers/drivers.go @@ -3,10 +3,12 @@ package drivers import ( "errors" "fmt" + "os/exec" "sort" "github.com/codegangsta/cli" "github.com/docker/machine/provider" + "github.com/docker/machine/ssh" "github.com/docker/machine/state" ) @@ -156,3 +158,20 @@ type DriverOptions interface { Int(key string) int Bool(key string) bool } + +func GetSSHCommandFromDriver(d Driver, args ...string) (*exec.Cmd, error) { + host, err := d.GetSSHHostname() + if err != nil { + return nil, err + } + + port, err := d.GetSSHPort() + if err != nil { + return nil, err + } + + user := d.GetSSHUsername() + keyPath := d.GetSSHKeyPath() + + return ssh.GetSSHCommand(host, port, user, keyPath, args...), nil +} diff --git a/drivers/virtualbox/virtualbox.go b/drivers/virtualbox/virtualbox.go index 21e53f84f4..d218a00745 100644 --- a/drivers/virtualbox/virtualbox.go +++ b/drivers/virtualbox/virtualbox.go @@ -461,24 +461,6 @@ func (d *Driver) setMachineNameIfNotSet() { } } -// getSSHCommand returns a command suitable for ssh -func (d *Driver) getSSHCommand(args ...string) (*exec.Cmd, error) { - host, err := d.GetSSHHostname() - if err != nil { - return nil, err - } - - port, err := d.GetSSHPort() - if err != nil { - return nil, err - } - - user := d.GetSSHUsername() - keyPath := d.GetSSHKeyPath() - - return ssh.GetSSHCommand(host, port, user, keyPath, args...), nil -} - func (d *Driver) GetIP() (string, error) { // DHCP is used to get the IP, so virtualbox hosts don't have IPs unless // they are running @@ -489,7 +471,7 @@ func (d *Driver) GetIP() (string, error) { if s != state.Running { return "", drivers.ErrHostIsNotRunning } - cmd, err := d.getSSHCommand("ip addr show dev eth1") + cmd, err := drivers.GetSSHCommandFromDriver(d, "ip addr show dev eth1") if err != nil { return "", err } diff --git a/host.go b/host.go index 7ff301a995..f365270533 100644 --- a/host.go +++ b/host.go @@ -117,6 +117,8 @@ func (h *Host) GetDockerConfigDir() (string, error) { return "/var/lib/boot2docker", nil case provider.Remote: return "/etc/default", nil + case provider.None: + return "", nil default: return "", ErrUnknownHypervisorType } From ec91959979a09573390eb870f0add57a9f150aa8 Mon Sep 17 00:00:00 2001 From: Evan Hazlett Date: Mon, 9 Mar 2015 23:18:18 -0400 Subject: [PATCH 16/29] google: updated to new driver interface Signed-off-by: Evan Hazlett --- commands.go | 2 +- drivers/google/compute_util.go | 40 +------ drivers/google/google.go | 211 +++++++++++++++------------------ 3 files changed, 98 insertions(+), 155 deletions(-) diff --git a/commands.go b/commands.go index 01f03194aa..d7c922cfd9 100644 --- a/commands.go +++ b/commands.go @@ -18,7 +18,7 @@ import ( _ "github.com/docker/machine/drivers/amazonec2" _ "github.com/docker/machine/drivers/azure" _ "github.com/docker/machine/drivers/digitalocean" - //_ "github.com/docker/machine/drivers/google" + _ "github.com/docker/machine/drivers/google" //_ "github.com/docker/machine/drivers/hyperv" _ "github.com/docker/machine/drivers/none" //_ "github.com/docker/machine/drivers/openstack" diff --git a/drivers/google/compute_util.go b/drivers/google/compute_util.go index a5a4a7fe23..45ee1c00cb 100644 --- a/drivers/google/compute_util.go +++ b/drivers/google/compute_util.go @@ -28,8 +28,7 @@ type ComputeUtil struct { } const ( - apiURL = "https://www.googleapis.com/compute/v1/projects/" - //imageName = "https://www.googleapis.com/compute/v1/projects/google-containers/global/images/container-vm-v20150129" + apiURL = "https://www.googleapis.com/compute/v1/projects/" imageName = "https://www.googleapis.com/compute/v1/projects/ubuntu-os-cloud/global/images/ubuntu-1404-trusty-v20150128" firewallRule = "docker-machines" port = "2376" @@ -48,7 +47,7 @@ func newComputeUtil(driver *Driver) (*ComputeUtil, error) { authTokenPath: driver.AuthTokenPath, zone: driver.Zone, instanceName: driver.MachineName, - userName: driver.UserName, + userName: driver.SSHUser, project: driver.Project, service: service, zoneURL: apiURL + driver.Project + "/zones/" + driver.Zone, @@ -203,7 +202,7 @@ func (c *ComputeUtil) createInstance(d *Driver) error { c.waitForSSH(ip) // Update the SSH Key - sshKey, err := ioutil.ReadFile(d.publicSSHKeyPath) + sshKey, err := ioutil.ReadFile(d.GetSSHKeyPath() + ".pub") if err != nil { return err } @@ -226,39 +225,6 @@ func (c *ComputeUtil) createInstance(d *Driver) error { return err } - log.Info("Configuring Machine...") - - log.Debugf("Setting hostname: %s", d.MachineName) - cmd, err := d.GetSSHCommand(fmt.Sprintf( - "echo \"127.0.0.1 %s\" | sudo tee -a /etc/hosts && sudo hostname %s && echo \"%s\" | sudo tee /etc/hostname", - d.MachineName, - d.MachineName, - d.MachineName, - )) - - if err != nil { - return err - } - if err := cmd.Run(); err != nil { - return err - } - - return nil -} - -func (c *ComputeUtil) updateDocker(d *Driver) error { - log.Debugf("Upgrading Docker") - - cmd, err := d.GetSSHCommand("sudo apt-get update && sudo apt-get install --upgrade lxc-docker") - if err != nil { - return err - - } - if err := cmd.Run(); err != nil { - return err - - } - return nil } diff --git a/drivers/google/google.go b/drivers/google/google.go index 8a7ed10727..be3543bd74 100644 --- a/drivers/google/google.go +++ b/drivers/google/google.go @@ -2,16 +2,14 @@ package google import ( "fmt" - - "github.com/docker/machine/state" - - "os/exec" - "path" + "path/filepath" log "github.com/Sirupsen/logrus" "github.com/codegangsta/cli" "github.com/docker/machine/drivers" + "github.com/docker/machine/provider" "github.com/docker/machine/ssh" + "github.com/docker/machine/state" ) const ( @@ -20,29 +18,27 @@ const ( // Driver is a struct compatible with the docker.hosts.drivers.Driver interface. type Driver struct { - MachineName string - Zone string - MachineType string - Scopes string - DiskSize int - AuthTokenPath string - storePath string - UserName string - Project string - CaCertPath string - PrivateKeyPath string - sshKeyPath string - publicSSHKeyPath string - SwarmMaster bool - SwarmHost string - SwarmDiscovery string + MachineName string + SSHUser string + SSHPort int + Zone string + MachineType string + Scopes string + DiskSize int + AuthTokenPath string + storePath string + Project string + CaCertPath string + PrivateKeyPath string + SwarmMaster bool + SwarmHost string + SwarmDiscovery string } // CreateFlags are the command line flags used to create a driver. type CreateFlags struct { Zone *string MachineType *string - UserName *string Project *string Scopes *string DiskSize *int @@ -105,40 +101,71 @@ func GetCreateFlags() []cli.Flag { // NewDriver creates a Driver with the specified storePath. func NewDriver(machineName string, storePath string, caCert string, privateKey string) (drivers.Driver, error) { return &Driver{ - MachineName: machineName, - storePath: storePath, - CaCertPath: caCert, - PrivateKeyPath: privateKey, - sshKeyPath: path.Join(storePath, "id_rsa"), - publicSSHKeyPath: path.Join(storePath, "id_rsa.pub"), + MachineName: machineName, + storePath: storePath, + CaCertPath: caCert, + PrivateKeyPath: privateKey, }, nil } +func (d *Driver) AuthorizePort(ports []*drivers.Port) error { + return nil +} + +func (d *Driver) DeauthorizePort(ports []*drivers.Port) error { + return nil +} + +func (d *Driver) GetMachineName() string { + return d.MachineName +} + +func (d *Driver) GetSSHHostname() (string, error) { + return d.GetIP() +} + +func (d *Driver) GetSSHKeyPath() string { + return filepath.Join(d.storePath, "id_rsa") +} + +func (d *Driver) GetSSHPort() (int, error) { + return d.SSHPort, nil +} + +func (d *Driver) GetSSHUsername() string { + return d.SSHUser +} + +func (d *Driver) GetProviderType() provider.ProviderType { + return provider.Remote +} + // DriverName returns the name of the driver. -func (driver *Driver) DriverName() string { +func (d *Driver) DriverName() string { return "google" } // SetConfigFromFlags initializes the driver based on the command line flags. -func (driver *Driver) SetConfigFromFlags(flags drivers.DriverOptions) error { - driver.Zone = flags.String("google-zone") - driver.MachineType = flags.String("google-machine-type") - driver.DiskSize = flags.Int("google-disk-size") - driver.UserName = flags.String("google-username") - driver.AuthTokenPath = flags.String("google-auth-token") - driver.Project = flags.String("google-project") - driver.Scopes = flags.String("google-scopes") - driver.SwarmMaster = flags.Bool("swarm-master") - driver.SwarmHost = flags.String("swarm-host") - driver.SwarmDiscovery = flags.String("swarm-discovery") - if driver.Project == "" { +func (d *Driver) SetConfigFromFlags(flags drivers.DriverOptions) error { + d.Zone = flags.String("google-zone") + d.MachineType = flags.String("google-machine-type") + d.DiskSize = flags.Int("google-disk-size") + d.AuthTokenPath = flags.String("google-auth-token") + d.Project = flags.String("google-project") + d.Scopes = flags.String("google-scopes") + d.SwarmMaster = flags.Bool("swarm-master") + d.SwarmHost = flags.String("swarm-host") + d.SwarmDiscovery = flags.String("swarm-discovery") + if d.Project == "" { return fmt.Errorf("Please specify the Google Cloud Project name using the option --google-project.") } + d.SSHUser = flags.String("google-username") + d.SSHPort = 22 return nil } -func (driver *Driver) initApis() (*ComputeUtil, error) { - return newComputeUtil(driver) +func (d *Driver) initApis() (*ComputeUtil, error) { + return newComputeUtil(d) } func (d *Driver) PreCreateCheck() error { @@ -146,8 +173,8 @@ func (d *Driver) PreCreateCheck() error { } // Create creates a GCE VM instance acting as a docker host. -func (driver *Driver) Create() error { - c, err := newComputeUtil(driver) +func (d *Driver) Create() error { + c, err := newComputeUtil(d) if err != nil { return err } @@ -155,20 +182,20 @@ func (driver *Driver) Create() error { // Check if the instance already exists. There will be an error if the instance // doesn't exist, so just check instance for nil. if instance, _ := c.instance(); instance != nil { - return fmt.Errorf("Instance %v already exists.", driver.MachineName) + return fmt.Errorf("Instance %v already exists.", d.MachineName) } log.Infof("Generating SSH Key") - if err := ssh.GenerateSSHKey(driver.sshKeyPath); err != nil { + if err := ssh.GenerateSSHKey(d.GetSSHKeyPath()); err != nil { return err } - return c.createInstance(driver) + return c.createInstance(d) } // GetURL returns the URL of the remote docker daemon. -func (driver *Driver) GetURL() (string, error) { - ip, err := driver.GetIP() +func (d *Driver) GetURL() (string, error) { + ip, err := d.GetIP() if err != nil { return "", err } @@ -177,8 +204,8 @@ func (driver *Driver) GetURL() (string, error) { } // GetIP returns the IP address of the GCE instance. -func (driver *Driver) GetIP() (string, error) { - c, err := newComputeUtil(driver) +func (d *Driver) GetIP() (string, error) { + c, err := newComputeUtil(d) if err != nil { return "", err } @@ -186,8 +213,8 @@ func (driver *Driver) GetIP() (string, error) { } // GetState returns a docker.hosts.state.State value representing the current state of the host. -func (driver *Driver) GetState() (state.State, error) { - c, err := newComputeUtil(driver) +func (d *Driver) GetState() (state.State, error) { + c, err := newComputeUtil(d) if err != nil { return state.None, err } @@ -215,17 +242,17 @@ func (driver *Driver) GetState() (state.State, error) { } // Start creates a GCE instance and attaches it to the existing disk. -func (driver *Driver) Start() error { - c, err := newComputeUtil(driver) +func (d *Driver) Start() error { + c, err := newComputeUtil(d) if err != nil { return err } - return c.createInstance(driver) + return c.createInstance(d) } // Stop deletes the GCE instance, but keeps the disk. -func (driver *Driver) Stop() error { - c, err := newComputeUtil(driver) +func (d *Driver) Stop() error { + c, err := newComputeUtil(d) if err != nil { return err } @@ -233,12 +260,12 @@ func (driver *Driver) Stop() error { } // Remove deletes the GCE instance and the disk. -func (driver *Driver) Remove() error { - c, err := newComputeUtil(driver) +func (d *Driver) Remove() error { + c, err := newComputeUtil(d) if err != nil { return err } - s, err := driver.GetState() + s, err := d.GetState() if err != nil { return err } @@ -251,8 +278,8 @@ func (driver *Driver) Remove() error { } // Restart deletes and recreates the GCE instance, keeping the disk. -func (driver *Driver) Restart() error { - c, err := newComputeUtil(driver) +func (d *Driver) Restart() error { + c, err := newComputeUtil(d) if err != nil { return err } @@ -260,60 +287,10 @@ func (driver *Driver) Restart() error { return err } - return c.createInstance(driver) + return c.createInstance(d) } // Kill deletes the GCE instance, but keeps the disk. -func (driver *Driver) Kill() error { - return driver.Stop() -} - -func (d *Driver) StartDocker() error { - log.Debug("Starting Docker...") - - cmd, err := d.GetSSHCommand("sudo service docker start") - if err != nil { - return err - } - if err := cmd.Run(); err != nil { - return err - } - - return nil -} - -func (d *Driver) StopDocker() error { - log.Debug("Stopping Docker...") - - cmd, err := d.GetSSHCommand("sudo service docker stop") - if err != nil { - return err - } - if err := cmd.Run(); err != nil { - return err - } - - return nil -} - -func (d *Driver) GetDockerConfigDir() string { - return dockerConfigDir -} - -// GetSSHCommand returns a command that will run over SSH on the GCE instance. -func (driver *Driver) GetSSHCommand(args ...string) (*exec.Cmd, error) { - ip, err := driver.GetIP() - if err != nil { - return nil, err - } - return ssh.GetSSHCommand(ip, 22, driver.UserName, driver.sshKeyPath, args...), nil -} - -// Upgrade upgrades the docker daemon on the host to the latest version. -func (driver *Driver) Upgrade() error { - c, err := newComputeUtil(driver) - if err != nil { - return err - } - return c.updateDocker(driver) +func (d *Driver) Kill() error { + return d.Stop() } From 7e362cf4a37bd99d3febaf05370a82536ae201e3 Mon Sep 17 00:00:00 2001 From: Evan Hazlett Date: Mon, 9 Mar 2015 23:24:11 -0400 Subject: [PATCH 17/29] hyperv: updated for new driver interface Signed-off-by: Evan Hazlett --- commands.go | 2 +- drivers/hyperv/hyperv_windows.go | 126 ++++++++++--------------------- 2 files changed, 40 insertions(+), 88 deletions(-) diff --git a/commands.go b/commands.go index d7c922cfd9..7421ac54c3 100644 --- a/commands.go +++ b/commands.go @@ -19,7 +19,7 @@ import ( _ "github.com/docker/machine/drivers/azure" _ "github.com/docker/machine/drivers/digitalocean" _ "github.com/docker/machine/drivers/google" - //_ "github.com/docker/machine/drivers/hyperv" + _ "github.com/docker/machine/drivers/hyperv" _ "github.com/docker/machine/drivers/none" //_ "github.com/docker/machine/drivers/openstack" //_ "github.com/docker/machine/drivers/rackspace" diff --git a/drivers/hyperv/hyperv_windows.go b/drivers/hyperv/hyperv_windows.go index 858436531f..3b9e91d806 100644 --- a/drivers/hyperv/hyperv_windows.go +++ b/drivers/hyperv/hyperv_windows.go @@ -6,13 +6,13 @@ import ( "fmt" "io/ioutil" "os" - "os/exec" "path/filepath" "time" log "github.com/Sirupsen/logrus" "github.com/codegangsta/cli" "github.com/docker/machine/drivers" + "github.com/docker/machine/provider" "github.com/docker/machine/ssh" "github.com/docker/machine/state" "github.com/docker/machine/utils" @@ -23,6 +23,8 @@ const ( ) type Driver struct { + SSHUser string + SSHPort int storePath string boot2DockerURL string boot2DockerLoc string @@ -83,6 +85,8 @@ func (d *Driver) SetConfigFromFlags(flags drivers.DriverOptions) error { d.SwarmMaster = flags.Bool("swarm-master") d.SwarmHost = flags.String("swarm-host") d.SwarmDiscovery = flags.String("swarm-discovery") + d.SSHUser = "docker" + d.SSHPort = 22 return nil } @@ -90,6 +94,38 @@ func NewDriver(machineName string, storePath string, caCert string, privateKey s return &Driver{MachineName: machineName, storePath: storePath, CaCertPath: caCert, PrivateKeyPath: privateKey}, nil } +func (d *Driver) AuthorizePort(ports []*drivers.Port) error { + return nil +} + +func (d *Driver) DeauthorizePort(ports []*drivers.Port) error { + return nil +} + +func (d *Driver) GetMachineName() string { + return d.MachineName +} + +func (d *Driver) GetSSHHostname() (string, error) { + return d.GetIP() +} + +func (d *Driver) GetSSHKeyPath() string { + return filepath.Join(d.storePath, "id_rsa") +} + +func (d *Driver) GetSSHPort() (int, error) { + return d.SSHPort, nil +} + +func (d *Driver) GetSSHUsername() string { + return d.SSHUser +} + +func (d *Driver) GetProviderType() provider.ProviderType { + return provider.Local +} + func (d *Driver) DriverName() string { return "hyper-v" } @@ -195,7 +231,7 @@ func (d *Driver) Create() error { log.Infof("Creating SSH key...") - if err := ssh.GenerateSSHKey(d.sshKeyPath()); err != nil { + if err := ssh.GenerateSSHKey(d.GetSSHKeyPath()); err != nil { return err } @@ -253,21 +289,6 @@ func (d *Driver) Create() error { return err } - log.Infof("Setting hostname...") - cmd, err := d.GetSSHCommand(fmt.Sprintf( - "sudo hostname %s && echo \"%s\" | sudo tee /var/lib/boot2docker/etc/hostname", - d.MachineName, - d.MachineName, - )) - if err != nil { - return err - - } - if err := cmd.Run(); err != nil { - return err - - } - return nil } @@ -412,77 +433,8 @@ func (d *Driver) GetIP() (string, error) { return resp[0], nil } -func (d *Driver) GetSSHCommand(args ...string) (*exec.Cmd, error) { - ip, err := d.GetIP() - if err != nil { - return nil, err - } - return ssh.GetSSHCommand(ip, 22, "docker", d.sshKeyPath(), args...), nil -} - -func (d *Driver) Upgrade() error { - log.Infof("Stopping machine...") - if err := d.Stop(); err != nil { - return err - } - - b2dutils := utils.NewB2dUtils("", "") - isoURL, err := b2dutils.GetLatestBoot2DockerReleaseURL() - if err != nil { - return err - } - - log.Infof("Downloading boot2docker...") - if err := b2dutils.DownloadISO(d.storePath, "boot2docker.iso", isoURL); err != nil { - return err - } - - log.Infof("Starting machine...") - if err := d.Start(); err != nil { - return err - } - - return nil -} - -func (d *Driver) StartDocker() error { - log.Debug("Starting Docker...") - - cmd, err := d.GetSSHCommand("sudo /etc/init.d/docker start") - if err != nil { - return err - } - if err := cmd.Run(); err != nil { - return err - } - - return nil -} - -func (d *Driver) StopDocker() error { - log.Debug("Stopping Docker...") - - cmd, err := d.GetSSHCommand("if [ -e /var/run/docker.pid ]; then sudo /etc/init.d/docker stop ; fi") - if err != nil { - return err - } - if err := cmd.Run(); err != nil { - return err - } - - return nil -} - -func (d *Driver) GetDockerConfigDir() string { - return dockerConfigDir -} - -func (d *Driver) sshKeyPath() string { - return filepath.Join(d.storePath, "id_rsa") -} - func (d *Driver) publicSSHKeyPath() string { - return d.sshKeyPath() + ".pub" + return d.GetSSHKeyPath() + ".pub" } func (d *Driver) generateDiskImage() error { From 6c931dadde46f20a3d499f7d192f20452895fc5f Mon Sep 17 00:00:00 2001 From: Evan Hazlett Date: Mon, 9 Mar 2015 23:27:17 -0400 Subject: [PATCH 18/29] openstack: update for new driver interface Signed-off-by: Evan Hazlett --- commands.go | 2 +- drivers/openstack/openstack.go | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/commands.go b/commands.go index 7421ac54c3..39ffb6d5c5 100644 --- a/commands.go +++ b/commands.go @@ -21,7 +21,7 @@ import ( _ "github.com/docker/machine/drivers/google" _ "github.com/docker/machine/drivers/hyperv" _ "github.com/docker/machine/drivers/none" - //_ "github.com/docker/machine/drivers/openstack" + _ "github.com/docker/machine/drivers/openstack" //_ "github.com/docker/machine/drivers/rackspace" //_ "github.com/docker/machine/drivers/softlayer" _ "github.com/docker/machine/drivers/virtualbox" diff --git a/drivers/openstack/openstack.go b/drivers/openstack/openstack.go index cacff28f45..2d07503027 100644 --- a/drivers/openstack/openstack.go +++ b/drivers/openstack/openstack.go @@ -5,6 +5,7 @@ import ( "io/ioutil" "os/exec" "path" + "path/filepath" "strings" "time" @@ -12,6 +13,7 @@ import ( "github.com/codegangsta/cli" "github.com/docker/docker/utils" "github.com/docker/machine/drivers" + "github.com/docker/machine/provider" "github.com/docker/machine/ssh" "github.com/docker/machine/state" ) @@ -203,6 +205,38 @@ func NewDerivedDriver(machineName string, storePath string, client Client, caCer }, nil } +func (d *Driver) AuthorizePort(ports []*drivers.Port) error { + return nil +} + +func (d *Driver) DeauthorizePort(ports []*drivers.Port) error { + return nil +} + +func (d *Driver) GetMachineName() string { + return d.MachineName +} + +func (d *Driver) GetSSHHostname() (string, error) { + return d.GetIP() +} + +func (d *Driver) GetSSHKeyPath() string { + return filepath.Join(d.storePath, "id_rsa") +} + +func (d *Driver) GetSSHPort() (int, error) { + return d.SSHPort, nil +} + +func (d *Driver) GetSSHUsername() string { + return d.SSHUser +} + +func (d *Driver) GetProviderType() provider.ProviderType { + return provider.Remote +} + func (d *Driver) DriverName() string { return "openstack" } From 6f098c817b5440784a317189cbd577261b22872e Mon Sep 17 00:00:00 2001 From: Evan Hazlett Date: Mon, 9 Mar 2015 23:29:52 -0400 Subject: [PATCH 19/29] openstack: driver cleanup for new interface Signed-off-by: Evan Hazlett --- drivers/openstack/openstack.go | 73 +--------------------------------- 1 file changed, 2 insertions(+), 71 deletions(-) diff --git a/drivers/openstack/openstack.go b/drivers/openstack/openstack.go index 2d07503027..06920eb495 100644 --- a/drivers/openstack/openstack.go +++ b/drivers/openstack/openstack.go @@ -3,8 +3,6 @@ package openstack import ( "fmt" "io/ioutil" - "os/exec" - "path" "path/filepath" "strings" "time" @@ -436,69 +434,6 @@ func (d *Driver) Kill() error { return d.Stop() } -func (d *Driver) Upgrade() error { - log.Debugf("Upgrading Docker") - - cmd, err := d.GetSSHCommand("sudo apt-get update && sudo apt-get install --upgrade lxc-docker") - if err != nil { - return err - - } - if err := cmd.Run(); err != nil { - return err - - } - - return cmd.Run() -} - -func (d *Driver) StartDocker() error { - log.Debug("Starting Docker...") - - cmd, err := d.GetSSHCommand("sudo service docker start") - if err != nil { - return err - } - if err := cmd.Run(); err != nil { - return err - } - - return nil -} - -func (d *Driver) StopDocker() error { - log.Debug("Stopping Docker...") - - cmd, err := d.GetSSHCommand("sudo service docker stop") - if err != nil { - return err - } - if err := cmd.Run(); err != nil { - return err - } - - return nil -} - -func (d *Driver) GetDockerConfigDir() string { - return dockerConfigDir -} - -func (d *Driver) GetSSHCommand(args ...string) (*exec.Cmd, error) { - ip, err := d.GetIP() - if err != nil { - return nil, err - } - - if len(args) != 0 && d.SSHUser != "root" { - cmd := strings.Replace(strings.Join(args, " "), "'", "\\'", -1) - args = []string{"sudo", "sh", "-c", fmt.Sprintf("'%s'", cmd)} - } - - log.WithField("MachineId", d.MachineId).Debug("Command: %s", args) - return ssh.GetSSHCommand(ip, d.SSHPort, d.SSHUser, d.sshKeyPath(), args...), nil -} - const ( errorMandatoryEnvOrOption string = "%s must be specified either using the environment variable %s or the CLI option %s" errorMandatoryOption string = "%s must be specified using the CLI option %s" @@ -658,7 +593,7 @@ func (d *Driver) initNetwork() error { func (d *Driver) createSSHKey() error { log.WithField("Name", d.KeyPairName).Debug("Creating Key Pair...") - if err := ssh.GenerateSSHKey(d.sshKeyPath()); err != nil { + if err := ssh.GenerateSSHKey(d.GetSSHKeyPath()); err != nil { return err } publicKey, err := ioutil.ReadFile(d.publicSSHKeyPath()) @@ -780,10 +715,6 @@ func (d *Driver) waitForInstanceToStart() error { return d.waitForSSHServer() } -func (d *Driver) sshKeyPath() string { - return path.Join(d.storePath, "id_rsa") -} - func (d *Driver) publicSSHKeyPath() string { - return d.sshKeyPath() + ".pub" + return d.GetSSHKeyPath() + ".pub" } From 272d15343abb1756c9afc0ff8f25c54b51d0e2d6 Mon Sep 17 00:00:00 2001 From: Evan Hazlett Date: Mon, 9 Mar 2015 23:39:44 -0400 Subject: [PATCH 20/29] rackspace: enable with new driver interface Signed-off-by: Evan Hazlett --- commands.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/commands.go b/commands.go index 39ffb6d5c5..cdeb0afee5 100644 --- a/commands.go +++ b/commands.go @@ -22,7 +22,7 @@ import ( _ "github.com/docker/machine/drivers/hyperv" _ "github.com/docker/machine/drivers/none" _ "github.com/docker/machine/drivers/openstack" - //_ "github.com/docker/machine/drivers/rackspace" + _ "github.com/docker/machine/drivers/rackspace" //_ "github.com/docker/machine/drivers/softlayer" _ "github.com/docker/machine/drivers/virtualbox" //_ "github.com/docker/machine/drivers/vmwarefusion" From 4b034fd1b6fe99efc000298b94ad63159399f59a Mon Sep 17 00:00:00 2001 From: Evan Hazlett Date: Mon, 9 Mar 2015 23:58:52 -0400 Subject: [PATCH 21/29] softlayer: update with new driver interface Signed-off-by: Evan Hazlett --- commands.go | 2 +- drivers/softlayer/driver.go | 102 +++++++++++++++--------------------- 2 files changed, 42 insertions(+), 62 deletions(-) diff --git a/commands.go b/commands.go index cdeb0afee5..ec53871228 100644 --- a/commands.go +++ b/commands.go @@ -23,7 +23,7 @@ import ( _ "github.com/docker/machine/drivers/none" _ "github.com/docker/machine/drivers/openstack" _ "github.com/docker/machine/drivers/rackspace" - //_ "github.com/docker/machine/drivers/softlayer" + _ "github.com/docker/machine/drivers/softlayer" _ "github.com/docker/machine/drivers/virtualbox" //_ "github.com/docker/machine/drivers/vmwarefusion" //_ "github.com/docker/machine/drivers/vmwarevcloudair" diff --git a/drivers/softlayer/driver.go b/drivers/softlayer/driver.go index 2c0ecb3345..4c4df1d92c 100644 --- a/drivers/softlayer/driver.go +++ b/drivers/softlayer/driver.go @@ -4,14 +4,14 @@ import ( "fmt" "io/ioutil" "os" - "os/exec" - "path" + "path/filepath" "regexp" "time" log "github.com/Sirupsen/logrus" "github.com/codegangsta/cli" "github.com/docker/machine/drivers" + "github.com/docker/machine/provider" "github.com/docker/machine/ssh" "github.com/docker/machine/state" ) @@ -27,6 +27,8 @@ type Driver struct { deviceConfig *deviceConfig Id int Client *Client + SSHUser string + SSHPort int MachineName string CaCertPath string PrivateKeyPath string @@ -59,6 +61,38 @@ func NewDriver(machineName string, storePath string, caCert string, privateKey s return &Driver{MachineName: machineName, storePath: storePath, CaCertPath: caCert, PrivateKeyPath: privateKey}, nil } +func (d *Driver) AuthorizePort(ports []*drivers.Port) error { + return nil +} + +func (d *Driver) DeauthorizePort(ports []*drivers.Port) error { + return nil +} + +func (d *Driver) GetMachineName() string { + return d.MachineName +} + +func (d *Driver) GetSSHHostname() (string, error) { + return d.GetIP() +} + +func (d *Driver) GetSSHKeyPath() string { + return filepath.Join(d.storePath, "id_rsa") +} + +func (d *Driver) GetSSHPort() (int, error) { + return d.SSHPort, nil +} + +func (d *Driver) GetSSHUsername() string { + return d.SSHUser +} + +func (d *Driver) GetProviderType() provider.ProviderType { + return provider.Remote +} + func GetCreateFlags() []cli.Flag { // Set hourly billing to true by default since codegangsta cli doesn't take default bool values if os.Getenv("SOFTLAYER_HOURLY_BILLING") == "" { @@ -188,6 +222,8 @@ func (d *Driver) SetConfigFromFlags(flags drivers.DriverOptions) error { d.SwarmMaster = flags.Bool("swarm-master") d.SwarmHost = flags.String("swarm-host") d.SwarmDiscovery = flags.String("swarm-discovery") + d.SSHUser = "root" + d.SSHPort = 22 if err := validateClientConfig(d.Client); err != nil { return err @@ -216,38 +252,6 @@ func (d *Driver) DriverName() string { return "softlayer" } -func (d *Driver) StartDocker() error { - log.Debug("Starting Docker...") - - cmd, err := d.GetSSHCommand("sudo service docker start") - if err != nil { - return err - } - if err := cmd.Run(); err != nil { - return err - } - - return nil -} - -func (d *Driver) StopDocker() error { - log.Debug("Stopping Docker...") - - cmd, err := d.GetSSHCommand("sudo service docker stop") - if err != nil { - return err - } - if err := cmd.Run(); err != nil { - return err - } - - return nil -} - -func (d *Driver) GetDockerConfigDir() string { - return dockerConfigDir -} - func (d *Driver) GetURL() (string, error) { ip, err := d.GetIP() if err != nil { @@ -283,10 +287,6 @@ func (d *Driver) GetState() (state.State, error) { return vmState, nil } -func (d *Driver) GetSSHCommand(args ...string) (*exec.Cmd, error) { - return ssh.GetSSHCommand(d.IPAddress, 22, "root", d.sshKeyPath(), args...), nil -} - func (d *Driver) PreCreateCheck() error { return nil } @@ -351,7 +351,7 @@ func (d *Driver) Create() error { waitForStart() ssh.WaitForTCP(d.IPAddress + ":22") - cmd, err := d.GetSSHCommand("sudo apt-get update && sudo apt-get install -y curl") + cmd, err := drivers.GetSSHCommandFromDriver(d, "sudo apt-get update && sudo apt-get install -y curl") if err != nil { return err @@ -382,7 +382,7 @@ func (d *Driver) buildHostSpec() *HostSpec { } func (d *Driver) createSSHKey() (*SshKey, error) { - if err := ssh.GenerateSSHKey(d.sshKeyPath()); err != nil { + if err := ssh.GenerateSSHKey(d.GetSSHKeyPath()); err != nil { return nil, err } @@ -400,11 +400,7 @@ func (d *Driver) createSSHKey() (*SshKey, error) { } func (d *Driver) publicSSHKeyPath() string { - return d.sshKeyPath() + ".pub" -} - -func (d *Driver) sshKeyPath() string { - return path.Join(d.storePath, "id_rsa") + return d.GetSSHKeyPath() + ".pub" } func (d *Driver) Kill() error { @@ -430,19 +426,3 @@ func (d *Driver) Start() error { func (d *Driver) Stop() error { return d.getClient().VirtualGuest().PowerOff(d.Id) } - -func (d *Driver) Upgrade() error { - log.Debugf("Upgrading Docker") - - cmd, err := d.GetSSHCommand("sudo apt-get update && sudo apt-get install --upgrade lxc-docker") - if err != nil { - return err - - } - if err := cmd.Run(); err != nil { - return err - - } - - return cmd.Run() -} From bff7e978cfbd6448d29a78cc46bd939976725686 Mon Sep 17 00:00:00 2001 From: Evan Hazlett Date: Tue, 10 Mar 2015 00:11:04 -0400 Subject: [PATCH 22/29] vmwarevcloudair: update with new driver interface Signed-off-by: Evan Hazlett --- commands.go | 2 +- drivers/vmwarevcloudair/vcloudair.go | 166 ++++++++++----------------- 2 files changed, 64 insertions(+), 104 deletions(-) diff --git a/commands.go b/commands.go index ec53871228..49bbaf15ee 100644 --- a/commands.go +++ b/commands.go @@ -26,7 +26,7 @@ import ( _ "github.com/docker/machine/drivers/softlayer" _ "github.com/docker/machine/drivers/virtualbox" //_ "github.com/docker/machine/drivers/vmwarefusion" - //_ "github.com/docker/machine/drivers/vmwarevcloudair" + _ "github.com/docker/machine/drivers/vmwarevcloudair" //_ "github.com/docker/machine/drivers/vmwarevsphere" "github.com/docker/machine/state" "github.com/docker/machine/utils" diff --git a/drivers/vmwarevcloudair/vcloudair.go b/drivers/vmwarevcloudair/vcloudair.go index b613b5318c..3e828e6b15 100644 --- a/drivers/vmwarevcloudair/vcloudair.go +++ b/drivers/vmwarevcloudair/vcloudair.go @@ -7,8 +7,7 @@ package vmwarevcloudair import ( "fmt" "io/ioutil" - "os/exec" - "path" + "path/filepath" "strings" "github.com/vmware/govcloudair" @@ -17,6 +16,7 @@ import ( "github.com/codegangsta/cli" "github.com/docker/docker/utils" "github.com/docker/machine/drivers" + "github.com/docker/machine/provider" "github.com/docker/machine/ssh" "github.com/docker/machine/state" ) @@ -36,6 +36,7 @@ type Driver struct { Catalog string CatalogItem string MachineName string + SSHUser string SSHPort int DockerPort int Provision bool @@ -61,6 +62,7 @@ type CreateFlags struct { Catalog *string CatalogItem *string Name *string + SSHUser string SSHPort *int DockerPort *int Provision *bool @@ -166,55 +168,88 @@ func NewDriver(machineName string, storePath string, caCert string, privateKey s return driver, nil } +func (d *Driver) AuthorizePort(ports []*drivers.Port) error { + return nil +} + +func (d *Driver) DeauthorizePort(ports []*drivers.Port) error { + return nil +} + +func (d *Driver) GetMachineName() string { + return d.MachineName +} + +func (d *Driver) GetSSHHostname() (string, error) { + return d.GetIP() +} + +func (d *Driver) GetSSHKeyPath() string { + return filepath.Join(d.storePath, "id_rsa") +} + +func (d *Driver) GetSSHPort() (int, error) { + return d.SSHPort, nil +} + +func (d *Driver) GetSSHUsername() string { + return d.SSHUser +} + +func (d *Driver) GetProviderType() provider.ProviderType { + return provider.Remote +} + // Driver interface implementation -func (driver *Driver) DriverName() string { +func (d *Driver) DriverName() string { return "vmwarevcloudair" } -func (driver *Driver) SetConfigFromFlags(flags drivers.DriverOptions) error { +func (d *Driver) SetConfigFromFlags(flags drivers.DriverOptions) error { - driver.UserName = flags.String("vmwarevcloudair-username") - driver.UserPassword = flags.String("vmwarevcloudair-password") - driver.VDCID = flags.String("vmwarevcloudair-vdcid") - driver.PublicIP = flags.String("vmwarevcloudair-publicip") - driver.SwarmMaster = flags.Bool("swarm-master") - driver.SwarmHost = flags.String("swarm-host") - driver.SwarmDiscovery = flags.String("swarm-discovery") + d.UserName = flags.String("vmwarevcloudair-username") + d.UserPassword = flags.String("vmwarevcloudair-password") + d.VDCID = flags.String("vmwarevcloudair-vdcid") + d.PublicIP = flags.String("vmwarevcloudair-publicip") + d.SwarmMaster = flags.Bool("swarm-master") + d.SwarmHost = flags.String("swarm-host") + d.SwarmDiscovery = flags.String("swarm-discovery") // Check for required Params - if driver.UserName == "" || driver.UserPassword == "" || driver.VDCID == "" || driver.PublicIP == "" { + if d.UserName == "" || d.UserPassword == "" || d.VDCID == "" || d.PublicIP == "" { return fmt.Errorf("Please specify vcloudair mandatory params using options: -vmwarevcloudair-username -vmwarevcloudair-password -vmwarevcloudair-vdcid and -vmwarevcloudair-publicip") } // If ComputeID is not set we're using a VPC, hence setting ComputeID = VDCID if flags.String("vmwarevcloudair-computeid") == "" { - driver.ComputeID = flags.String("vmwarevcloudair-vdcid") + d.ComputeID = flags.String("vmwarevcloudair-vdcid") } else { - driver.ComputeID = flags.String("vmwarevcloudair-computeid") + d.ComputeID = flags.String("vmwarevcloudair-computeid") } // If the Org VDC Network is empty, set it to the default routed network. if flags.String("vmwarevcloudair-orgvdcnetwork") == "" { - driver.OrgVDCNet = flags.String("vmwarevcloudair-vdcid") + "-default-routed" + d.OrgVDCNet = flags.String("vmwarevcloudair-vdcid") + "-default-routed" } else { - driver.OrgVDCNet = flags.String("vmwarevcloudair-orgvdcnetwork") + d.OrgVDCNet = flags.String("vmwarevcloudair-orgvdcnetwork") } // If the Edge Gateway is empty, just set it to the default edge gateway. if flags.String("vmwarevcloudair-edgegateway") == "" { - driver.EdgeGateway = flags.String("vmwarevcloudair-vdcid") + d.EdgeGateway = flags.String("vmwarevcloudair-vdcid") } else { - driver.EdgeGateway = flags.String("vmwarevcloudair-edgegateway") + d.EdgeGateway = flags.String("vmwarevcloudair-edgegateway") } - driver.Catalog = flags.String("vmwarevcloudair-catalog") - driver.CatalogItem = flags.String("vmwarevcloudair-catalogitem") + d.Catalog = flags.String("vmwarevcloudair-catalog") + d.CatalogItem = flags.String("vmwarevcloudair-catalogitem") - driver.DockerPort = flags.Int("vmwarevcloudair-docker-port") - driver.SSHPort = flags.Int("vmwarevcloudair-ssh-port") - driver.Provision = flags.Bool("vmwarevcloudair-provision") - driver.CPUCount = flags.Int("vmwarevcloudair-cpu-count") - driver.MemorySize = flags.Int("vmwarevcloudair-memory-size") + d.DockerPort = flags.Int("vmwarevcloudair-docker-port") + d.SSHUser = "root" + d.SSHPort = flags.Int("vmwarevcloudair-ssh-port") + d.Provision = flags.Bool("vmwarevcloudair-provision") + d.CPUCount = flags.Int("vmwarevcloudair-cpu-count") + d.MemorySize = flags.Int("vmwarevcloudair-memory-size") return nil } @@ -395,26 +430,10 @@ func (d *Driver) Create() error { return err } - log.Info("Configuring Machine...") - - log.Debugf("Setting hostname: %s", d.MachineName) - cmd, err := d.GetSSHCommand(fmt.Sprintf( - "echo \"127.0.0.1 %s\" | sudo tee -a /etc/hosts && sudo hostname %s && echo \"%s\" | sudo tee /etc/hostname", - d.MachineName, - d.MachineName, - d.MachineName, - )) - if err != nil { - return err - } - if err := cmd.Run(); err != nil { - return err - } - connTest := "ping -c 3 www.google.com >/dev/null 2>&1 && ( echo \"Connectivity and DNS tests passed.\" ) || ( echo \"Connectivity and DNS tests failed, trying to add Nameserver to resolv.conf\"; echo \"nameserver 8.8.8.8\" >> /etc/resolv.conf )" log.Debugf("Connectivity and DNS sanity test...") - cmd, err = d.GetSSHCommand(connTest) + cmd, err := drivers.GetSSHCommandFromDriver(d, connTest) if err != nil { return err } @@ -437,7 +456,6 @@ func (d *Driver) Create() error { } func (d *Driver) Remove() error { - p, err := govcloudair.NewClient() if err != nil { return err @@ -660,7 +678,6 @@ func (d *Driver) Restart() error { } func (d *Driver) Kill() error { - p, err := govcloudair.NewClient() if err != nil { return err @@ -703,58 +720,6 @@ func (d *Driver) Kill() error { } -func (d *Driver) StartDocker() error { - log.Debug("Starting Docker...") - - cmd, err := d.GetSSHCommand("sudo service docker start") - if err != nil { - return err - } - if err := cmd.Run(); err != nil { - return err - } - - return nil -} - -func (d *Driver) StopDocker() error { - log.Debug("Stopping Docker...") - - cmd, err := d.GetSSHCommand("sudo service docker stop") - if err != nil { - return err - } - if err := cmd.Run(); err != nil { - return err - } - - return nil -} - -func (d *Driver) GetDockerConfigDir() string { - return dockerConfigDir -} - -func (d *Driver) Upgrade() error { - log.Debugf("Upgrading Docker") - - cmd, err := d.GetSSHCommand("sudo apt-get update && sudo apt-get install --upgrade lxc-docker") - if err != nil { - return err - - } - if err := cmd.Run(); err != nil { - return err - - } - - return cmd.Run() -} - -func (d *Driver) GetSSHCommand(args ...string) (*exec.Cmd, error) { - return ssh.GetSSHCommand(d.PublicIP, d.SSHPort, "root", d.sshKeyPath(), args...), nil -} - // Helpers func generateVMName() string { @@ -763,8 +728,7 @@ func generateVMName() string { } func (d *Driver) createSSHKey() (string, error) { - - if err := ssh.GenerateSSHKey(d.sshKeyPath()); err != nil { + if err := ssh.GenerateSSHKey(d.GetSSHKeyPath()); err != nil { return "", err } @@ -776,10 +740,6 @@ func (d *Driver) createSSHKey() (string, error) { return string(publicKey), nil } -func (d *Driver) sshKeyPath() string { - return path.Join(d.storePath, "id_rsa") -} - func (d *Driver) publicSSHKeyPath() string { - return d.sshKeyPath() + ".pub" + return d.GetSSHKeyPath() + ".pub" } From 9e27af64e3f3e156f1f09b6fa05b550b885cfe8d Mon Sep 17 00:00:00 2001 From: Evan Hazlett Date: Tue, 10 Mar 2015 00:27:11 -0400 Subject: [PATCH 23/29] vmwarefusion: update with new driver interface Signed-off-by: Evan Hazlett --- commands.go | 2 +- drivers/vmwarefusion/fusion_darwin.go | 101 ++++++++++---------------- 2 files changed, 40 insertions(+), 63 deletions(-) diff --git a/commands.go b/commands.go index 49bbaf15ee..c7b53e3754 100644 --- a/commands.go +++ b/commands.go @@ -25,7 +25,7 @@ import ( _ "github.com/docker/machine/drivers/rackspace" _ "github.com/docker/machine/drivers/softlayer" _ "github.com/docker/machine/drivers/virtualbox" - //_ "github.com/docker/machine/drivers/vmwarefusion" + _ "github.com/docker/machine/drivers/vmwarefusion" _ "github.com/docker/machine/drivers/vmwarevcloudair" //_ "github.com/docker/machine/drivers/vmwarevsphere" "github.com/docker/machine/state" diff --git a/drivers/vmwarefusion/fusion_darwin.go b/drivers/vmwarefusion/fusion_darwin.go index 82bff84d36..4018387dad 100644 --- a/drivers/vmwarefusion/fusion_darwin.go +++ b/drivers/vmwarefusion/fusion_darwin.go @@ -11,7 +11,6 @@ import ( "io/ioutil" "net/http" "os" - "os/exec" "path" "path/filepath" "regexp" @@ -23,6 +22,7 @@ import ( log "github.com/Sirupsen/logrus" "github.com/codegangsta/cli" "github.com/docker/machine/drivers" + "github.com/docker/machine/provider" "github.com/docker/machine/ssh" "github.com/docker/machine/state" "github.com/docker/machine/utils" @@ -50,6 +50,8 @@ type Driver struct { SwarmHost string SwarmDiscovery string CPUS int + SSHUser string + SSHPort int storePath string } @@ -95,6 +97,38 @@ func NewDriver(machineName string, storePath string, caCert string, privateKey s return &Driver{MachineName: machineName, storePath: storePath, CaCertPath: caCert, PrivateKeyPath: privateKey}, nil } +func (d *Driver) AuthorizePort(ports []*drivers.Port) error { + return nil +} + +func (d *Driver) DeauthorizePort(ports []*drivers.Port) error { + return nil +} + +func (d *Driver) GetMachineName() string { + return d.MachineName +} + +func (d *Driver) GetSSHHostname() (string, error) { + return d.GetIP() +} + +func (d *Driver) GetSSHKeyPath() string { + return filepath.Join(d.storePath, "id_rsa") +} + +func (d *Driver) GetSSHPort() (int, error) { + return d.SSHPort, nil +} + +func (d *Driver) GetSSHUsername() string { + return d.SSHUser +} + +func (d *Driver) GetProviderType() provider.ProviderType { + return provider.Local +} + func (d *Driver) DriverName() string { return "vmwarefusion" } @@ -108,6 +142,8 @@ func (d *Driver) SetConfigFromFlags(flags drivers.DriverOptions) error { d.SwarmHost = flags.String("swarm-host") d.SwarmDiscovery = flags.String("swarm-discovery") d.CPUS = runtime.NumCPU() + d.SSHUser = "docker" + d.SSHPort = 22 // We support a maximum of 16 cpu to be consistent with Virtual Hardware 10 // specs. @@ -209,7 +245,7 @@ func (d *Driver) Create() error { } log.Infof("Creating SSH key...") - if err := ssh.GenerateSSHKey(d.sshKeyPath()); err != nil { + if err := ssh.GenerateSSHKey(d.GetSSHKeyPath()); err != nil { return err } @@ -284,20 +320,6 @@ func (d *Driver) Create() error { // Expand tar file. vmrun("-gu", B2D_USER, "-gp", B2D_PASS, "runScriptInGuest", d.vmxPath(), "/bin/sh", "sudo /bin/mv /home/docker/userdata.tar /var/lib/boot2docker/userdata.tar && sudo tar xf /var/lib/boot2docker/userdata.tar -C /home/docker/ > /var/log/userdata.log 2>&1 && sudo chown -R docker:staff /home/docker") - log.Debugf("Setting hostname: %s", d.MachineName) - cmd, err := d.GetSSHCommand(fmt.Sprintf( - "echo \"127.0.0.1 %s\" | sudo tee -a /etc/hosts && sudo hostname %s && echo \"%s\" | sudo tee /etc/hostname", - d.MachineName, - d.MachineName, - d.MachineName, - )) - if err != nil { - return err - } - if err := cmd.Run(); err != nil { - return err - } - return nil } @@ -338,51 +360,10 @@ func (d *Driver) Kill() error { return nil } -func (d *Driver) StartDocker() error { - log.Debug("Starting Docker...") - - cmd, err := d.GetSSHCommand("sudo /etc/init.d/docker start") - if err != nil { - return err - } - if err := cmd.Run(); err != nil { - return err - } - - return nil -} - -func (d *Driver) StopDocker() error { - log.Debug("Stopping Docker...") - - // Check if pidfile exists, then if process exists, depending on that stop docker or remove pidfile - cmd, err := d.GetSSHCommand("if [ -e /var/run/docker.pid ]; then if [ -f /proc/$(cat /var/run/docker.pid)/status ]; then sudo /etc/init.d/docker stop; else rm -f /var/run/docker.pid; fi fi") - if err != nil { - return err - } - if err := cmd.Run(); err != nil { - return err - } - - return nil -} - -func (d *Driver) GetDockerConfigDir() string { - return dockerConfigDir -} - func (d *Driver) Upgrade() error { return fmt.Errorf("VMware Fusion does not currently support the upgrade operation.") } -func (d *Driver) GetSSHCommand(args ...string) (*exec.Cmd, error) { - ip, err := d.GetIP() - if err != nil { - return nil, err - } - return ssh.GetSSHCommand(ip, 22, "docker", d.sshKeyPath(), args...), nil -} - func (d *Driver) vmxPath() string { return path.Join(d.storePath, fmt.Sprintf("%s.vmx", d.MachineName)) } @@ -500,12 +481,8 @@ func (d *Driver) getIPfromDHCPLease() (string, error) { } -func (d *Driver) sshKeyPath() string { - return path.Join(d.storePath, "id_rsa") -} - func (d *Driver) publicSSHKeyPath() string { - return d.sshKeyPath() + ".pub" + return d.GetSSHKeyPath() + ".pub" } // Make a boot2docker userdata.tar key bundle From 72f05505fa8c207bc7c13ccf277286756a41f5e6 Mon Sep 17 00:00:00 2001 From: Evan Hazlett Date: Tue, 10 Mar 2015 00:41:02 -0400 Subject: [PATCH 24/29] vmwarevsphere: update with new driver interface Signed-off-by: Evan Hazlett --- commands.go | 2 +- drivers/vmwarevsphere/vsphere.go | 100 ++++++++++++------------------- 2 files changed, 38 insertions(+), 64 deletions(-) diff --git a/commands.go b/commands.go index c7b53e3754..bbdead7a16 100644 --- a/commands.go +++ b/commands.go @@ -27,7 +27,7 @@ import ( _ "github.com/docker/machine/drivers/virtualbox" _ "github.com/docker/machine/drivers/vmwarefusion" _ "github.com/docker/machine/drivers/vmwarevcloudair" - //_ "github.com/docker/machine/drivers/vmwarevsphere" + _ "github.com/docker/machine/drivers/vmwarevsphere" "github.com/docker/machine/state" "github.com/docker/machine/utils" ) diff --git a/drivers/vmwarevsphere/vsphere.go b/drivers/vmwarevsphere/vsphere.go index 865299d0e7..936561889e 100644 --- a/drivers/vmwarevsphere/vsphere.go +++ b/drivers/vmwarevsphere/vsphere.go @@ -11,7 +11,6 @@ import ( "io/ioutil" "net/http" "os" - "os/exec" "path" "path/filepath" "strings" @@ -22,10 +21,10 @@ import ( "github.com/codegangsta/cli" "github.com/docker/machine/drivers" "github.com/docker/machine/drivers/vmwarevsphere/errors" + "github.com/docker/machine/provider" "github.com/docker/machine/ssh" "github.com/docker/machine/state" "github.com/docker/machine/utils" - // cssh "golang.org/x/crypto/ssh" ) const ( @@ -40,6 +39,7 @@ const ( type Driver struct { MachineName string + SSHUser string SSHPort int CPU int Memory int @@ -160,11 +160,44 @@ func NewDriver(machineName string, storePath string, caCert string, privateKey s return &Driver{MachineName: machineName, StorePath: storePath, CaCertPath: caCert, PrivateKeyPath: privateKey}, nil } +func (d *Driver) AuthorizePort(ports []*drivers.Port) error { + return nil +} + +func (d *Driver) DeauthorizePort(ports []*drivers.Port) error { + return nil +} + +func (d *Driver) GetMachineName() string { + return d.MachineName +} + +func (d *Driver) GetSSHHostname() (string, error) { + return d.GetIP() +} + +func (d *Driver) GetSSHKeyPath() string { + return filepath.Join(d.storePath, "id_rsa") +} + +func (d *Driver) GetSSHPort() (int, error) { + return d.SSHPort, nil +} + +func (d *Driver) GetSSHUsername() string { + return d.SSHUser +} + +func (d *Driver) GetProviderType() provider.ProviderType { + return provider.Local +} + func (d *Driver) DriverName() string { return "vmwarevsphere" } func (d *Driver) SetConfigFromFlags(flags drivers.DriverOptions) error { + d.SSHUser = "docker" d.SSHPort = 22 d.CPU = flags.Int("vmwarevsphere-cpu-count") d.Memory = flags.Int("vmwarevsphere-memory-size") @@ -243,7 +276,6 @@ func (d *Driver) Create() error { var ( isoURL string - err error ) b2dutils := utils.NewB2dUtils("", "") @@ -305,7 +337,7 @@ func (d *Driver) Create() error { } log.Infof("Generating SSH Keypair...") - if err := ssh.GenerateSSHKey(d.sshKeyPath()); err != nil { + if err := ssh.GenerateSSHKey(d.GetSSHKeyPath()); err != nil { return err } @@ -357,20 +389,6 @@ func (d *Driver) Create() error { return err } - log.Debugf("Setting hostname: %s", d.MachineName) - cmd, err := d.GetSSHCommand(fmt.Sprintf( - "echo \"127.0.0.1 %s\" | sudo tee -a /etc/hosts && sudo hostname %s && echo \"%s\" | sudo tee /etc/hostname", - d.MachineName, - d.MachineName, - d.MachineName, - )) - if err != nil { - return err - } - if err := cmd.Run(); err != nil { - return err - } - return nil } @@ -469,56 +487,12 @@ func (d *Driver) Kill() error { return nil } -func (d *Driver) StartDocker() error { - log.Debug("Starting Docker...") - - cmd, err := d.GetSSHCommand("sudo /etc/init.d/docker start") - if err != nil { - return err - } - if err := cmd.Run(); err != nil { - return err - } - - return nil -} - -func (d *Driver) StopDocker() error { - log.Debug("Stopping Docker...") - - cmd, err := d.GetSSHCommand("sudo /etc/init.d/docker stop") - if err != nil { - return err - } - if err := cmd.Run(); err != nil { - return err - } - - return nil -} - -func (d *Driver) GetDockerConfigDir() string { - return dockerConfigDir -} - func (d *Driver) Upgrade() error { return fmt.Errorf("upgrade is not supported for vsphere driver at this moment") } -func (d *Driver) GetSSHCommand(args ...string) (*exec.Cmd, error) { - ip, err := d.GetIP() - if err != nil { - return nil, err - } - return ssh.GetSSHCommand(ip, d.SSHPort, "docker", d.sshKeyPath(), args...), nil -} - -func (d *Driver) sshKeyPath() string { - return path.Join(d.storePath, "id_rsa") -} - func (d *Driver) publicSSHKeyPath() string { - return d.sshKeyPath() + ".pub" + return d.GetSSHKeyPath() + ".pub" } func (d *Driver) checkVsphereConfig() error { From b442515491e21b4dfdfab895f9ee6e8e5d05899b Mon Sep 17 00:00:00 2001 From: Evan Hazlett Date: Tue, 10 Mar 2015 00:44:57 -0400 Subject: [PATCH 25/29] add provider package tests Signed-off-by: Evan Hazlett --- provider/provider_test.go | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 provider/provider_test.go diff --git a/provider/provider_test.go b/provider/provider_test.go new file mode 100644 index 0000000000..60a5ebcf84 --- /dev/null +++ b/provider/provider_test.go @@ -0,0 +1,17 @@ +package provider + +import ( + "testing" +) + +func TestProviderType(t *testing.T) { + if None.String() != "" { + t.Fatal("None provider type should be empty string") + } + if Local.String() != "Local" { + t.Fatal("Local provider type should be 'Local'") + } + if Remote.String() != "Remote" { + t.Fatal("Remote provider type should be 'Remote'") + } +} From 645bf8ab90cb662fef6917aef197b693cf774d2a Mon Sep 17 00:00:00 2001 From: Evan Hazlett Date: Wed, 11 Mar 2015 22:04:52 -0400 Subject: [PATCH 26/29] amazonec2: add SSHUser to driver Signed-off-by: Evan Hazlett --- drivers/amazonec2/amazonec2.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/amazonec2/amazonec2.go b/drivers/amazonec2/amazonec2.go index 361189a724..56dd2a3c95 100644 --- a/drivers/amazonec2/amazonec2.go +++ b/drivers/amazonec2/amazonec2.go @@ -43,6 +43,7 @@ type Driver struct { Region string AMI string SSHKeyID int + SSHUser string SSHPort int KeyName string InstanceId string @@ -209,6 +210,7 @@ func (d *Driver) SetConfigFromFlags(flags drivers.DriverOptions) error { d.SwarmMaster = flags.Bool("swarm-master") d.SwarmHost = flags.String("swarm-host") d.SwarmDiscovery = flags.String("swarm-discovery") + d.SSHUser = "ubuntu" d.SSHPort = 22 if d.AccessKey == "" { @@ -429,7 +431,7 @@ func (d *Driver) GetSSHPort() (int, error) { } func (d *Driver) GetSSHUsername() string { - return "ubuntu" + return d.SSHUser } func (d *Driver) Start() error { From bc6b66c12213a93181aef7ec59dce4b115690fa1 Mon Sep 17 00:00:00 2001 From: Evan Hazlett Date: Wed, 11 Mar 2015 22:59:28 -0400 Subject: [PATCH 27/29] drivers: specify defaults if values are missing; i.e. config updates Signed-off-by: Evan Hazlett --- drivers/amazonec2/amazonec2.go | 8 ++++++++ drivers/azure/azure.go | 8 ++++++++ drivers/digitalocean/digitalocean.go | 8 ++++++++ drivers/google/google.go | 8 ++++++++ drivers/hyperv/hyperv_windows.go | 8 ++++++++ drivers/openstack/openstack.go | 8 ++++++++ drivers/softlayer/driver.go | 8 ++++++++ drivers/virtualbox/virtualbox.go | 4 ++++ drivers/vmwarefusion/fusion_darwin.go | 8 ++++++++ drivers/vmwarevcloudair/vcloudair.go | 8 ++++++++ drivers/vmwarevsphere/vsphere.go | 8 ++++++++ 11 files changed, 84 insertions(+) diff --git a/drivers/amazonec2/amazonec2.go b/drivers/amazonec2/amazonec2.go index 56dd2a3c95..88f89915bb 100644 --- a/drivers/amazonec2/amazonec2.go +++ b/drivers/amazonec2/amazonec2.go @@ -427,10 +427,18 @@ func (d *Driver) GetSSHHostname() (string, error) { } func (d *Driver) GetSSHPort() (int, error) { + if d.SSHPort == 0 { + d.SSHPort = 22 + } + return d.SSHPort, nil } func (d *Driver) GetSSHUsername() string { + if d.SSHUser == "" { + d.SSHUser = "ubuntu" + } + return d.SSHUser } diff --git a/drivers/azure/azure.go b/drivers/azure/azure.go index df6e6fcac6..6e10b051b7 100644 --- a/drivers/azure/azure.go +++ b/drivers/azure/azure.go @@ -138,10 +138,18 @@ func (d *Driver) GetSSHKeyPath() string { } func (d *Driver) GetSSHPort() (int, error) { + if d.SSHPort == 0 { + d.SSHPort = 22 + } + return d.SSHPort, nil } func (d *Driver) GetSSHUsername() string { + if d.SSHUser == "" { + d.SSHUser = "ubuntu" + } + return d.SSHUser } diff --git a/drivers/digitalocean/digitalocean.go b/drivers/digitalocean/digitalocean.go index c759352a79..50cc3dc3b6 100644 --- a/drivers/digitalocean/digitalocean.go +++ b/drivers/digitalocean/digitalocean.go @@ -122,10 +122,18 @@ func (d *Driver) GetSSHKeyPath() string { } func (d *Driver) GetSSHPort() (int, error) { + if d.SSHPort == 0 { + d.SSHPort = 22 + } + return d.SSHPort, nil } func (d *Driver) GetSSHUsername() string { + if d.SSHUser == "" { + d.SSHUser = "root" + } + return d.SSHUser } diff --git a/drivers/google/google.go b/drivers/google/google.go index be3543bd74..832276d14f 100644 --- a/drivers/google/google.go +++ b/drivers/google/google.go @@ -129,10 +129,18 @@ func (d *Driver) GetSSHKeyPath() string { } func (d *Driver) GetSSHPort() (int, error) { + if d.SSHPort == 0 { + d.SSHPort = 22 + } + return d.SSHPort, nil } func (d *Driver) GetSSHUsername() string { + if d.SSHUser == "" { + d.SSHUser = "docker-user" + } + return d.SSHUser } diff --git a/drivers/hyperv/hyperv_windows.go b/drivers/hyperv/hyperv_windows.go index 3b9e91d806..26bdd95c57 100644 --- a/drivers/hyperv/hyperv_windows.go +++ b/drivers/hyperv/hyperv_windows.go @@ -115,10 +115,18 @@ func (d *Driver) GetSSHKeyPath() string { } func (d *Driver) GetSSHPort() (int, error) { + if d.SSHPort == 0 { + d.SSHPort = 22 + } + return d.SSHPort, nil } func (d *Driver) GetSSHUsername() string { + if d.SSHUser == "" { + d.SSHUser = "docker" + } + return d.SSHUser } diff --git a/drivers/openstack/openstack.go b/drivers/openstack/openstack.go index 06920eb495..261b4b47ca 100644 --- a/drivers/openstack/openstack.go +++ b/drivers/openstack/openstack.go @@ -224,10 +224,18 @@ func (d *Driver) GetSSHKeyPath() string { } func (d *Driver) GetSSHPort() (int, error) { + if d.SSHPort == 0 { + d.SSHPort = 22 + } + return d.SSHPort, nil } func (d *Driver) GetSSHUsername() string { + if d.SSHUser == "" { + d.SSHUser = "root" + } + return d.SSHUser } diff --git a/drivers/softlayer/driver.go b/drivers/softlayer/driver.go index 26dc61b1d4..74f11eabd7 100644 --- a/drivers/softlayer/driver.go +++ b/drivers/softlayer/driver.go @@ -82,10 +82,18 @@ func (d *Driver) GetSSHKeyPath() string { } func (d *Driver) GetSSHPort() (int, error) { + if d.SSHPort == 0 { + d.SSHPort = 22 + } + return d.SSHPort, nil } func (d *Driver) GetSSHUsername() string { + if d.SSHUser == "" { + d.SSHUser = "root" + } + return d.SSHUser } diff --git a/drivers/virtualbox/virtualbox.go b/drivers/virtualbox/virtualbox.go index a55ed60d02..8e7005d72d 100644 --- a/drivers/virtualbox/virtualbox.go +++ b/drivers/virtualbox/virtualbox.go @@ -110,6 +110,10 @@ func (d *Driver) GetSSHPort() (int, error) { } func (d *Driver) GetSSHUsername() string { + if d.SSHUser == "" { + d.SSHUser = "docker" + } + return d.SSHUser } diff --git a/drivers/vmwarefusion/fusion_darwin.go b/drivers/vmwarefusion/fusion_darwin.go index 4018387dad..d52d9b8bdc 100644 --- a/drivers/vmwarefusion/fusion_darwin.go +++ b/drivers/vmwarefusion/fusion_darwin.go @@ -118,10 +118,18 @@ func (d *Driver) GetSSHKeyPath() string { } func (d *Driver) GetSSHPort() (int, error) { + if d.SSHPort == 0 { + d.SSHPort = 22 + } + return d.SSHPort, nil } func (d *Driver) GetSSHUsername() string { + if d.SSHUser == "" { + d.SSHUser = "docker" + } + return d.SSHUser } diff --git a/drivers/vmwarevcloudair/vcloudair.go b/drivers/vmwarevcloudair/vcloudair.go index 3e828e6b15..2560cc0510 100644 --- a/drivers/vmwarevcloudair/vcloudair.go +++ b/drivers/vmwarevcloudair/vcloudair.go @@ -189,10 +189,18 @@ func (d *Driver) GetSSHKeyPath() string { } func (d *Driver) GetSSHPort() (int, error) { + if d.SSHPort == 0 { + d.SSHPort = 22 + } + return d.SSHPort, nil } func (d *Driver) GetSSHUsername() string { + if d.SSHUser == "" { + d.SSHUser = "root" + } + return d.SSHUser } diff --git a/drivers/vmwarevsphere/vsphere.go b/drivers/vmwarevsphere/vsphere.go index 936561889e..5fcdb92b4b 100644 --- a/drivers/vmwarevsphere/vsphere.go +++ b/drivers/vmwarevsphere/vsphere.go @@ -181,10 +181,18 @@ func (d *Driver) GetSSHKeyPath() string { } func (d *Driver) GetSSHPort() (int, error) { + if d.SSHPort == 0 { + d.SSHPort = 22 + } + return d.SSHPort, nil } func (d *Driver) GetSSHUsername() string { + if d.SSHUser == "" { + d.SSHUser = "docker" + } + return d.SSHUser } From 4a416c6cf78cb3ce862dead9aa112371d051aeff Mon Sep 17 00:00:00 2001 From: Evan Hazlett Date: Thu, 12 Mar 2015 12:03:17 -0400 Subject: [PATCH 28/29] fixed b2d hostname regression Signed-off-by: Evan Hazlett --- host.go | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/host.go b/host.go index f365270533..81540478a6 100644 --- a/host.go +++ b/host.go @@ -487,6 +487,11 @@ func (h *Host) Create(name string) error { return err } + // set hostname + if err := h.SetHostname(); err != nil { + return err + } + // install docker if err := h.Provision(); err != nil { return err @@ -519,10 +524,6 @@ func (h *Host) Provision() error { return fmt.Errorf("error installing docker: %s\n%s\n", err, string(buf.Bytes())) } - if err := h.SetHostname(); err != nil { - return err - } - return nil } @@ -551,6 +552,11 @@ func (h *Host) SetHostname() error { err error ) + log.Debugf("setting hostname for provider type %s: %s", + h.Driver.GetProviderType(), + h.Name, + ) + switch h.Driver.GetProviderType() { case provider.Local: cmd, err = h.GetSSHCommand(fmt.Sprintf( From 7c5a0d512678e040daed7f3abbb0040e24a9fc50 Mon Sep 17 00:00:00 2001 From: Evan Hazlett Date: Thu, 12 Mar 2015 13:08:52 -0400 Subject: [PATCH 29/29] update tests for sethostname Signed-off-by: Evan Hazlett --- host.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/host.go b/host.go index 81540478a6..d579599e7f 100644 --- a/host.go +++ b/host.go @@ -558,6 +558,8 @@ func (h *Host) SetHostname() error { ) switch h.Driver.GetProviderType() { + case provider.None: + return nil case provider.Local: cmd, err = h.GetSSHCommand(fmt.Sprintf( "sudo hostname %s && echo \"%s\" | sudo tee /var/lib/boot2docker/etc/hostname",