func (driver *Driver) addPublicKeyToAuthorizedHosts(authorizedKeysPath string, retries int) error { if err := drivers.AddPublicKeyToAuthorizedHosts(driver, authorizedKeysPath); err != nil { if err.Error() == "exit status 255" { if retries == 0 { return err } return driver.addPublicKeyToAuthorizedHosts(authorizedKeysPath, retries-1) } return err } return nil }
// updateDocker updates the docker daemon to the latest version. func (c *ComputeUtil) updateDocker(d *Driver) error { log.Infof("Updating docker.") ip, err := d.GetIP() if err != nil { return fmt.Errorf("error retrieving ip: %v", err) } if c.executeCommands([]string{dockerStopCommand}, ip, d.sshKeyPath); err != nil { return err } var scriptBuf bytes.Buffer if err := dockerUpgradeScriptTemplate.Execute(&scriptBuf, d); err != nil { return fmt.Errorf("error expanding upgrade script template: %v", err) } commands := strings.Split(scriptBuf.String(), "\n") if err := c.executeCommands(commands, ip, d.sshKeyPath); err != nil { return err } if err := drivers.AddPublicKeyToAuthorizedHosts(d, "/.docker/authorized-keys.d"); err != nil { return err } return c.executeCommands([]string{dockerStartCommand}, ip, d.sshKeyPath) }
func (d *Driver) Create() error { var ( err error isoURL string ) // Check that VBoxManage exists and works if err = vbm(); err != nil { return err } d.SSHPort, err = getAvailableTCPPort() if err != nil { return err } d.setMachineNameIfNotSet() if d.Boot2DockerURL != "" { isoURL = d.Boot2DockerURL log.Infof("Downloading boot2docker.iso from %s...", isoURL) if err := downloadISO(d.storePath, "boot2docker.iso", isoURL); err != nil { return err } } else { // HACK: Docker 1.4.1 boot2docker image with client/daemon auth isoURL = "https://ejhazlett.s3.amazonaws.com/public/boot2docker/machine-b2d-docker-1.4.1-identity.iso" // todo: check latest release URL, download if it's new // until then always use "latest" // isoURL, err = getLatestReleaseURL() // if err != nil { // return err // } // todo: use real constant for .docker rootPath := filepath.Join(drivers.GetHomeDir(), ".docker") imgPath := filepath.Join(rootPath, "images") commonIsoPath := filepath.Join(imgPath, "boot2docker.iso") if _, err := os.Stat(commonIsoPath); os.IsNotExist(err) { log.Infof("Downloading boot2docker.iso to %s...", commonIsoPath) // just in case boot2docker.iso has been manually deleted if _, err := os.Stat(imgPath); os.IsNotExist(err) { if err := os.Mkdir(imgPath, 0700); err != nil { return err } } if err := downloadISO(imgPath, "boot2docker.iso", isoURL); err != nil { return err } } isoDest := filepath.Join(d.storePath, "boot2docker.iso") if err := cpIso(commonIsoPath, isoDest); err != nil { return err } } log.Infof("Creating SSH key...") if err := ssh.GenerateSSHKey(d.sshKeyPath()); err != nil { return err } log.Infof("Creating VirtualBox VM...") if err := d.generateDiskImage(d.DiskSize); err != nil { return err } if err := vbm("createvm", "--name", d.MachineName, "--register"); err != nil { return err } cpus := uint(runtime.NumCPU()) if cpus > 32 { cpus = 32 } if err := vbm("modifyvm", d.MachineName, "--firmware", "bios", "--bioslogofadein", "off", "--bioslogofadeout", "off", "--natdnshostresolver1", "on", "--bioslogodisplaytime", "0", "--biosbootmenu", "disabled", "--ostype", "Linux26_64", "--cpus", fmt.Sprintf("%d", cpus), "--memory", fmt.Sprintf("%d", d.Memory), "--acpi", "on", "--ioapic", "on", "--rtcuseutc", "on", "--cpuhotplug", "off", "--pae", "on", "--synthcpu", "off", "--hpet", "on", "--hwvirtex", "on", "--nestedpaging", "on", "--largepages", "on", "--vtxvpid", "on", "--accelerate3d", "off", "--boot1", "dvd"); err != nil { return err } if err := vbm("modifyvm", d.MachineName, "--nic1", "nat", "--nictype1", "virtio", "--cableconnected1", "on"); err != nil { return err } if err := vbm("modifyvm", d.MachineName, "--natpf1", fmt.Sprintf("ssh,tcp,127.0.0.1,%d,,22", d.SSHPort)); err != nil { return err } hostOnlyNetwork, err := getOrCreateHostOnlyNetwork( net.ParseIP("192.168.99.1"), net.IPv4Mask(255, 255, 255, 0), net.ParseIP("192.168.99.2"), net.ParseIP("192.168.99.100"), net.ParseIP("192.168.99.254")) if err != nil { return err } if err := vbm("modifyvm", d.MachineName, "--nic2", "hostonly", "--nictype2", "virtio", "--hostonlyadapter2", hostOnlyNetwork.Name, "--cableconnected2", "on"); err != nil { return err } if err := vbm("storagectl", d.MachineName, "--name", "SATA", "--add", "sata", "--hostiocache", "on"); err != nil { return err } if err := vbm("storageattach", d.MachineName, "--storagectl", "SATA", "--port", "0", "--device", "0", "--type", "dvddrive", "--medium", filepath.Join(d.storePath, "boot2docker.iso")); err != nil { return err } if err := vbm("storageattach", d.MachineName, "--storagectl", "SATA", "--port", "1", "--device", "0", "--type", "hdd", "--medium", d.diskPath()); err != nil { return err } // let VBoxService do nice magic automounting (when it's used) if err := vbm("guestproperty", "set", d.MachineName, "/VirtualBox/GuestAdd/SharedFolders/MountPrefix", "/"); err != nil { return err } if err := vbm("guestproperty", "set", d.MachineName, "/VirtualBox/GuestAdd/SharedFolders/MountDir", "/"); err != nil { return err } var shareName, shareDir string // TODO configurable at some point switch runtime.GOOS { case "darwin": shareName = "Users" shareDir = "/Users" // TODO "linux" and "windows" } if shareDir != "" { if _, err := os.Stat(shareDir); err != nil && !os.IsNotExist(err) { return err } else if !os.IsNotExist(err) { if shareName == "" { // parts of the VBox internal code are buggy with share names that start with "/" shareName = strings.TrimLeft(shareDir, "/") // TODO do some basic Windows -> MSYS path conversion // ie, s!^([a-z]+):[/\\]+!\1/!; s!\\!/!g } // woo, shareDir exists! let's carry on! if err := vbm("sharedfolder", "add", d.MachineName, "--name", shareName, "--hostpath", shareDir, "--automount"); err != nil { return err } // enable symlinks if err := vbm("setextradata", d.MachineName, "VBoxInternal2/SharedFoldersEnableSymlinksCreate/"+shareName, "1"); err != nil { return err } } } log.Infof("Starting VirtualBox VM...") if err := d.Start(); err != nil { return err } log.Debugf("Adding key to authorized-keys.d...") cmd, err := d.GetSSHCommand("sudo mkdir -p /var/lib/boot2docker/.docker && sudo chown -R docker /var/lib/boot2docker/.docker") if err != nil { return err } if err := cmd.Run(); err != nil { return err } if err := drivers.AddPublicKeyToAuthorizedHosts(d, "/var/lib/boot2docker/.docker/authorized-keys.d"); err != nil { return err } // HACK: configure docker to use persisted auth cmd, err = d.GetSSHCommand("echo DOCKER_TLS=no | sudo tee -a /var/lib/boot2docker/profile") if err != nil { return err } if err := cmd.Run(); err != nil { 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 --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) cmd, err = d.GetSSHCommand(sshCmd) if err != nil { return err } if err := cmd.Run(); err != nil { return err } cmd, err = d.GetSSHCommand("sudo /etc/init.d/docker restart") if err != nil { return err } if err := cmd.Run(); err != nil { return err } return nil }
func (d *Driver) Create() error { d.setDropletNameIfNotSet() log.Infof("Creating SSH key...") key, err := d.createSSHKey() if err != nil { return err } d.SSHKeyID = key.ID log.Infof("Creating Digital Ocean droplet...") client := d.getClient() createRequest := &godo.DropletCreateRequest{ Image: d.Image, Name: d.DropletName, Region: d.Region, Size: d.Size, SSHKeys: []interface{}{d.SSHKeyID}, } newDroplet, _, err := client.Droplets.Create(createRequest) if err != nil { return err } d.DropletID = newDroplet.Droplet.ID for { newDroplet, _, err = client.Droplets.Get(d.DropletID) if err != nil { return err } for _, network := range newDroplet.Droplet.Networks.V4 { if network.Type == "public" { d.IPAddress = network.IPAddress } } if d.IPAddress != "" { break } time.Sleep(1 * time.Second) } log.Debugf("Created droplet ID %d, IP address %s", newDroplet.Droplet.ID, d.IPAddress) log.Infof("Waiting for SSH...") if err := ssh.WaitForTCP(fmt.Sprintf("%s:%d", d.IPAddress, 22)); err != nil { return err } log.Debugf("HACK: Downloading version of Docker with identity auth...") cmd, err := d.GetSSHCommand("stop docker") if err != nil { return err } if err := cmd.Run(); err != nil { return err } cmd, err = d.GetSSHCommand("curl -sS https://ehazlett.s3.amazonaws.com/public/docker/linux/docker-1.4.1-136b351e-identity > /usr/bin/docker") if err != nil { return err } if err := cmd.Run(); err != nil { return err } log.Debugf("Updating /etc/default/docker to use identity auth...") cmd, err = d.GetSSHCommand("echo 'export DOCKER_OPTS=\"--auth=identity --host=tcp://0.0.0.0:2376\"' >> /etc/default/docker") if err != nil { return err } if err := cmd.Run(); err != nil { return err } log.Debugf("Adding key to authorized-keys.d...") if err := drivers.AddPublicKeyToAuthorizedHosts(d, "/.docker/authorized-keys.d"); err != nil { return err } cmd, err = d.GetSSHCommand("start docker") if err != nil { return err } if err := cmd.Run(); err != nil { return err } return nil }