From 861b16dba9020ae6cb3c62e699683db9554300cc Mon Sep 17 00:00:00 2001 From: Simon Thulbourn Date: Mon, 5 Jan 2015 16:45:08 +0000 Subject: [PATCH] add machine name to VM name and hostname This work sets the machine name in the Cloud API or Hypervisor. As well as setting the hostname inside the VM. I've added the machine name to the NewDriver func to allow for identification by Cloud APIs and for the driver package. Each driver will attempt to set the hostname for the VM, except for Azure, which sets it based on the DNS name. Signed-off-by: Simon Thulbourn --- drivers/amazonec2/amazonec2.go | 39 ++++++++++++++---- drivers/amazonec2/amz/ec2.go | 28 +++++++++++++ drivers/amazonec2/amz/tags.go | 6 +++ drivers/azure/azure.go | 45 ++++++++++----------- drivers/digitalocean/digitalocean.go | 37 ++++++++++------- drivers/drivers.go | 6 +-- drivers/drivers_test.go | 4 +- drivers/google/compute_util.go | 17 +++++++- drivers/google/google.go | 26 +++++------- drivers/google/integration_test.go | 5 ++- drivers/none/none.go | 2 +- drivers/virtualbox/virtualbox.go | 24 ++++++++--- drivers/vmwarefusion/fusion.go | 38 ++++++++++-------- drivers/vmwarefusion/vmx.go | 4 +- drivers/vmwarevcloudair/vcloudair.go | 59 ++++++++++++++-------------- drivers/vmwarevsphere/vsphere.go | 33 ++++++++-------- host.go | 6 +-- store.go | 3 +- 18 files changed, 237 insertions(+), 145 deletions(-) create mode 100644 drivers/amazonec2/amz/tags.go diff --git a/drivers/amazonec2/amazonec2.go b/drivers/amazonec2/amazonec2.go index ad302850c4..f199770f28 100644 --- a/drivers/amazonec2/amazonec2.go +++ b/drivers/amazonec2/amazonec2.go @@ -40,6 +40,7 @@ type Driver struct { InstanceId string InstanceType string IPAddress string + MachineName string SecurityGroupId string ReservationId string RootSize int64 @@ -126,9 +127,9 @@ func GetCreateFlags() []cli.Flag { } } -func NewDriver(storePath string) (drivers.Driver, error) { +func NewDriver(machineName string, storePath string) (drivers.Driver, error) { id := generateId() - return &Driver{Id: id, storePath: storePath}, nil + return &Driver{Id: id, MachineName: machineName, storePath: storePath}, nil } func (d *Driver) SetConfigFromFlags(flags drivers.DriverOptions) error { @@ -171,7 +172,7 @@ func (d *Driver) Create() error { group, err := d.createSecurityGroup() if err != nil { - return err + log.Fatalf("Please make sure you don't have a security group named: %s", d.MachineName) } bdm := &amz.BlockDeviceMapping{ @@ -219,15 +220,39 @@ func (d *Driver) Create() error { d.InstanceId, d.IPAddress) - log.Infof("Waiting for SSH...") + log.Infof("Waiting for SSH on %s:%d", d.IPAddress, 22) if err := ssh.WaitForTCP(fmt.Sprintf("%s:%d", d.IPAddress, 22)); err != nil { return err } + log.Debug("Settings tags for instance") + tags := map[string]string{ + "Name": d.MachineName, + } + + if err = d.getClient().CreateTags(d.InstanceId, tags); err != nil { + 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 + } + log.Debugf("Installing Docker") - cmd, err := d.GetSSHCommand("if [ ! -e /usr/bin/docker ]; then curl get.docker.io | sudo sh -; fi") + cmd, err = d.GetSSHCommand("if [ ! -e /usr/bin/docker ]; then curl get.docker.io | sudo sh -; fi") if err != nil { return err } @@ -483,7 +508,7 @@ func (d *Driver) createKeyPair() error { return err } - keyName := fmt.Sprintf("docker-machine-%s", d.Id) + keyName := d.MachineName log.Debugf("creating key pair: %s", keyName) @@ -511,7 +536,7 @@ func (d *Driver) terminate() error { func (d *Driver) createSecurityGroup() (*amz.SecurityGroup, error) { log.Debugf("creating security group in %s", d.VpcId) - grpName := fmt.Sprintf("docker-machine-%s", d.Id) + grpName := d.MachineName group, err := d.getClient().CreateSecurityGroup(grpName, "Docker Machine", d.VpcId) if err != nil { return nil, err diff --git a/drivers/amazonec2/amz/ec2.go b/drivers/amazonec2/amz/ec2.go index 33cd34b3d6..6d903888f5 100644 --- a/drivers/amazonec2/amz/ec2.go +++ b/drivers/amazonec2/amz/ec2.go @@ -274,6 +274,34 @@ func (e *EC2) ImportKeyPair(name, publicKey string) error { return nil } +func (e *EC2) CreateTags(id string, tags map[string]string) error { + v := url.Values{} + v.Set("Action", "CreateTags") + v.Set("ResourceId.1", id) + + counter := 1 + for k, val := range tags { + v.Set(fmt.Sprintf("Tag.%d.Key", counter), k) + v.Set(fmt.Sprintf("Tag.%d.Value", counter), val) + + counter += 1 + } + + resp, err := e.awsApiCall(v) + defer resp.Body.Close() + if err != nil { + return err + } + + createTagsResponse := &CreateTagsResponse{} + + if err := getDecodedResponse(resp, &createTagsResponse); err != nil { + return fmt.Errorf("Error decoding create tags response: %s", err) + } + + return nil +} + func (e *EC2) CreateSecurityGroup(name string, description string, vpcId string) (*SecurityGroup, error) { v := url.Values{} v.Set("Action", "CreateSecurityGroup") diff --git a/drivers/amazonec2/amz/tags.go b/drivers/amazonec2/amz/tags.go new file mode 100644 index 0000000000..0d25e90474 --- /dev/null +++ b/drivers/amazonec2/amz/tags.go @@ -0,0 +1,6 @@ +package amz + +type CreateTagsResponse struct { + RequestId string `xml:"requestId"` + Return bool `xml:"return"` +} diff --git a/drivers/azure/azure.go b/drivers/azure/azure.go index e97d74bce0..122a544d0a 100644 --- a/drivers/azure/azure.go +++ b/drivers/azure/azure.go @@ -21,6 +21,7 @@ import ( ) type Driver struct { + MachineName string SubscriptionID string SubscriptionCert string PublishSettingsFilePath string @@ -105,8 +106,8 @@ func GetCreateFlags() []cli.Flag { } } -func NewDriver(storePath string) (drivers.Driver, error) { - driver := &Driver{storePath: storePath} +func NewDriver(machineName string, storePath string) (drivers.Driver, error) { + driver := &Driver{MachineName: machineName, storePath: storePath} return driver, nil } @@ -119,7 +120,6 @@ func (driver *Driver) SetConfigFromFlags(flags drivers.DriverOptions) error { cert := flags.String("azure-subscription-cert") publishSettings := flags.String("azure-publish-settings-file") - name := flags.String("azure-name") image := flags.String("azure-image") username := flags.String("azure-username") @@ -141,12 +141,6 @@ func (driver *Driver) SetConfigFromFlags(flags drivers.DriverOptions) error { return fmt.Errorf("Please specify azure subscription params using options: --azure-subscription-id and --azure-subscription-cert or --azure-publish-settings-file") } - if name == "" { - driver.Name = generateVMName() - } else { - driver.Name = name - } - if image == "" { driver.Image = "b39f27a8b8c64d52b05eac6a62ebad85__Ubuntu-14_04_1-LTS-amd64-server-20140927-en-us-30GB" } else { @@ -173,8 +167,11 @@ func (driver *Driver) Create() error { return err } + t := time.Now().Format("20060102150405") + name := fmt.Sprintf("%s-%s", driver.MachineName, t) + log.Infof("Creating Azure host...") - vmConfig, err := vmClient.CreateAzureVMConfiguration(driver.Name, driver.Size, driver.Image, driver.Location) + vmConfig, err := vmClient.CreateAzureVMConfiguration(name, driver.Size, driver.Image, driver.Location) if err != nil { return err } @@ -192,7 +189,7 @@ func (driver *Driver) Create() error { return err } - if err := vmClient.CreateAzureVM(vmConfig, driver.Name, driver.Location); err != nil { + if err := vmClient.CreateAzureVM(vmConfig, name, driver.Location); err != nil { return err } @@ -358,7 +355,7 @@ func (driver *Driver) GetState() (state.State, error) { return state.Error, err } - dockerVM, err := vmClient.GetVMDeployment(driver.Name, driver.Name) + dockerVM, err := vmClient.GetVMDeployment(driver.MachineName, driver.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.") @@ -395,9 +392,9 @@ func (driver *Driver) Start() error { return nil } - log.Debugf("starting %s", driver.Name) + log.Debugf("starting %s", driver.MachineName) - err = vmClient.StartRole(driver.Name, driver.Name, driver.Name) + err = vmClient.StartRole(driver.MachineName, driver.MachineName, driver.MachineName) if err != nil { return err } @@ -426,9 +423,9 @@ func (driver *Driver) Stop() error { return nil } - log.Debugf("stopping %s", driver.Name) + log.Debugf("stopping %s", driver.MachineName) - err = vmClient.ShutdownRole(driver.Name, driver.Name, driver.Name) + err = vmClient.ShutdownRole(driver.MachineName, driver.MachineName, driver.MachineName) if err != nil { return err } @@ -440,7 +437,7 @@ func (driver *Driver) Remove() error { if err != nil { return err } - available, _, err := vmClient.CheckHostedServiceNameAvailability(driver.Name) + available, _, err := vmClient.CheckHostedServiceNameAvailability(driver.MachineName) if err != nil { return err } @@ -448,9 +445,9 @@ func (driver *Driver) Remove() error { return nil } - log.Debugf("removing %s", driver.Name) + log.Debugf("removing %s", driver.MachineName) - err = vmClient.DeleteHostedService(driver.Name) + err = vmClient.DeleteHostedService(driver.MachineName) if err != nil { return err } @@ -471,9 +468,9 @@ func (driver *Driver) Restart() error { return fmt.Errorf("Host is already stopped, use start command to run it") } - log.Debugf("restarting %s", driver.Name) + log.Debugf("restarting %s", driver.MachineName) - err = vmClient.RestartRole(driver.Name, driver.Name, driver.Name) + err = vmClient.RestartRole(driver.MachineName, driver.MachineName, driver.MachineName) if err != nil { return err } @@ -502,9 +499,9 @@ func (driver *Driver) Kill() error { return nil } - log.Debugf("killing %s", driver.Name) + log.Debugf("killing %s", driver.MachineName) - err = vmClient.ShutdownRole(driver.Name, driver.Name, driver.Name) + err = vmClient.ShutdownRole(driver.MachineName, driver.MachineName, driver.MachineName) if err != nil { return err } @@ -639,5 +636,5 @@ func (driver *Driver) azureCertPath() string { } func (driver *Driver) getHostname() string { - return driver.Name + ".cloudapp.net" + return driver.MachineName + ".cloudapp.net" } diff --git a/drivers/digitalocean/digitalocean.go b/drivers/digitalocean/digitalocean.go index b4e5c4ffb4..e6b6a76115 100644 --- a/drivers/digitalocean/digitalocean.go +++ b/drivers/digitalocean/digitalocean.go @@ -12,7 +12,7 @@ import ( log "github.com/Sirupsen/logrus" "github.com/codegangsta/cli" "github.com/digitalocean/godo" - "github.com/docker/docker/utils" + // "github.com/docker/docker/utils" "github.com/docker/machine/drivers" "github.com/docker/machine/ssh" "github.com/docker/machine/state" @@ -21,9 +21,9 @@ import ( type Driver struct { AccessToken string DropletID int - DropletName string Image string IPAddress string + MachineName string Region string SSHKeyID int Size string @@ -67,8 +67,8 @@ func GetCreateFlags() []cli.Flag { } } -func NewDriver(storePath string) (drivers.Driver, error) { - return &Driver{storePath: storePath}, nil +func NewDriver(machineName string, storePath string) (drivers.Driver, error) { + return &Driver{MachineName: machineName, storePath: storePath}, nil } func (d *Driver) DriverName() string { @@ -89,8 +89,6 @@ func (d *Driver) SetConfigFromFlags(flags drivers.DriverOptions) error { } func (d *Driver) Create() error { - d.setDropletNameIfNotSet() - log.Infof("Creating SSH key...") key, err := d.createSSHKey() @@ -106,7 +104,7 @@ func (d *Driver) Create() error { createRequest := &godo.DropletCreateRequest{ Image: d.Image, - Name: d.DropletName, + Name: d.MachineName, Region: d.Region, Size: d.Size, SSHKeys: []interface{}{d.SSHKeyID}, @@ -147,9 +145,24 @@ 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 + } + log.Debugf("HACK: Downloading version of Docker with identity auth...") - cmd, err := d.GetSSHCommand("stop docker") + cmd, err = d.GetSSHCommand("stop docker") if err != nil { return err } @@ -203,7 +216,7 @@ func (d *Driver) createSSHKey() (*godo.Key, error) { } createRequest := &godo.KeyCreateRequest{ - Name: d.DropletName, + Name: d.MachineName, PublicKey: string(publicKey), } @@ -303,12 +316,6 @@ func (d *Driver) GetSSHCommand(args ...string) (*exec.Cmd, error) { return ssh.GetSSHCommand(d.IPAddress, 22, "root", d.sshKeyPath(), args...), nil } -func (d *Driver) setDropletNameIfNotSet() { - if d.DropletName == "" { - d.DropletName = fmt.Sprintf("docker-host-%s", utils.GenerateRandomID()) - } -} - func (d *Driver) getClient() *godo.Client { t := &oauth.Transport{ Token: &oauth.Token{AccessToken: d.AccessToken}, diff --git a/drivers/drivers.go b/drivers/drivers.go index 81098ac9d3..e4530dde01 100644 --- a/drivers/drivers.go +++ b/drivers/drivers.go @@ -67,7 +67,7 @@ type Driver interface { // - RegisterCreateFlags: a function that takes the FlagSet for // "docker hosts create" and returns an object to pass to SetConfigFromFlags type RegisteredDriver struct { - New func(storePath string) (Driver, error) + New func(machineName string, storePath string) (Driver, error) GetCreateFlags func() []cli.Flag } @@ -92,12 +92,12 @@ func Register(name string, registeredDriver *RegisteredDriver) error { } // NewDriver creates a new driver of type "name" -func NewDriver(name string, storePath string) (Driver, error) { +func NewDriver(name string, machineName string, storePath string) (Driver, error) { driver, exists := drivers[name] if !exists { return nil, fmt.Errorf("hosts: Unknown driver %q", name) } - return driver.New(storePath) + return driver.New(machineName, storePath) } // GetCreateFlags runs GetCreateFlags for all of the drivers and diff --git a/drivers/drivers_test.go b/drivers/drivers_test.go index 1d558666c6..488135d398 100644 --- a/drivers/drivers_test.go +++ b/drivers/drivers_test.go @@ -8,7 +8,7 @@ import ( func TestGetCreateFlags(t *testing.T) { Register("foo", &RegisteredDriver{ - New: func(storePath string) (Driver, error) { return nil, nil }, + New: func(machineName string, storePath string) (Driver, error) { return nil, nil }, GetCreateFlags: func() []cli.Flag { return []cli.Flag{ cli.StringFlag{ @@ -33,7 +33,7 @@ func TestGetCreateFlags(t *testing.T) { }, }) Register("bar", &RegisteredDriver{ - New: func(storePath string) (Driver, error) { return nil, nil }, + New: func(machineName string, storePath string) (Driver, error) { return nil, nil }, GetCreateFlags: func() []cli.Flag { return []cli.Flag{ cli.StringFlag{ diff --git a/drivers/google/compute_util.go b/drivers/google/compute_util.go index 6f3651a0c7..2809194e81 100644 --- a/drivers/google/compute_util.go +++ b/drivers/google/compute_util.go @@ -56,7 +56,7 @@ func newComputeUtil(driver *Driver) (*ComputeUtil, error) { } c := ComputeUtil{ zone: driver.Zone, - instanceName: driver.InstanceName, + instanceName: driver.MachineName, userName: driver.UserName, project: driver.Project, service: service, @@ -207,6 +207,21 @@ func (c *ComputeUtil) createInstance(d *Driver) 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 c.updateDocker(d) } diff --git a/drivers/google/google.go b/drivers/google/google.go index 6d11c831b8..7dfaa01eb1 100644 --- a/drivers/google/google.go +++ b/drivers/google/google.go @@ -16,7 +16,7 @@ import ( // Driver is a struct compatible with the docker.hosts.drivers.Driver interface. type Driver struct { - InstanceName string + MachineName string Zone string MachineType string storePath string @@ -28,11 +28,10 @@ type Driver struct { // CreateFlags are the command line flags used to create a driver. type CreateFlags struct { - InstanceName *string - Zone *string - MachineType *string - UserName *string - Project *string + Zone *string + MachineType *string + UserName *string + Project *string } func init() { @@ -64,12 +63,6 @@ func GetCreateFlags() []cli.Flag { Value: "docker-user", EnvVar: "GOOGLE_USERNAME", }, - cli.StringFlag{ - Name: "google-instance-name", - Usage: "GCE Instance Name", - Value: "docker-machine", - EnvVar: "GOOGLE_INSTANCE_NAME", - }, cli.StringFlag{ Name: "google-project", Usage: "GCE Project", @@ -79,8 +72,10 @@ func GetCreateFlags() []cli.Flag { } // NewDriver creates a Driver with the specified storePath. -func NewDriver(storePath string) (drivers.Driver, error) { - return &Driver{storePath: storePath, +func NewDriver(machineName string, storePath string) (drivers.Driver, error) { + return &Driver{ + MachineName: machineName, + storePath: storePath, sshKeyPath: path.Join(storePath, "id_rsa"), publicSSHKeyPath: path.Join(storePath, "id_rsa.pub"), }, nil @@ -93,7 +88,6 @@ func (driver *Driver) DriverName() string { // SetConfigFromFlags initializes the driver based on the command line flags. func (driver *Driver) SetConfigFromFlags(flags drivers.DriverOptions) error { - driver.InstanceName = flags.String("google-instance-name") driver.Zone = flags.String("google-zone") driver.MachineType = flags.String("google-machine-type") driver.UserName = flags.String("google-username") @@ -118,7 +112,7 @@ 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.InstanceName) + return fmt.Errorf("Instance %v already exists.", driver.MachineName) } log.Infof("Generating SSH Key") diff --git a/drivers/google/integration_test.go b/drivers/google/integration_test.go index d708b2252e..7c89c99cf8 100644 --- a/drivers/google/integration_test.go +++ b/drivers/google/integration_test.go @@ -46,9 +46,11 @@ func init() { // go test can't take args from stdin, so the path to an existing token must be passed as a flag. os.Link(*tokenPath, path.Join(tmpDir, "gce_token")) + log.Fatal("hai") + driver = &Driver{ storePath: tmpDir, - InstanceName: "test-instance", + MachineName: "test-instance", Zone: "us-central1-a", MachineType: "n1-standard-1", UserName: os.Getenv("USER"), @@ -108,6 +110,7 @@ type operation struct { DiskExpected bool InstanceExpected bool State state.State + Arguments []interface{} } func TestBasicOperations(t *testing.T) { diff --git a/drivers/none/none.go b/drivers/none/none.go index 1122e852d1..45f02f5b5e 100644 --- a/drivers/none/none.go +++ b/drivers/none/none.go @@ -34,7 +34,7 @@ func GetCreateFlags() []cli.Flag { } } -func NewDriver(storePath string) (drivers.Driver, error) { +func NewDriver(machineName string, storePath string) (drivers.Driver, error) { return &Driver{}, nil } diff --git a/drivers/virtualbox/virtualbox.go b/drivers/virtualbox/virtualbox.go index 9de8197882..1ccafdb7b6 100644 --- a/drivers/virtualbox/virtualbox.go +++ b/drivers/virtualbox/virtualbox.go @@ -71,8 +71,8 @@ func GetCreateFlags() []cli.Flag { } } -func NewDriver(storePath string) (drivers.Driver, error) { - return &Driver{storePath: storePath}, nil +func NewDriver(machineName string, storePath string) (drivers.Driver, error) { + return &Driver{MachineName: machineName, storePath: storePath}, nil } func (d *Driver) DriverName() string { @@ -123,7 +123,6 @@ func (d *Driver) Create() error { if err != nil { return err } - d.setMachineNameIfNotSet() if d.Boot2DockerURL != "" { isoURL = d.Boot2DockerURL @@ -341,9 +340,9 @@ func (d *Driver) Create() error { return err } - extraArgs := `EXTRA_ARGS='--auth=identity - --auth-authorized-dir=/var/lib/boot2docker/.docker/authorized-keys.d - --auth-known-hosts=/var/lib/boot2docker/.docker/known-hosts.json + extraArgs := `EXTRA_ARGS='--auth=identity + --auth-authorized-dir=/var/lib/boot2docker/.docker/authorized-keys.d + --auth-known-hosts=/var/lib/boot2docker/.docker/known-hosts.json --identity=/var/lib/boot2docker/.docker/key.json -H tcp://0.0.0.0:2376'` sshCmd := fmt.Sprintf("echo \"%s\" | sudo tee -a /var/lib/boot2docker/profile", extraArgs) @@ -363,6 +362,19 @@ 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 } diff --git a/drivers/vmwarefusion/fusion.go b/drivers/vmwarefusion/fusion.go index 0693bf8f89..5572d32e7c 100644 --- a/drivers/vmwarefusion/fusion.go +++ b/drivers/vmwarefusion/fusion.go @@ -20,7 +20,6 @@ import ( log "github.com/Sirupsen/logrus" "github.com/codegangsta/cli" - "github.com/docker/docker/utils" "github.com/docker/machine/drivers" "github.com/docker/machine/ssh" "github.com/docker/machine/state" @@ -33,7 +32,7 @@ const ( // Driver for VMware Fusion type Driver struct { - Name string + MachineName string Memory int DiskSize int ISO string @@ -43,7 +42,6 @@ type Driver struct { } type CreateFlags struct { - Name *string Boot2DockerURL *string Memory *int DiskSize *int @@ -80,8 +78,8 @@ func GetCreateFlags() []cli.Flag { } } -func NewDriver(storePath string) (drivers.Driver, error) { - return &Driver{storePath: storePath}, nil +func NewDriver(machineName string, storePath string) (drivers.Driver, error) { + return &Driver{MachineName: machineName, storePath: storePath}, nil } func (d *Driver) DriverName() string { @@ -92,8 +90,6 @@ func (d *Driver) SetConfigFromFlags(flags drivers.DriverOptions) error { d.Memory = flags.Int("vmwarefusion-memory-size") d.DiskSize = flags.Int("vmwarefusion-disk-size") d.Boot2DockerURL = flags.String("vmwarefusion-boot2docker-url") - // Autogenerate VM Name - d.Name = generateVMName() d.ISO = path.Join(d.storePath, "boot2docker.iso") return nil @@ -164,7 +160,7 @@ func (d *Driver) Create() error { vmxt.Execute(vmxfile, d) // Generate vmdk file - diskImg := filepath.Join(d.storePath, fmt.Sprintf("%s.vmdk", d.Name)) + diskImg := filepath.Join(d.storePath, fmt.Sprintf("%s.vmdk", d.MachineName)) if _, err := os.Stat(diskImg); err != nil { if !os.IsNotExist(err) { return err @@ -212,7 +208,21 @@ func (d *Driver) Create() error { return err } - cmd, err := d.GetSSHCommand("sudo /etc/init.d/docker restart; sleep 5") + 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 + } + + cmd, err = d.GetSSHCommand("sudo /etc/init.d/docker restart; sleep 5") if err != nil { return err } @@ -270,11 +280,11 @@ func (d *Driver) GetSSHCommand(args ...string) (*exec.Cmd, error) { } func (d *Driver) vmxPath() string { - return path.Join(d.storePath, fmt.Sprintf("%s.vmx", d.Name)) + return path.Join(d.storePath, fmt.Sprintf("%s.vmx", d.MachineName)) } func (d *Driver) vmdkPath() string { - return path.Join(d.storePath, fmt.Sprintf("%s.vmdk", d.Name)) + return path.Join(d.storePath, fmt.Sprintf("%s.vmdk", d.MachineName)) } // Download boot2docker ISO image for the given tag and save it at dest. @@ -304,13 +314,7 @@ func downloadISO(dir, file, url string) error { return nil } -func generateVMName() string { - randomID := utils.TruncateID(utils.GenerateRandomID()) - return fmt.Sprintf("docker-host-%s", randomID) -} - func (d *Driver) getIPfromDHCPLease() (string, error) { - var vmxfh *os.File var dhcpfh *os.File var vmxcontent []byte diff --git a/drivers/vmwarefusion/vmx.go b/drivers/vmwarefusion/vmx.go index f57ee988d7..3f46f633e4 100644 --- a/drivers/vmwarefusion/vmx.go +++ b/drivers/vmwarefusion/vmx.go @@ -7,7 +7,7 @@ package vmwarefusion const vmx = ` .encoding = "UTF-8" config.version = "8" -displayName = "{{.Name}}" +displayName = "{{.MachineName}}" ethernet0.addressType = "generated" ethernet0.connectionType = "nat" ethernet0.linkStatePropagation.enable = "TRUE" @@ -28,7 +28,7 @@ powerType.reset = "hard" powerType.suspend = "hard" scsi0.present = "TRUE" scsi0.virtualDev = "lsilogic" -scsi0:0.fileName = "{{.Name}}.vmdk" +scsi0:0.fileName = "{{.MachineName}}.vmdk" scsi0:0.present = "TRUE" virtualHW.productCompatibility = "hosted" virtualHW.version = "10" diff --git a/drivers/vmwarevcloudair/vcloudair.go b/drivers/vmwarevcloudair/vcloudair.go index d6351aa05d..07e47d9b2b 100644 --- a/drivers/vmwarevcloudair/vcloudair.go +++ b/drivers/vmwarevcloudair/vcloudair.go @@ -33,7 +33,7 @@ type Driver struct { PublicIP string Catalog string CatalogItem string - Name string + MachineName string SSHPort int DockerPort int Provision bool @@ -120,11 +120,6 @@ func GetCreateFlags() []cli.Flag { Usage: "vCloud Air Catalog Item (default is Ubuntu Precise)", Value: "Ubuntu Server 12.04 LTS (amd64 20140927)", }, - cli.StringFlag{ - EnvVar: "VCLOUDAIR_NAME", - Name: "vmwarevcloudair-name", - Usage: "vCloud Air vApp Name (default is autogenerated)", - }, // BoolTFlag is true by default. cli.BoolTFlag{ @@ -160,8 +155,8 @@ func GetCreateFlags() []cli.Flag { } } -func NewDriver(storePath string) (drivers.Driver, error) { - driver := &Driver{storePath: storePath} +func NewDriver(machineName string, storePath string) (drivers.Driver, error) { + driver := &Driver{MachineName: machineName, storePath: storePath} return driver, nil } @@ -206,13 +201,6 @@ func (driver *Driver) SetConfigFromFlags(flags drivers.DriverOptions) error { driver.Catalog = flags.String("vmwarevcloudair-catalog") driver.CatalogItem = flags.String("vmwarevcloudair-catalogitem") - // If no name is provided, autogenerate a name with a random id. - if flags.String("vmwarevcloudair-name") == "" { - driver.Name = generateVMName() - } else { - driver.Name = flags.String("vmwarevcloudair-name") - } - driver.DockerPort = flags.Int("vmwarevcloudair-docker-port") driver.SSHPort = flags.Int("vmwarevcloudair-ssh-port") driver.Provision = flags.Bool("vmwarevcloudair-provision") @@ -326,9 +314,9 @@ func (d *Driver) Create() error { // Create a new empty vApp vapp := govcloudair.NewVApp(p) - log.Infof("Creating a new vApp: %s...", d.Name) + log.Infof("Creating a new vApp: %s...", d.MachineName) // Compose the vApp with ComposeVApp - task, err := vapp.ComposeVApp(net, vapptemplate, d.Name, "Container Host created with Docker Host") + task, err := vapp.ComposeVApp(net, vapptemplate, d.MachineName, "Container Host created with Docker Host") if err != nil { return err } @@ -358,7 +346,7 @@ func (d *Driver) Create() error { sshCustomScript := "echo \"" + strings.TrimSpace(key) + "\" > /root/.ssh/authorized_keys" - task, err = vapp.RunCustomizationScript(d.Name, sshCustomScript) + task, err = vapp.RunCustomizationScript(d.MachineName, sshCustomScript) if err != nil { return err } @@ -379,7 +367,7 @@ func (d *Driver) Create() error { } log.Infof("Creating NAT and Firewall Rules on %s...", d.EdgeGateway) - task, err = edge.Create1to1Mapping(vapp.VApp.Children.VM[0].NetworkConnectionSection.NetworkConnection.IPAddress, d.PublicIP, d.Name) + task, err = edge.Create1to1Mapping(vapp.VApp.Children.VM[0].NetworkConnectionSection.NetworkConnection.IPAddress, d.PublicIP, d.MachineName) if err != nil { return err } @@ -394,11 +382,24 @@ 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 + } + 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 = d.GetSSHCommand(connTest) if err != nil { return err } @@ -524,7 +525,7 @@ func (d *Driver) Remove() error { if status == "POWERED_ON" { // If it's powered on, power it off before deleting - log.Infof("Powering Off %s...", d.Name) + log.Infof("Powering Off %s...", d.MachineName) task, err = vapp.PowerOff() if err != nil { return err @@ -535,7 +536,7 @@ func (d *Driver) Remove() error { } - log.Debugf("Undeploying %s...", d.Name) + log.Debugf("Undeploying %s...", d.MachineName) task, err = vapp.Undeploy() if err != nil { return err @@ -544,7 +545,7 @@ func (d *Driver) Remove() error { return err } - log.Infof("Deleting %s...", d.Name) + log.Infof("Deleting %s...", d.MachineName) task, err = vapp.Delete() if err != nil { return err @@ -586,7 +587,7 @@ func (d *Driver) Start() error { } if status == "POWERED_OFF" { - log.Infof("Starting %s...", d.Name) + log.Infof("Starting %s...", d.MachineName) task, err := vapp.PowerOn() if err != nil { return err @@ -630,7 +631,7 @@ func (d *Driver) Stop() error { } if status == "POWERED_ON" { - log.Infof("Shutting down %s...", d.Name) + log.Infof("Shutting down %s...", d.MachineName) task, err := vapp.Shutdown() if err != nil { return err @@ -675,7 +676,7 @@ func (d *Driver) Restart() error { if status == "POWERED_ON" { // If it's powered on, restart the machine - log.Infof("Restarting %s...", d.Name) + log.Infof("Restarting %s...", d.MachineName) task, err := vapp.Reset() if err != nil { return err @@ -686,7 +687,7 @@ func (d *Driver) Restart() error { } else { // If it's not powered on, start it. - log.Infof("Docker host %s is powered off, powering it back on...", d.Name) + log.Infof("Docker host %s is powered off, powering it back on...", d.MachineName) task, err := vapp.PowerOn() if err != nil { return err @@ -730,7 +731,7 @@ func (d *Driver) Kill() error { } if status == "POWERED_ON" { - log.Infof("Stopping %s...", d.Name) + log.Infof("Stopping %s...", d.MachineName) task, err := vapp.PowerOff() if err != nil { return err diff --git a/drivers/vmwarevsphere/vsphere.go b/drivers/vmwarevsphere/vsphere.go index 851807c3e7..4cd69e6297 100644 --- a/drivers/vmwarevsphere/vsphere.go +++ b/drivers/vmwarevsphere/vsphere.go @@ -18,7 +18,6 @@ import ( log "github.com/Sirupsen/logrus" "github.com/codegangsta/cli" - "github.com/docker/docker/utils" "github.com/docker/machine/drivers" "github.com/docker/machine/drivers/vmwarevsphere/errors" "github.com/docker/machine/ssh" @@ -144,8 +143,8 @@ func GetCreateFlags() []cli.Flag { } } -func NewDriver(storePath string) (drivers.Driver, error) { - return &Driver{StorePath: storePath}, nil +func NewDriver(machineName string, storePath string) (drivers.Driver, error) { + return &Driver{MachineName: machineName, StorePath: storePath}, nil } func (d *Driver) DriverName() string { @@ -153,7 +152,6 @@ func (d *Driver) DriverName() string { } func (d *Driver) SetConfigFromFlags(flags drivers.DriverOptions) error { - d.setMachineNameIfNotSet() d.SSHPort = 22 d.CPU = flags.Int("vmwarevsphere-cpu-count") d.Memory = flags.Int("vmwarevsphere-memory-size") @@ -216,8 +214,6 @@ func (d *Driver) GetState() (state.State, error) { // 3. create a virtual machine with the boot2docker ISO mounted; // 4. reconfigure the virtual machine network and disk size; func (d *Driver) Create() error { - d.setMachineNameIfNotSet() - if err := d.checkVsphereConfig(); err != nil { return err } @@ -268,6 +264,20 @@ 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 + } + if err := d.Start(); err != nil { return err } @@ -381,12 +391,6 @@ func (d *Driver) GetSSHCommand(args ...string) (*exec.Cmd, error) { return ssh.GetSSHCommand(ip, d.SSHPort, "docker", d.sshKeyPath(), args...), nil } -func (d *Driver) setMachineNameIfNotSet() { - if d.MachineName == "" { - d.MachineName = generateVMName() - } -} - func (d *Driver) sshKeyPath() string { return filepath.Join(d.StorePath, "id_docker_host_vsphere") } @@ -443,8 +447,3 @@ func downloadISO(dir, file, url string) error { } return nil } - -func generateVMName() string { - randomID := utils.TruncateID(utils.GenerateRandomID()) - return fmt.Sprintf("docker-host-%s", randomID) -} diff --git a/host.go b/host.go index 58e534132d..ab9b4b536a 100644 --- a/host.go +++ b/host.go @@ -34,7 +34,7 @@ type hostConfig struct { } func NewHost(name, driverName, storePath string) (*Host, error) { - driver, err := drivers.NewDriver(driverName, storePath) + driver, err := drivers.NewDriver(driverName, name, storePath) if err != nil { return nil, err } @@ -197,7 +197,7 @@ func (h *Host) addHostToKnownHosts() error { return nil } -func (h *Host) Create() error { +func (h *Host) Create(name string) error { if err := h.Driver.Create(); err != nil { return err } @@ -261,7 +261,7 @@ func (h *Host) LoadConfig() error { return err } - driver, err := drivers.NewDriver(config.DriverName, h.storePath) + driver, err := drivers.NewDriver(config.DriverName, h.Name, h.storePath) if err != nil { return err } diff --git a/store.go b/store.go index 2e8f8b89ce..1fbcd20407 100644 --- a/store.go +++ b/store.go @@ -52,9 +52,10 @@ func (s *Store) Create(name string, driverName string, flags drivers.DriverOptio return host, err } - if err := host.Create(); err != nil { + if err := host.Create(name); err != nil { return host, err } + return host, nil }