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 <simon+github@thulbourn.com>
This commit is contained in:
Simon Thulbourn 2015-01-05 16:45:08 +00:00
parent 8a0d468a49
commit 861b16dba9
18 changed files with 237 additions and 145 deletions

View File

@ -40,6 +40,7 @@ type Driver struct {
InstanceId string InstanceId string
InstanceType string InstanceType string
IPAddress string IPAddress string
MachineName string
SecurityGroupId string SecurityGroupId string
ReservationId string ReservationId string
RootSize int64 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() 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 { func (d *Driver) SetConfigFromFlags(flags drivers.DriverOptions) error {
@ -171,7 +172,7 @@ func (d *Driver) Create() error {
group, err := d.createSecurityGroup() group, err := d.createSecurityGroup()
if err != nil { if err != nil {
return err log.Fatalf("Please make sure you don't have a security group named: %s", d.MachineName)
} }
bdm := &amz.BlockDeviceMapping{ bdm := &amz.BlockDeviceMapping{
@ -219,15 +220,39 @@ func (d *Driver) Create() error {
d.InstanceId, d.InstanceId,
d.IPAddress) 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 { if err := ssh.WaitForTCP(fmt.Sprintf("%s:%d", d.IPAddress, 22)); err != nil {
return err 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") 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 { if err != nil {
return err return err
} }
@ -483,7 +508,7 @@ func (d *Driver) createKeyPair() error {
return err return err
} }
keyName := fmt.Sprintf("docker-machine-%s", d.Id) keyName := d.MachineName
log.Debugf("creating key pair: %s", keyName) log.Debugf("creating key pair: %s", keyName)
@ -511,7 +536,7 @@ func (d *Driver) terminate() error {
func (d *Driver) createSecurityGroup() (*amz.SecurityGroup, error) { func (d *Driver) createSecurityGroup() (*amz.SecurityGroup, error) {
log.Debugf("creating security group in %s", d.VpcId) 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) group, err := d.getClient().CreateSecurityGroup(grpName, "Docker Machine", d.VpcId)
if err != nil { if err != nil {
return nil, err return nil, err

View File

@ -274,6 +274,34 @@ func (e *EC2) ImportKeyPair(name, publicKey string) error {
return nil 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) { func (e *EC2) CreateSecurityGroup(name string, description string, vpcId string) (*SecurityGroup, error) {
v := url.Values{} v := url.Values{}
v.Set("Action", "CreateSecurityGroup") v.Set("Action", "CreateSecurityGroup")

View File

@ -0,0 +1,6 @@
package amz
type CreateTagsResponse struct {
RequestId string `xml:"requestId"`
Return bool `xml:"return"`
}

View File

@ -21,6 +21,7 @@ import (
) )
type Driver struct { type Driver struct {
MachineName string
SubscriptionID string SubscriptionID string
SubscriptionCert string SubscriptionCert string
PublishSettingsFilePath string PublishSettingsFilePath string
@ -105,8 +106,8 @@ func GetCreateFlags() []cli.Flag {
} }
} }
func NewDriver(storePath string) (drivers.Driver, error) { func NewDriver(machineName string, storePath string) (drivers.Driver, error) {
driver := &Driver{storePath: storePath} driver := &Driver{MachineName: machineName, storePath: storePath}
return driver, nil return driver, nil
} }
@ -119,7 +120,6 @@ func (driver *Driver) SetConfigFromFlags(flags drivers.DriverOptions) error {
cert := flags.String("azure-subscription-cert") cert := flags.String("azure-subscription-cert")
publishSettings := flags.String("azure-publish-settings-file") publishSettings := flags.String("azure-publish-settings-file")
name := flags.String("azure-name")
image := flags.String("azure-image") image := flags.String("azure-image")
username := flags.String("azure-username") 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") 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 == "" { if image == "" {
driver.Image = "b39f27a8b8c64d52b05eac6a62ebad85__Ubuntu-14_04_1-LTS-amd64-server-20140927-en-us-30GB" driver.Image = "b39f27a8b8c64d52b05eac6a62ebad85__Ubuntu-14_04_1-LTS-amd64-server-20140927-en-us-30GB"
} else { } else {
@ -173,8 +167,11 @@ func (driver *Driver) Create() error {
return err return err
} }
t := time.Now().Format("20060102150405")
name := fmt.Sprintf("%s-%s", driver.MachineName, t)
log.Infof("Creating Azure host...") 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 { if err != nil {
return err return err
} }
@ -192,7 +189,7 @@ func (driver *Driver) Create() error {
return err 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 return err
} }
@ -358,7 +355,7 @@ func (driver *Driver) GetState() (state.State, error) {
return state.Error, err return state.Error, err
} }
dockerVM, err := vmClient.GetVMDeployment(driver.Name, driver.Name) dockerVM, err := vmClient.GetVMDeployment(driver.MachineName, driver.MachineName)
if err != nil { if err != nil {
if strings.Contains(err.Error(), "Code: ResourceNotFound") { if strings.Contains(err.Error(), "Code: ResourceNotFound") {
return state.Error, fmt.Errorf("Azure host was not found. Please check your Azure subscription.") 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 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 { if err != nil {
return err return err
} }
@ -426,9 +423,9 @@ func (driver *Driver) Stop() error {
return nil 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 { if err != nil {
return err return err
} }
@ -440,7 +437,7 @@ func (driver *Driver) Remove() error {
if err != nil { if err != nil {
return err return err
} }
available, _, err := vmClient.CheckHostedServiceNameAvailability(driver.Name) available, _, err := vmClient.CheckHostedServiceNameAvailability(driver.MachineName)
if err != nil { if err != nil {
return err return err
} }
@ -448,9 +445,9 @@ func (driver *Driver) Remove() error {
return nil 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 { if err != nil {
return err return err
} }
@ -471,9 +468,9 @@ func (driver *Driver) Restart() error {
return fmt.Errorf("Host is already stopped, use start command to run it") 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 { if err != nil {
return err return err
} }
@ -502,9 +499,9 @@ func (driver *Driver) Kill() error {
return nil 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 { if err != nil {
return err return err
} }
@ -639,5 +636,5 @@ func (driver *Driver) azureCertPath() string {
} }
func (driver *Driver) getHostname() string { func (driver *Driver) getHostname() string {
return driver.Name + ".cloudapp.net" return driver.MachineName + ".cloudapp.net"
} }

View File

@ -12,7 +12,7 @@ import (
log "github.com/Sirupsen/logrus" log "github.com/Sirupsen/logrus"
"github.com/codegangsta/cli" "github.com/codegangsta/cli"
"github.com/digitalocean/godo" "github.com/digitalocean/godo"
"github.com/docker/docker/utils" // "github.com/docker/docker/utils"
"github.com/docker/machine/drivers" "github.com/docker/machine/drivers"
"github.com/docker/machine/ssh" "github.com/docker/machine/ssh"
"github.com/docker/machine/state" "github.com/docker/machine/state"
@ -21,9 +21,9 @@ import (
type Driver struct { type Driver struct {
AccessToken string AccessToken string
DropletID int DropletID int
DropletName string
Image string Image string
IPAddress string IPAddress string
MachineName string
Region string Region string
SSHKeyID int SSHKeyID int
Size string Size string
@ -67,8 +67,8 @@ func GetCreateFlags() []cli.Flag {
} }
} }
func NewDriver(storePath string) (drivers.Driver, error) { func NewDriver(machineName string, storePath string) (drivers.Driver, error) {
return &Driver{storePath: storePath}, nil return &Driver{MachineName: machineName, storePath: storePath}, nil
} }
func (d *Driver) DriverName() string { func (d *Driver) DriverName() string {
@ -89,8 +89,6 @@ func (d *Driver) SetConfigFromFlags(flags drivers.DriverOptions) error {
} }
func (d *Driver) Create() error { func (d *Driver) Create() error {
d.setDropletNameIfNotSet()
log.Infof("Creating SSH key...") log.Infof("Creating SSH key...")
key, err := d.createSSHKey() key, err := d.createSSHKey()
@ -106,7 +104,7 @@ func (d *Driver) Create() error {
createRequest := &godo.DropletCreateRequest{ createRequest := &godo.DropletCreateRequest{
Image: d.Image, Image: d.Image,
Name: d.DropletName, Name: d.MachineName,
Region: d.Region, Region: d.Region,
Size: d.Size, Size: d.Size,
SSHKeys: []interface{}{d.SSHKeyID}, SSHKeys: []interface{}{d.SSHKeyID},
@ -147,9 +145,24 @@ func (d *Driver) Create() error {
return err 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...") 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 { if err != nil {
return err return err
} }
@ -203,7 +216,7 @@ func (d *Driver) createSSHKey() (*godo.Key, error) {
} }
createRequest := &godo.KeyCreateRequest{ createRequest := &godo.KeyCreateRequest{
Name: d.DropletName, Name: d.MachineName,
PublicKey: string(publicKey), 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 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 { func (d *Driver) getClient() *godo.Client {
t := &oauth.Transport{ t := &oauth.Transport{
Token: &oauth.Token{AccessToken: d.AccessToken}, Token: &oauth.Token{AccessToken: d.AccessToken},

View File

@ -67,7 +67,7 @@ type Driver interface {
// - RegisterCreateFlags: a function that takes the FlagSet for // - RegisterCreateFlags: a function that takes the FlagSet for
// "docker hosts create" and returns an object to pass to SetConfigFromFlags // "docker hosts create" and returns an object to pass to SetConfigFromFlags
type RegisteredDriver struct { type RegisteredDriver struct {
New func(storePath string) (Driver, error) New func(machineName string, storePath string) (Driver, error)
GetCreateFlags func() []cli.Flag GetCreateFlags func() []cli.Flag
} }
@ -92,12 +92,12 @@ func Register(name string, registeredDriver *RegisteredDriver) error {
} }
// NewDriver creates a new driver of type "name" // 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] driver, exists := drivers[name]
if !exists { if !exists {
return nil, fmt.Errorf("hosts: Unknown driver %q", name) 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 // GetCreateFlags runs GetCreateFlags for all of the drivers and

View File

@ -8,7 +8,7 @@ import (
func TestGetCreateFlags(t *testing.T) { func TestGetCreateFlags(t *testing.T) {
Register("foo", &RegisteredDriver{ 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 { GetCreateFlags: func() []cli.Flag {
return []cli.Flag{ return []cli.Flag{
cli.StringFlag{ cli.StringFlag{
@ -33,7 +33,7 @@ func TestGetCreateFlags(t *testing.T) {
}, },
}) })
Register("bar", &RegisteredDriver{ 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 { GetCreateFlags: func() []cli.Flag {
return []cli.Flag{ return []cli.Flag{
cli.StringFlag{ cli.StringFlag{

View File

@ -56,7 +56,7 @@ func newComputeUtil(driver *Driver) (*ComputeUtil, error) {
} }
c := ComputeUtil{ c := ComputeUtil{
zone: driver.Zone, zone: driver.Zone,
instanceName: driver.InstanceName, instanceName: driver.MachineName,
userName: driver.UserName, userName: driver.UserName,
project: driver.Project, project: driver.Project,
service: service, service: service,
@ -207,6 +207,21 @@ func (c *ComputeUtil) createInstance(d *Driver) error {
return err 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) return c.updateDocker(d)
} }

View File

@ -16,7 +16,7 @@ import (
// Driver is a struct compatible with the docker.hosts.drivers.Driver interface. // Driver is a struct compatible with the docker.hosts.drivers.Driver interface.
type Driver struct { type Driver struct {
InstanceName string MachineName string
Zone string Zone string
MachineType string MachineType string
storePath string storePath string
@ -28,11 +28,10 @@ type Driver struct {
// CreateFlags are the command line flags used to create a driver. // CreateFlags are the command line flags used to create a driver.
type CreateFlags struct { type CreateFlags struct {
InstanceName *string Zone *string
Zone *string MachineType *string
MachineType *string UserName *string
UserName *string Project *string
Project *string
} }
func init() { func init() {
@ -64,12 +63,6 @@ func GetCreateFlags() []cli.Flag {
Value: "docker-user", Value: "docker-user",
EnvVar: "GOOGLE_USERNAME", EnvVar: "GOOGLE_USERNAME",
}, },
cli.StringFlag{
Name: "google-instance-name",
Usage: "GCE Instance Name",
Value: "docker-machine",
EnvVar: "GOOGLE_INSTANCE_NAME",
},
cli.StringFlag{ cli.StringFlag{
Name: "google-project", Name: "google-project",
Usage: "GCE Project", Usage: "GCE Project",
@ -79,8 +72,10 @@ func GetCreateFlags() []cli.Flag {
} }
// NewDriver creates a Driver with the specified storePath. // NewDriver creates a Driver with the specified storePath.
func NewDriver(storePath string) (drivers.Driver, error) { func NewDriver(machineName string, storePath string) (drivers.Driver, error) {
return &Driver{storePath: storePath, return &Driver{
MachineName: machineName,
storePath: storePath,
sshKeyPath: path.Join(storePath, "id_rsa"), sshKeyPath: path.Join(storePath, "id_rsa"),
publicSSHKeyPath: path.Join(storePath, "id_rsa.pub"), publicSSHKeyPath: path.Join(storePath, "id_rsa.pub"),
}, nil }, nil
@ -93,7 +88,6 @@ func (driver *Driver) DriverName() string {
// SetConfigFromFlags initializes the driver based on the command line flags. // SetConfigFromFlags initializes the driver based on the command line flags.
func (driver *Driver) SetConfigFromFlags(flags drivers.DriverOptions) error { func (driver *Driver) SetConfigFromFlags(flags drivers.DriverOptions) error {
driver.InstanceName = flags.String("google-instance-name")
driver.Zone = flags.String("google-zone") driver.Zone = flags.String("google-zone")
driver.MachineType = flags.String("google-machine-type") driver.MachineType = flags.String("google-machine-type")
driver.UserName = flags.String("google-username") 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 // Check if the instance already exists. There will be an error if the instance
// doesn't exist, so just check instance for nil. // doesn't exist, so just check instance for nil.
if instance, _ := c.instance(); instance != 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") log.Infof("Generating SSH Key")

View File

@ -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. // 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")) os.Link(*tokenPath, path.Join(tmpDir, "gce_token"))
log.Fatal("hai")
driver = &Driver{ driver = &Driver{
storePath: tmpDir, storePath: tmpDir,
InstanceName: "test-instance", MachineName: "test-instance",
Zone: "us-central1-a", Zone: "us-central1-a",
MachineType: "n1-standard-1", MachineType: "n1-standard-1",
UserName: os.Getenv("USER"), UserName: os.Getenv("USER"),
@ -108,6 +110,7 @@ type operation struct {
DiskExpected bool DiskExpected bool
InstanceExpected bool InstanceExpected bool
State state.State State state.State
Arguments []interface{}
} }
func TestBasicOperations(t *testing.T) { func TestBasicOperations(t *testing.T) {

View File

@ -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 return &Driver{}, nil
} }

View File

@ -71,8 +71,8 @@ func GetCreateFlags() []cli.Flag {
} }
} }
func NewDriver(storePath string) (drivers.Driver, error) { func NewDriver(machineName string, storePath string) (drivers.Driver, error) {
return &Driver{storePath: storePath}, nil return &Driver{MachineName: machineName, storePath: storePath}, nil
} }
func (d *Driver) DriverName() string { func (d *Driver) DriverName() string {
@ -123,7 +123,6 @@ func (d *Driver) Create() error {
if err != nil { if err != nil {
return err return err
} }
d.setMachineNameIfNotSet()
if d.Boot2DockerURL != "" { if d.Boot2DockerURL != "" {
isoURL = d.Boot2DockerURL isoURL = d.Boot2DockerURL
@ -341,9 +340,9 @@ func (d *Driver) Create() error {
return err return err
} }
extraArgs := `EXTRA_ARGS='--auth=identity extraArgs := `EXTRA_ARGS='--auth=identity
--auth-authorized-dir=/var/lib/boot2docker/.docker/authorized-keys.d --auth-authorized-dir=/var/lib/boot2docker/.docker/authorized-keys.d
--auth-known-hosts=/var/lib/boot2docker/.docker/known-hosts.json --auth-known-hosts=/var/lib/boot2docker/.docker/known-hosts.json
--identity=/var/lib/boot2docker/.docker/key.json --identity=/var/lib/boot2docker/.docker/key.json
-H tcp://0.0.0.0:2376'` -H tcp://0.0.0.0:2376'`
sshCmd := fmt.Sprintf("echo \"%s\" | sudo tee -a /var/lib/boot2docker/profile", extraArgs) sshCmd := fmt.Sprintf("echo \"%s\" | sudo tee -a /var/lib/boot2docker/profile", extraArgs)
@ -363,6 +362,19 @@ func (d *Driver) Create() error {
return err 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 return nil
} }

View File

@ -20,7 +20,6 @@ import (
log "github.com/Sirupsen/logrus" log "github.com/Sirupsen/logrus"
"github.com/codegangsta/cli" "github.com/codegangsta/cli"
"github.com/docker/docker/utils"
"github.com/docker/machine/drivers" "github.com/docker/machine/drivers"
"github.com/docker/machine/ssh" "github.com/docker/machine/ssh"
"github.com/docker/machine/state" "github.com/docker/machine/state"
@ -33,7 +32,7 @@ const (
// Driver for VMware Fusion // Driver for VMware Fusion
type Driver struct { type Driver struct {
Name string MachineName string
Memory int Memory int
DiskSize int DiskSize int
ISO string ISO string
@ -43,7 +42,6 @@ type Driver struct {
} }
type CreateFlags struct { type CreateFlags struct {
Name *string
Boot2DockerURL *string Boot2DockerURL *string
Memory *int Memory *int
DiskSize *int DiskSize *int
@ -80,8 +78,8 @@ func GetCreateFlags() []cli.Flag {
} }
} }
func NewDriver(storePath string) (drivers.Driver, error) { func NewDriver(machineName string, storePath string) (drivers.Driver, error) {
return &Driver{storePath: storePath}, nil return &Driver{MachineName: machineName, storePath: storePath}, nil
} }
func (d *Driver) DriverName() string { 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.Memory = flags.Int("vmwarefusion-memory-size")
d.DiskSize = flags.Int("vmwarefusion-disk-size") d.DiskSize = flags.Int("vmwarefusion-disk-size")
d.Boot2DockerURL = flags.String("vmwarefusion-boot2docker-url") d.Boot2DockerURL = flags.String("vmwarefusion-boot2docker-url")
// Autogenerate VM Name
d.Name = generateVMName()
d.ISO = path.Join(d.storePath, "boot2docker.iso") d.ISO = path.Join(d.storePath, "boot2docker.iso")
return nil return nil
@ -164,7 +160,7 @@ func (d *Driver) Create() error {
vmxt.Execute(vmxfile, d) vmxt.Execute(vmxfile, d)
// Generate vmdk file // 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 _, err := os.Stat(diskImg); err != nil {
if !os.IsNotExist(err) { if !os.IsNotExist(err) {
return err return err
@ -212,7 +208,21 @@ func (d *Driver) Create() error {
return err 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 { if err != nil {
return err return err
} }
@ -270,11 +280,11 @@ func (d *Driver) GetSSHCommand(args ...string) (*exec.Cmd, error) {
} }
func (d *Driver) vmxPath() string { 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 { 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. // 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 return nil
} }
func generateVMName() string {
randomID := utils.TruncateID(utils.GenerateRandomID())
return fmt.Sprintf("docker-host-%s", randomID)
}
func (d *Driver) getIPfromDHCPLease() (string, error) { func (d *Driver) getIPfromDHCPLease() (string, error) {
var vmxfh *os.File var vmxfh *os.File
var dhcpfh *os.File var dhcpfh *os.File
var vmxcontent []byte var vmxcontent []byte

View File

@ -7,7 +7,7 @@ package vmwarefusion
const vmx = ` const vmx = `
.encoding = "UTF-8" .encoding = "UTF-8"
config.version = "8" config.version = "8"
displayName = "{{.Name}}" displayName = "{{.MachineName}}"
ethernet0.addressType = "generated" ethernet0.addressType = "generated"
ethernet0.connectionType = "nat" ethernet0.connectionType = "nat"
ethernet0.linkStatePropagation.enable = "TRUE" ethernet0.linkStatePropagation.enable = "TRUE"
@ -28,7 +28,7 @@ powerType.reset = "hard"
powerType.suspend = "hard" powerType.suspend = "hard"
scsi0.present = "TRUE" scsi0.present = "TRUE"
scsi0.virtualDev = "lsilogic" scsi0.virtualDev = "lsilogic"
scsi0:0.fileName = "{{.Name}}.vmdk" scsi0:0.fileName = "{{.MachineName}}.vmdk"
scsi0:0.present = "TRUE" scsi0:0.present = "TRUE"
virtualHW.productCompatibility = "hosted" virtualHW.productCompatibility = "hosted"
virtualHW.version = "10" virtualHW.version = "10"

View File

@ -33,7 +33,7 @@ type Driver struct {
PublicIP string PublicIP string
Catalog string Catalog string
CatalogItem string CatalogItem string
Name string MachineName string
SSHPort int SSHPort int
DockerPort int DockerPort int
Provision bool Provision bool
@ -120,11 +120,6 @@ func GetCreateFlags() []cli.Flag {
Usage: "vCloud Air Catalog Item (default is Ubuntu Precise)", Usage: "vCloud Air Catalog Item (default is Ubuntu Precise)",
Value: "Ubuntu Server 12.04 LTS (amd64 20140927)", 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. // BoolTFlag is true by default.
cli.BoolTFlag{ cli.BoolTFlag{
@ -160,8 +155,8 @@ func GetCreateFlags() []cli.Flag {
} }
} }
func NewDriver(storePath string) (drivers.Driver, error) { func NewDriver(machineName string, storePath string) (drivers.Driver, error) {
driver := &Driver{storePath: storePath} driver := &Driver{MachineName: machineName, storePath: storePath}
return driver, nil return driver, nil
} }
@ -206,13 +201,6 @@ func (driver *Driver) SetConfigFromFlags(flags drivers.DriverOptions) error {
driver.Catalog = flags.String("vmwarevcloudair-catalog") driver.Catalog = flags.String("vmwarevcloudair-catalog")
driver.CatalogItem = flags.String("vmwarevcloudair-catalogitem") 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.DockerPort = flags.Int("vmwarevcloudair-docker-port")
driver.SSHPort = flags.Int("vmwarevcloudair-ssh-port") driver.SSHPort = flags.Int("vmwarevcloudair-ssh-port")
driver.Provision = flags.Bool("vmwarevcloudair-provision") driver.Provision = flags.Bool("vmwarevcloudair-provision")
@ -326,9 +314,9 @@ func (d *Driver) Create() error {
// Create a new empty vApp // Create a new empty vApp
vapp := govcloudair.NewVApp(p) 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 // 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 { if err != nil {
return err return err
} }
@ -358,7 +346,7 @@ func (d *Driver) Create() error {
sshCustomScript := "echo \"" + strings.TrimSpace(key) + "\" > /root/.ssh/authorized_keys" 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 { if err != nil {
return err return err
} }
@ -379,7 +367,7 @@ func (d *Driver) Create() error {
} }
log.Infof("Creating NAT and Firewall Rules on %s...", d.EdgeGateway) 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 { if err != nil {
return err return err
} }
@ -394,11 +382,24 @@ func (d *Driver) Create() error {
return err 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 )" 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...") log.Debugf("Connectivity and DNS sanity test...")
cmd, err = d.GetSSHCommand(connTest)
cmd, err := d.GetSSHCommand(connTest)
if err != nil { if err != nil {
return err return err
} }
@ -524,7 +525,7 @@ func (d *Driver) Remove() error {
if status == "POWERED_ON" { if status == "POWERED_ON" {
// If it's powered on, power it off before deleting // 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() task, err = vapp.PowerOff()
if err != nil { if err != nil {
return err 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() task, err = vapp.Undeploy()
if err != nil { if err != nil {
return err return err
@ -544,7 +545,7 @@ func (d *Driver) Remove() error {
return err return err
} }
log.Infof("Deleting %s...", d.Name) log.Infof("Deleting %s...", d.MachineName)
task, err = vapp.Delete() task, err = vapp.Delete()
if err != nil { if err != nil {
return err return err
@ -586,7 +587,7 @@ func (d *Driver) Start() error {
} }
if status == "POWERED_OFF" { if status == "POWERED_OFF" {
log.Infof("Starting %s...", d.Name) log.Infof("Starting %s...", d.MachineName)
task, err := vapp.PowerOn() task, err := vapp.PowerOn()
if err != nil { if err != nil {
return err return err
@ -630,7 +631,7 @@ func (d *Driver) Stop() error {
} }
if status == "POWERED_ON" { if status == "POWERED_ON" {
log.Infof("Shutting down %s...", d.Name) log.Infof("Shutting down %s...", d.MachineName)
task, err := vapp.Shutdown() task, err := vapp.Shutdown()
if err != nil { if err != nil {
return err return err
@ -675,7 +676,7 @@ func (d *Driver) Restart() error {
if status == "POWERED_ON" { if status == "POWERED_ON" {
// If it's powered on, restart the machine // If it's powered on, restart the machine
log.Infof("Restarting %s...", d.Name) log.Infof("Restarting %s...", d.MachineName)
task, err := vapp.Reset() task, err := vapp.Reset()
if err != nil { if err != nil {
return err return err
@ -686,7 +687,7 @@ func (d *Driver) Restart() error {
} else { } else {
// If it's not powered on, start it. // 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() task, err := vapp.PowerOn()
if err != nil { if err != nil {
return err return err
@ -730,7 +731,7 @@ func (d *Driver) Kill() error {
} }
if status == "POWERED_ON" { if status == "POWERED_ON" {
log.Infof("Stopping %s...", d.Name) log.Infof("Stopping %s...", d.MachineName)
task, err := vapp.PowerOff() task, err := vapp.PowerOff()
if err != nil { if err != nil {
return err return err

View File

@ -18,7 +18,6 @@ import (
log "github.com/Sirupsen/logrus" log "github.com/Sirupsen/logrus"
"github.com/codegangsta/cli" "github.com/codegangsta/cli"
"github.com/docker/docker/utils"
"github.com/docker/machine/drivers" "github.com/docker/machine/drivers"
"github.com/docker/machine/drivers/vmwarevsphere/errors" "github.com/docker/machine/drivers/vmwarevsphere/errors"
"github.com/docker/machine/ssh" "github.com/docker/machine/ssh"
@ -144,8 +143,8 @@ func GetCreateFlags() []cli.Flag {
} }
} }
func NewDriver(storePath string) (drivers.Driver, error) { func NewDriver(machineName string, storePath string) (drivers.Driver, error) {
return &Driver{StorePath: storePath}, nil return &Driver{MachineName: machineName, StorePath: storePath}, nil
} }
func (d *Driver) DriverName() string { func (d *Driver) DriverName() string {
@ -153,7 +152,6 @@ func (d *Driver) DriverName() string {
} }
func (d *Driver) SetConfigFromFlags(flags drivers.DriverOptions) error { func (d *Driver) SetConfigFromFlags(flags drivers.DriverOptions) error {
d.setMachineNameIfNotSet()
d.SSHPort = 22 d.SSHPort = 22
d.CPU = flags.Int("vmwarevsphere-cpu-count") d.CPU = flags.Int("vmwarevsphere-cpu-count")
d.Memory = flags.Int("vmwarevsphere-memory-size") 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; // 3. create a virtual machine with the boot2docker ISO mounted;
// 4. reconfigure the virtual machine network and disk size; // 4. reconfigure the virtual machine network and disk size;
func (d *Driver) Create() error { func (d *Driver) Create() error {
d.setMachineNameIfNotSet()
if err := d.checkVsphereConfig(); err != nil { if err := d.checkVsphereConfig(); err != nil {
return err return err
} }
@ -268,6 +264,20 @@ func (d *Driver) Create() error {
return err 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 { if err := d.Start(); err != nil {
return err 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 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 { func (d *Driver) sshKeyPath() string {
return filepath.Join(d.StorePath, "id_docker_host_vsphere") return filepath.Join(d.StorePath, "id_docker_host_vsphere")
} }
@ -443,8 +447,3 @@ func downloadISO(dir, file, url string) error {
} }
return nil return nil
} }
func generateVMName() string {
randomID := utils.TruncateID(utils.GenerateRandomID())
return fmt.Sprintf("docker-host-%s", randomID)
}

View File

@ -34,7 +34,7 @@ type hostConfig struct {
} }
func NewHost(name, driverName, storePath string) (*Host, error) { func NewHost(name, driverName, storePath string) (*Host, error) {
driver, err := drivers.NewDriver(driverName, storePath) driver, err := drivers.NewDriver(driverName, name, storePath)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -197,7 +197,7 @@ func (h *Host) addHostToKnownHosts() error {
return nil return nil
} }
func (h *Host) Create() error { func (h *Host) Create(name string) error {
if err := h.Driver.Create(); err != nil { if err := h.Driver.Create(); err != nil {
return err return err
} }
@ -261,7 +261,7 @@ func (h *Host) LoadConfig() error {
return err return err
} }
driver, err := drivers.NewDriver(config.DriverName, h.storePath) driver, err := drivers.NewDriver(config.DriverName, h.Name, h.storePath)
if err != nil { if err != nil {
return err return err
} }

View File

@ -52,9 +52,10 @@ func (s *Store) Create(name string, driverName string, flags drivers.DriverOptio
return host, err return host, err
} }
if err := host.Create(); err != nil { if err := host.Create(name); err != nil {
return host, err return host, err
} }
return host, nil return host, nil
} }