func TestStoreRemove(t *testing.T) { if err := clearHosts(); err != nil { t.Fatal(err) } flags := &DriverOptionsMock{ Data: map[string]interface{}{ "url": "unix:///var/run/docker.sock", }, } store := NewStore("") _, err := store.Create("test", "none", flags) if err != nil { t.Fatal(err) } path := filepath.Join(drivers.GetHomeDir(), ".docker", "machines", "test") if _, err := os.Stat(path); os.IsNotExist(err) { t.Fatalf("Host path doesn't exist: %s", path) } err = store.Remove("test", false) if err != nil { t.Fatal(err) } if _, err := os.Stat(path); err == nil { t.Fatalf("Host path still exists after remove: %s", path) } }
func NewStore(rootPath string) *Store { if rootPath == "" { rootPath = filepath.Join(drivers.GetHomeDir(), ".docker", "machines") } return &Store{Path: rootPath} }
func clearHosts() error { return os.RemoveAll(path.Join(drivers.GetHomeDir(), ".docker", "machines")) }
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 }