func (provisioner *Boot2DockerProvisioner) upgradeIso() error { log.Info("Stopping machine to do the upgrade...") if err := provisioner.Driver.Stop(); err != nil { return err } if err := utils.WaitFor(drivers.MachineInState(provisioner.Driver, state.Stopped)); err != nil { return err } machineName := provisioner.GetDriver().GetMachineName() log.Infof("Upgrading machine %s...", machineName) isoFilename := "" switch provisioner.GetDriver().DriverName() { case "virtualbox": isoFilename = "boot2docker-virtualbox.iso" case "vmwarefusion", "vmwarevsphere", "vmwareworkstation": isoFilename = "boot2docker-vmware.iso" case "hyper-v": isoFilename = "boot2docker-hyperv.iso" default: return ErrUnknownDriver } b2dutils := utils.NewB2dUtils("", "", isoFilename) // Usually we call this implicitly, but call it here explicitly to get // the latest boot2docker ISO. if err := b2dutils.DownloadLatestBoot2Docker(); err != nil { return err } // Copy the latest version of boot2docker ISO to the machine's directory if err := b2dutils.CopyIsoToMachineDir("", machineName); err != nil { return err } if err := provisioner.Driver.Start(); err != nil { return err } return utils.WaitFor(drivers.MachineInState(provisioner.Driver, state.Running)) }
func (provisioner *Boot2DockerProvisioner) upgradeIso() error { log.Infof("Stopping machine to do the upgrade...") switch provisioner.Driver.DriverName() { case "vmwarefusion", "vmwarevsphere": return errors.New("Upgrade functionality is currently not supported for these providers, as they use a custom ISO.") } if err := provisioner.Driver.Stop(); err != nil { return err } if err := utils.WaitFor(drivers.MachineInState(provisioner.Driver, state.Stopped)); err != nil { return err } machineName := provisioner.GetDriver().GetMachineName() log.Infof("Upgrading machine %s...", machineName) b2dutils := utils.NewB2dUtils("", "") // Usually we call this implicitly, but call it here explicitly to get // the latest boot2docker ISO. if err := b2dutils.DownloadLatestBoot2Docker(); err != nil { return err } // Copy the latest version of boot2docker ISO to the machine's directory if err := b2dutils.CopyIsoToMachineDir("", machineName); err != nil { return err } log.Infof("Starting machine back up...") if err := provisioner.Driver.Start(); err != nil { return err } return utils.WaitFor(drivers.MachineInState(provisioner.Driver, state.Running)) }
func (provisioner *RancherProvisioner) upgradeIso() error { // Largely copied from Boot2Docker provisioner, we should find a way to share this code log.Info("Stopping machine to do the upgrade...") if err := provisioner.Driver.Stop(); err != nil { return err } if err := utils.WaitFor(drivers.MachineInState(provisioner.Driver, state.Stopped)); err != nil { return err } machineName := provisioner.GetDriver().GetMachineName() log.Infof("Upgrading machine %s...", machineName) b2dutils := utils.NewB2dUtils("", "", isoFilename) url, err := provisioner.getLatestISOURL() if err != nil { return err } if err := b2dutils.DownloadISOFromURL(url); err != nil { return err } // Copy the latest version of boot2docker ISO to the machine's directory if err := b2dutils.CopyIsoToMachineDir("", machineName); err != nil { return err } log.Infof("Starting machine back up...") if err := provisioner.Driver.Start(); err != nil { return err } return utils.WaitFor(drivers.MachineInState(provisioner.Driver, state.Running)) }
func (provisioner *Boot2DockerProvisioner) upgradeIso() error { log.Info("Stopping machine to do the upgrade...") if err := provisioner.Driver.Stop(); err != nil { return err } if err := utils.WaitFor(drivers.MachineInState(provisioner.Driver, state.Stopped)); err != nil { return err } machineName := provisioner.GetDriver().GetMachineName() log.Infof("Upgrading machine %s...", machineName) b2dutils := utils.NewB2dUtils("", "") // Usually we call this implicitly, but call it here explicitly to get // the latest boot2docker ISO. if err := b2dutils.DownloadLatestBoot2Docker(); err != nil { return err } // Copy the latest version of boot2docker ISO to the machine's directory if err := b2dutils.CopyIsoToMachineDir("", machineName); err != nil { return err } log.Infof("Starting machine back up...") if err := provisioner.Driver.Start(); err != nil { return err } return utils.WaitFor(drivers.MachineInState(provisioner.Driver, state.Running)) }
func (d *Driver) Create() error { b2dutils := utils.NewB2dUtils("", "") if err := b2dutils.CopyIsoToMachineDir(d.Boot2DockerURL, d.MachineName); err != nil { return err } log.Infof("Creating SSH key...") if err := ssh.GenerateSSHKey(d.GetSSHKeyPath()); err != nil { return err } log.Infof("Creating VM...") if err := os.MkdirAll(d.ResolveStorePath("."), 0755); err != nil { return err } if _, err := os.Stat(d.vmxPath()); err == nil { return ErrMachineExist } // Generate vmx config file from template vmxt := template.Must(template.New("vmx").Parse(vmx)) vmxfile, err := os.Create(d.vmxPath()) if err != nil { return err } vmxt.Execute(vmxfile, d) // Generate vmdk file diskImg := d.ResolveStorePath(fmt.Sprintf("%s.vmdk", d.MachineName)) if _, err := os.Stat(diskImg); err != nil { if !os.IsNotExist(err) { return err } if err := vdiskmanager(diskImg, d.DiskSize); err != nil { return err } } log.Infof("Starting %s...", d.MachineName) vmrun("start", d.vmxPath(), "nogui") var ip string log.Infof("Waiting for VM to come online...") for i := 1; i <= 60; i++ { ip, err = d.getIPfromDHCPLease() if err != nil { log.Debugf("Not there yet %d/%d, error: %s", i, 60, err) time.Sleep(2 * time.Second) continue } if ip != "" { log.Debugf("Got an ip: %s", ip) break } } if ip == "" { return fmt.Errorf("Machine didn't return an IP after 120 seconds, aborting") } // we got an IP, let's copy ssh keys over d.IPAddress = ip // Generate a tar keys bundle if err := d.generateKeyBundle(); err != nil { return err } // Test if /var/lib/boot2docker exists vmrun("-gu", B2DUser, "-gp", B2DPass, "directoryExistsInGuest", d.vmxPath(), "/var/lib/boot2docker") // Copy SSH keys bundle vmrun("-gu", B2DUser, "-gp", B2DPass, "CopyFileFromHostToGuest", d.vmxPath(), d.ResolveStorePath("userdata.tar"), "/home/docker/userdata.tar") // Expand tar file. vmrun("-gu", B2DUser, "-gp", B2DPass, "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") // Enable Shared Folders vmrun("-gu", B2DUser, "-gp", B2DPass, "enableSharedFolders", d.vmxPath()) 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) { // add shared folder, create mountpoint and mount it. vmrun("-gu", B2DUser, "-gp", B2DPass, "addSharedFolder", d.vmxPath(), shareName, shareDir) vmrun("-gu", B2DUser, "-gp", B2DPass, "runScriptInGuest", d.vmxPath(), "/bin/sh", "sudo mkdir "+shareDir+" && sudo mount -t vmhgfs .host:/"+shareName+" "+shareDir) } } return nil }
func (d *Driver) Create() error { var ( err error ) // Check that VBoxManage exists and works if err = vbm(); err != nil { return err } b2dutils := utils.NewB2dUtils("", "") if err := b2dutils.CopyIsoToMachineDir(d.Boot2DockerURL, d.MachineName); err != nil { return err } log.Infof("Creating VirtualBox VM...") // import b2d VM if requested if d.Boot2DockerImportVM != "" { name := d.Boot2DockerImportVM // make sure vm is stopped _ = vbm("controlvm", name, "poweroff") diskInfo, err := getVMDiskInfo(name) if err != nil { return err } if _, err := os.Stat(diskInfo.Path); err != nil { return err } if err := vbm("clonehd", diskInfo.Path, d.diskPath()); err != nil { return err } log.Debugf("Importing VM settings...") vmInfo, err := getVMInfo(name) if err != nil { return err } d.CPU = vmInfo.CPUs d.Memory = vmInfo.Memory log.Debugf("Importing SSH key...") keyPath := filepath.Join(utils.GetHomeDir(), ".ssh", "id_boot2docker") if err := utils.CopyFile(keyPath, d.GetSSHKeyPath()); err != nil { return err } } else { log.Infof("Creating SSH key...") if err := ssh.GenerateSSHKey(d.GetSSHKeyPath()); err != nil { return err } log.Debugf("Creating disk image...") if err := d.generateDiskImage(d.DiskSize); err != nil { return err } } if err := vbm("createvm", "--basefolder", d.ResolveStorePath("."), "--name", d.MachineName, "--register"); err != nil { return err } log.Debugf("VM CPUS: %d", d.CPU) log.Debugf("VM Memory: %d", d.Memory) cpus := d.CPU if cpus < 1 { cpus = int(runtime.NumCPU()) } if cpus > 32 { cpus = 32 } if err := vbm("modifyvm", d.MachineName, "--firmware", "bios", "--bioslogofadein", "off", "--bioslogofadeout", "off", "--bioslogodisplaytime", "0", "--biosbootmenu", "disabled", "--ostype", "Linux26_64", "--cpus", fmt.Sprintf("%d", cpus), "--memory", fmt.Sprintf("%d", d.Memory), "--acpi", "on", "--ioapic", "on", "--rtcuseutc", "on", "--natdnshostresolver1", "off", "--natdnsproxy1", "off", "--cpuhotplug", "off", "--pae", "on", "--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", "82540EM", "--cableconnected1", "on"); err != nil { return err } if err := d.setupHostOnlyNetwork(d.MachineName); 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", d.ResolveStorePath("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 "windows": shareName = "c/Users" shareDir = "c:\\Users" case "darwin": shareName = "Users" shareDir = "/Users" // TODO "linux" } if shareDir != "" && !d.NoShare { log.Debugf("setting up 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 } return nil }
func (d *Driver) Create() error { b2dutils := utils.NewB2dUtils("", "", isoFilename) if err := b2dutils.CopyIsoToMachineDir(d.Boot2DockerURL, d.MachineName); err != nil { return err } log.Infof("Creating SSH key...") if err := ssh.GenerateSSHKey(d.GetSSHKeyPath()); err != nil { return err } log.Infof("Creating VM...") if err := os.MkdirAll(d.ResolveStorePath("."), 0755); err != nil { return err } if _, err := os.Stat(d.vmxPath()); err == nil { return ErrMachineExist } // Generate vmx config file from template vmxt := template.Must(template.New("vmx").Parse(vmx)) vmxfile, err := os.Create(d.vmxPath()) if err != nil { return err } vmxt.Execute(vmxfile, d) // Generate vmdk file diskImg := d.ResolveStorePath(fmt.Sprintf("%s.vmdk", d.MachineName)) if _, err := os.Stat(diskImg); err != nil { if !os.IsNotExist(err) { return err } if err := vdiskmanager(diskImg, d.DiskSize); err != nil { return err } } log.Infof("Starting %s...", d.MachineName) vmrun("start", d.vmxPath(), "nogui") var ip string log.Infof("Waiting for VM to come online...") for i := 1; i <= 60; i++ { ip, err = d.GetIP() if err != nil { log.Debugf("Not there yet %d/%d, error: %s", i, 60, err) time.Sleep(2 * time.Second) continue } if ip != "" { log.Debugf("Got an ip: %s", ip) break } } if ip == "" { return fmt.Errorf("Machine didn't return an IP after 120 seconds, aborting") } // we got an IP, let's copy ssh keys over d.IPAddress = ip // use ssh to set keys sshClient, err := d.getLocalSSHClient() if err != nil { return err } // add pub key for user pubKey, err := ioutil.ReadFile(d.publicSSHKeyPath()) if err != nil { return err } if out, err := sshClient.Output(fmt.Sprintf( "mkdir -p /home/%s/.ssh", d.GetSSHUsername(), )); err != nil { log.Error(out) return err } if out, err := sshClient.Output(fmt.Sprintf( "printf '%%s' '%s' | tee /home/%s/.ssh/authorized_keys", string(pubKey), d.GetSSHUsername(), )); err != nil { log.Error(out) return err } // Enable Shared Folders vmrun("-gu", B2DUser, "-gp", B2DPass, "enableSharedFolders", d.vmxPath()) if err := d.setupSharedDirs(); err != nil { return err } return nil }
func (d *Driver) Create() error { var ( isoURL string err error ) b2dutils := utils.NewB2dUtils("", "") imgPath := utils.GetMachineCacheDir() commonIsoPath := filepath.Join(imgPath, isoFilename) // 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 d.Boot2DockerURL != "" { isoURL = d.Boot2DockerURL log.Infof("Downloading boot2docker.iso from %s...", isoURL) if err := b2dutils.DownloadISO(d.storePath, isoFilename, isoURL); err != nil { return err } } else { // TODO: until vmw tools are merged into b2d master // we will use the iso from the vmware team. //// todo: check latest release URL, download if it's new //// until then always use "latest" //isoURL, err = b2dutils.GetLatestBoot2DockerReleaseURL() //if err != nil { // log.Warnf("Unable to check for the latest release: %s", err) //} // see https://github.com/boot2docker/boot2docker/pull/747 isoURL := "https://github.com/cloudnativeapps/boot2docker/releases/download/1.5.0-GH747/boot2docker-1.5.0-GH747.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 := b2dutils.DownloadISO(imgPath, isoFilename, isoURL); err != nil { return err } } isoDest := filepath.Join(d.storePath, isoFilename) if err := utils.CopyFile(commonIsoPath, isoDest); err != nil { return err } } log.Infof("Creating SSH key...") if err := ssh.GenerateSSHKey(d.GetSSHKeyPath()); err != nil { return err } log.Infof("Creating VM...") if err := os.MkdirAll(d.storePath, 0755); err != nil { return err } if _, err := os.Stat(d.vmxPath()); err == nil { return ErrMachineExist } // Generate vmx config file from template vmxt := template.Must(template.New("vmx").Parse(vmx)) vmxfile, err := os.Create(d.vmxPath()) if err != nil { return err } vmxt.Execute(vmxfile, d) // Generate vmdk file diskImg := filepath.Join(d.storePath, fmt.Sprintf("%s.vmdk", d.MachineName)) if _, err := os.Stat(diskImg); err != nil { if !os.IsNotExist(err) { return err } if err := vdiskmanager(diskImg, d.DiskSize); err != nil { return err } } if err := d.Start(); err != nil { return err } var ip string log.Infof("Waiting for VM to come online...") for i := 1; i <= 60; i++ { ip, err = d.getIPfromDHCPLease() if err != nil { log.Debugf("Not there yet %d/%d, error: %s", i, 60, err) time.Sleep(2 * time.Second) continue } if ip != "" { log.Debugf("Got an ip: %s", ip) break } } if ip == "" { return fmt.Errorf("Machine didn't return an IP after 120 seconds, aborting") } // we got an IP, let's copy ssh keys over d.IPAddress = ip // Generate a tar keys bundle if err := d.generateKeyBundle(); err != nil { return err } // Test if /var/lib/boot2docker exists vmrun("-gu", B2D_USER, "-gp", B2D_PASS, "directoryExistsInGuest", d.vmxPath(), "/var/lib/boot2docker") // Copy SSH keys bundle vmrun("-gu", B2D_USER, "-gp", B2D_PASS, "CopyFileFromHostToGuest", d.vmxPath(), path.Join(d.storePath, "userdata.tar"), "/home/docker/userdata.tar") // 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") return nil }
func (d *Driver) Create() error { b2dutils := utils.NewB2dUtils("", "") if err := b2dutils.CopyIsoToMachineDir(d.Boot2DockerURL, d.MachineName); err != nil { return err } // download cloud-init config drive if d.ConfigDriveURL != "" { log.Infof("Downloading %s from %s", isoConfigDrive, d.ConfigDriveURL) if err := b2dutils.DownloadISO(d.ResolveStorePath("."), isoConfigDrive, d.ConfigDriveURL); err != nil { return err } } log.Infof("Creating SSH key...") if err := ssh.GenerateSSHKey(d.GetSSHKeyPath()); err != nil { return err } log.Infof("Creating VM...") if err := os.MkdirAll(d.ResolveStorePath("."), 0755); err != nil { return err } if _, err := os.Stat(d.vmxPath()); err == nil { return ErrMachineExist } // Generate vmx config file from template vmxt := template.Must(template.New("vmx").Parse(vmx)) vmxfile, err := os.Create(d.vmxPath()) if err != nil { return err } vmxt.Execute(vmxfile, d) // Generate vmdk file diskImg := d.ResolveStorePath(fmt.Sprintf("%s.vmdk", d.MachineName)) if _, err := os.Stat(diskImg); err != nil { if !os.IsNotExist(err) { return err } if err := vdiskmanager(diskImg, d.DiskSize); err != nil { return err } } log.Infof("Starting %s...", d.MachineName) vmrun("start", d.vmxPath(), "nogui") var ip string log.Infof("Waiting for VM to come online...") for i := 1; i <= 60; i++ { ip, err = d.getIPfromDHCPLease() if err != nil { log.Debugf("Not there yet %d/%d, error: %s", i, 60, err) time.Sleep(2 * time.Second) continue } if ip != "" { log.Debugf("Got an ip: %s", ip) conn, err := net.DialTimeout("tcp", fmt.Sprintf("%s:%d", ip, 22), time.Duration(2*time.Second)) if err != nil { log.Debugf("SSH Daemon not responding yet: %s", err) time.Sleep(2 * time.Second) continue } conn.Close() break } } if ip == "" { return fmt.Errorf("Machine didn't return an IP after 120 seconds, aborting") } // we got an IP, let's copy ssh keys over d.IPAddress = ip // Do not execute the rest of boot2docker specific configuration // The uplaod of the public ssh key uses a ssh connection, // this works without installed vmware client tools if d.ConfigDriveURL != "" { var keyfh *os.File var keycontent []byte log.Infof("Copy public SSH key to %s [%s]", d.MachineName, d.IPAddress) // create .ssh folder in users home if err := executeSSHCommand(fmt.Sprintf("mkdir -p /home/%s/.ssh", d.SSHUser), d); err != nil { return err } // read generated public ssh key if keyfh, err = os.Open(d.publicSSHKeyPath()); err != nil { return err } defer keyfh.Close() if keycontent, err = ioutil.ReadAll(keyfh); err != nil { return err } // add public ssh key to authorized_keys if err := executeSSHCommand(fmt.Sprintf("echo '%s' > /home/%s/.ssh/authorized_keys", string(keycontent), d.SSHUser), d); err != nil { return err } // make it secure if err := executeSSHCommand(fmt.Sprintf("chmod 600 /home/%s/.ssh/authorized_keys", d.SSHUser), d); err != nil { return err } log.Debugf("Leaving create sequence early, configdrive found") return nil } // Generate a tar keys bundle if err := d.generateKeyBundle(); err != nil { return err } // Test if /var/lib/boot2docker exists vmrun("-gu", B2DUser, "-gp", B2DPass, "directoryExistsInGuest", d.vmxPath(), "/var/lib/boot2docker") // Copy SSH keys bundle vmrun("-gu", B2DUser, "-gp", B2DPass, "CopyFileFromHostToGuest", d.vmxPath(), d.ResolveStorePath("userdata.tar"), "/home/docker/userdata.tar") // Expand tar file. vmrun("-gu", B2DUser, "-gp", B2DPass, "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") // Enable Shared Folders vmrun("-gu", B2DUser, "-gp", B2DPass, "enableSharedFolders", d.vmxPath()) 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) { // add shared folder, create mountpoint and mount it. vmrun("-gu", B2DUser, "-gp", B2DPass, "addSharedFolder", d.vmxPath(), shareName, shareDir) vmrun("-gu", B2DUser, "-gp", B2DPass, "runScriptInGuest", d.vmxPath(), "/bin/sh", "sudo mkdir "+shareDir+" && sudo mount -t vmhgfs .host:/"+shareName+" "+shareDir) } } return nil }
// the current implementation does the following: // 1. check whether the docker directory contains the boot2docker ISO // 2. generate an SSH keypair and bundle it in a tar. // 3. create a virtual machine with the boot2docker ISO mounted; // 4. reconfigure the virtual machine network and disk size; func (d *Driver) Create() error { if err := d.checkVsphereConfig(); err != nil { return err } b2dutils := utils.NewB2dUtils("", "") if err := b2dutils.CopyIsoToMachineDir(d.Boot2DockerURL, d.MachineName); err != nil { return err } log.Infof("Generating SSH Keypair...") if err := ssh.GenerateSSHKey(d.GetSSHKeyPath()); err != nil { return err } vcConn := NewVcConn(d) log.Infof("Uploading Boot2docker ISO ...") if err := vcConn.DatastoreMkdir(d.MachineName); err != nil { return err } if _, err := os.Stat(d.ISO); os.IsNotExist(err) { log.Errorf("Unable to find boot2docker ISO at %s", d.ISO) return errors.NewIncompleteVsphereConfigError(d.ISO) } if err := vcConn.DatastoreUpload(d.ISO, d.MachineName); err != nil { return err } isoPath := fmt.Sprintf("%s/%s", d.MachineName, isoFilename) if err := vcConn.VMCreate(isoPath); err != nil { return err } log.Infof("Configuring the virtual machine %s... ", d.MachineName) if err := vcConn.VMDiskCreate(); err != nil { return err } if err := vcConn.VMAttachNetwork(); err != nil { return err } if err := d.Start(); err != nil { return err } // Generate a tar keys bundle if err := d.generateKeyBundle(); err != nil { return err } // Copy SSH keys bundle if err := vcConn.GuestUpload(B2DUser, B2DPass, path.Join(d.storePath, "userdata.tar"), "/home/docker/userdata.tar"); err != nil { return err } // Expand tar file. if err := vcConn.GuestStart(B2DUser, B2DPass, "/usr/bin/sudo", "/bin/mv /home/docker/userdata.tar /var/lib/boot2docker/userdata.tar && /usr/bin/sudo tar xf /var/lib/boot2docker/userdata.tar -C /home/docker/ > /var/log/userdata.log 2>&1 && /usr/bin/sudo chown -R docker:staff /home/docker"); err != nil { return err } return nil }
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 } b2dutils := utils.NewB2dUtils("", "") imgPath := utils.GetMachineCacheDir() isoFilename := "boot2docker.iso" commonIsoPath := filepath.Join(imgPath, "boot2docker.iso") // 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 d.Boot2DockerURL != "" { isoURL = d.Boot2DockerURL log.Infof("Downloading %s from %s...", isoFilename, isoURL) if err := b2dutils.DownloadISO(commonIsoPath, isoFilename, isoURL); err != nil { return err } } else { // todo: check latest release URL, download if it's new // until then always use "latest" isoURL, err = b2dutils.GetLatestBoot2DockerReleaseURL() if err != nil { log.Warnf("Unable to check for the latest release: %s", err) } if _, err := os.Stat(commonIsoPath); os.IsNotExist(err) { log.Infof("Downloading %s to %s...", isoFilename, commonIsoPath) if err := b2dutils.DownloadISO(imgPath, isoFilename, isoURL); err != nil { return err } } isoDest := filepath.Join(d.storePath, isoFilename) if err := utils.CopyFile(commonIsoPath, isoDest); err != nil { return err } } log.Infof("Creating SSH key...") if err := ssh.GenerateSSHKey(d.GetSSHKeyPath()); err != nil { return err } log.Infof("Creating VirtualBox VM...") if err := d.generateDiskImage(d.DiskSize); err != nil { return err } if err := vbm("createvm", "--basefolder", d.storePath, "--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 } return nil }
func (d *Driver) Create() error { err := hypervAvailable() if err != nil { return err } d.setMachineNameIfNotSet() var isoURL string b2dutils := utils.NewB2dUtils("", "") if d.boot2DockerLoc == "" { if d.boot2DockerURL != "" { isoURL = d.boot2DockerURL log.Infof("Downloading boot2docker.iso from %s...", isoURL) if err := b2dutils.DownloadISO(d.ResolveStorePath("."), "boot2docker.iso", isoURL); err != nil { return err } } else { // todo: check latest release URL, download if it's new // until then always use "latest" isoURL, err = b2dutils.GetLatestBoot2DockerReleaseURL() if err != nil { log.Warnf("Unable to check for the latest release: %s", err) } // todo: use real constant for .docker rootPath := filepath.Join(utils.GetDockerDir()) 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 := b2dutils.DownloadISO(imgPath, "boot2docker.iso", isoURL); err != nil { return err } } isoDest := d.ResolveStorePath("boot2docker.iso") if err := utils.CopyFile(commonIsoPath, isoDest); err != nil { return err } } } else { if err := utils.CopyFile(d.boot2DockerLoc, d.ResolveStorePath("boot2docker.iso")); err != nil { return err } } log.Infof("Creating SSH key...") if err := ssh.GenerateSSHKey(d.GetSSHKeyPath()); err != nil { return err } log.Infof("Creating VM...") virtualSwitch, err := d.chooseVirtualSwitch() if err != nil { return err } err = d.generateDiskImage() if err != nil { return err } command := []string{ "New-VM", "-Name", d.MachineName, "-Path", fmt.Sprintf("'%s'", d.ResolveStorePath(".")), "-MemoryStartupBytes", fmt.Sprintf("%dMB", d.memSize)} _, err = execute(command) if err != nil { return err } command = []string{ "Set-VMDvdDrive", "-VMName", d.MachineName, "-Path", fmt.Sprintf("'%s'", d.ResolveStorePath("boot2docker.iso"))} _, err = execute(command) if err != nil { return err } command = []string{ "Add-VMHardDiskDrive", "-VMName", d.MachineName, "-Path", fmt.Sprintf("'%s'", d.diskImage)} _, err = execute(command) if err != nil { return err } command = []string{ "Connect-VMNetworkAdapter", "-VMName", d.MachineName, "-SwitchName", fmt.Sprintf("'%s'", virtualSwitch)} _, err = execute(command) if err != nil { return err } log.Infof("Starting VM...") if err := d.Start(); err != nil { return err } return nil }
func (d *Driver) Create() error { err := hypervAvailable() if err != nil { return err } d.setMachineNameIfNotSet() b2dutils := utils.NewB2dUtils("", "", isoFilename) if err := b2dutils.CopyIsoToMachineDir(d.boot2DockerURL, d.MachineName); err != nil { return err } log.Infof("Creating SSH key...") if err := ssh.GenerateSSHKey(d.GetSSHKeyPath()); err != nil { return err } log.Infof("Creating VM...") virtualSwitch, err := d.chooseVirtualSwitch() if err != nil { return err } if err := d.generateDiskImage(); err != nil { return err } command := []string{ "New-VM", "-Name", d.MachineName, "-Path", fmt.Sprintf("'%s'", d.ResolveStorePath(".")), "-MemoryStartupBytes", fmt.Sprintf("%dMB", d.memSize)} _, err = execute(command) if err != nil { return err } command = []string{ "Set-VMDvdDrive", "-VMName", d.MachineName, "-Path", fmt.Sprintf("'%s'", d.ResolveStorePath(isoFilename))} if _, err = execute(command); err != nil { return err } command = []string{ "Add-VMHardDiskDrive", "-VMName", d.MachineName, "-Path", fmt.Sprintf("'%s'", d.diskImage)} if _, err = execute(command); err != nil { return err } command = []string{ "Connect-VMNetworkAdapter", "-VMName", d.MachineName, "-SwitchName", fmt.Sprintf("'%s'", virtualSwitch)} if _, err = execute(command); err != nil { return err } log.Infof("Starting VM...") if err := d.Start(); err != nil { return err } // use ssh to set keys sshClient, err := d.getLocalSSHClient() if err != nil { return err } // add pub key for user pubKey, err := ioutil.ReadFile(d.publicSSHKeyPath()) if err != nil { return err } if out, err := sshClient.Output(fmt.Sprintf( "mkdir -p /home/%s/.ssh", d.GetSSHUsername(), )); err != nil { log.Error(out) return err } if out, err := sshClient.Output(fmt.Sprintf( "printf '%%s' '%s' | tee /home/%s/.ssh/authorized_keys", string(pubKey), d.GetSSHUsername(), )); err != nil { log.Error(out) return err } return nil }
// the current implementation does the following: // 1. check whether the docker directory contains the boot2docker ISO // 2. generate an SSH keypair and bundle it in a tar. // 3. create a virtual machine with the boot2docker ISO mounted; // 4. reconfigure the virtual machine network and disk size; func (d *Driver) Create() error { if err := d.checkVsphereConfig(); err != nil { return err } var ( isoURL string ) b2dutils := utils.NewB2dUtils("", "") imgPath := utils.GetMachineCacheDir() commonIsoPath := filepath.Join(imgPath, isoFilename) // 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 d.Boot2DockerURL != "" { isoURL = d.Boot2DockerURL log.Infof("Downloading boot2docker.iso from %s...", isoURL) if err := b2dutils.DownloadISO(commonIsoPath, isoFilename, isoURL); err != nil { return err } } else { // TODO: until vmw tools are merged into b2d master // we will use the iso from the vmware team //// todo: check latest release URL, download if it's new //// until then always use "latest" //isoURL, err = b2dutils.GetLatestBoot2DockerReleaseURL() //if err != nil { // log.Warnf("Unable to check for the latest release: %s", err) //} // see https://github.com/boot2docker/boot2docker/pull/747 isoURL := "https://github.com/cloudnativeapps/boot2docker/releases/download/1.5.0-GH747/boot2docker-1.5.0-GH747.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 := b2dutils.DownloadISO(imgPath, isoFilename, isoURL); err != nil { return err } } isoDest := filepath.Join(d.storePath, isoFilename) if err := utils.CopyFile(commonIsoPath, isoDest); err != nil { return err } } log.Infof("Generating SSH Keypair...") if err := ssh.GenerateSSHKey(d.GetSSHKeyPath()); err != nil { return err } vcConn := NewVcConn(d) log.Infof("Uploading Boot2docker ISO ...") if err := vcConn.DatastoreMkdir(DATASTORE_DIR); err != nil { return err } if _, err := os.Stat(d.ISO); os.IsNotExist(err) { log.Errorf("Unable to find boot2docker ISO at %s", d.ISO) return errors.NewIncompleteVsphereConfigError(d.ISO) } if err := vcConn.DatastoreUpload(d.ISO); err != nil { return err } isoPath := fmt.Sprintf("%s/%s", DATASTORE_DIR, isoFilename) if err := vcConn.VmCreate(isoPath); err != nil { return err } log.Infof("Configuring the virtual machine %s... ", d.MachineName) if err := vcConn.VmDiskCreate(); err != nil { return err } if err := vcConn.VmAttachNetwork(); err != nil { return err } if err := d.Start(); err != nil { return err } // Generate a tar keys bundle if err := d.generateKeyBundle(); err != nil { return err } // Copy SSH keys bundle if err := vcConn.GuestUpload(B2D_USER, B2D_PASS, path.Join(d.storePath, "userdata.tar"), "/home/docker/userdata.tar"); err != nil { return err } // Expand tar file. if err := vcConn.GuestStart(B2D_USER, B2D_PASS, "/usr/bin/sudo", "/bin/mv /home/docker/userdata.tar /var/lib/boot2docker/userdata.tar && /usr/bin/sudo tar xf /var/lib/boot2docker/userdata.tar -C /home/docker/ > /var/log/userdata.log 2>&1 && /usr/bin/sudo chown -R docker:staff /home/docker"); err != nil { return err } return nil }
func (d *Driver) Create() error { var ( err error ) // Check that VBoxManage exists and works if err = vbm(); err != nil { return err } b2dutils := utils.NewB2dUtils("", "", isoFilename) if err := b2dutils.CopyIsoToMachineDir(d.Boot2DockerURL, d.MachineName); err != nil { return err } log.Infof("Creating VirtualBox VM...") // import b2d VM if requested if d.Boot2DockerImportVM != "" { name := d.Boot2DockerImportVM // make sure vm is stopped _ = vbm("controlvm", name, "poweroff") diskInfo, err := getVMDiskInfo(name) if err != nil { return err } if _, err := os.Stat(diskInfo.Path); err != nil { return err } if err := vbm("clonehd", diskInfo.Path, d.diskPath()); err != nil { return err } log.Debugf("Importing VM settings...") vmInfo, err := getVMInfo(name) if err != nil { return err } d.CPU = vmInfo.CPUs d.Memory = vmInfo.Memory log.Debugf("Importing SSH key...") keyPath := filepath.Join(utils.GetHomeDir(), ".ssh", "id_boot2docker") if err := utils.CopyFile(keyPath, d.GetSSHKeyPath()); err != nil { return err } } else { log.Infof("Creating SSH key...") if err := ssh.GenerateSSHKey(d.GetSSHKeyPath()); err != nil { return err } log.Debugf("Creating disk image...") if err := vbm("createhd", "--size", fmt.Sprintf("%d", d.DiskSize), "--format", "VMDK", "--filename", d.diskPath()); err != nil { return err } } if err := vbm("createvm", "--basefolder", d.ResolveStorePath("."), "--name", d.MachineName, "--register"); err != nil { return err } log.Debugf("VM CPUS: %d", d.CPU) log.Debugf("VM Memory: %d", d.Memory) cpus := d.CPU if cpus < 1 { cpus = int(runtime.NumCPU()) } if cpus > 32 { cpus = 32 } if err := vbm("modifyvm", d.MachineName, "--firmware", "bios", "--bioslogofadein", "off", "--bioslogofadeout", "off", "--bioslogodisplaytime", "0", "--biosbootmenu", "disabled", "--ostype", "Linux26_64", "--cpus", fmt.Sprintf("%d", cpus), "--memory", fmt.Sprintf("%d", d.Memory), "--acpi", "on", "--ioapic", "on", "--rtcuseutc", "on", "--natdnshostresolver1", "off", "--natdnsproxy1", "off", "--cpuhotplug", "off", "--pae", "on", "--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", "82540EM", "--cableconnected1", "on"); err != nil { return err } if err := d.setupHostOnlyNetwork(d.MachineName); 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", d.ResolveStorePath(isoFilename)); 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 } shareDir := homedir.Get() shareName := shareDir log.Debugf("creating share: path=%s", shareDir) // let VBoxService do nice magic automounting (when it's used) if err := vbm("guestproperty", "set", d.MachineName, "/VirtualBox/GuestAdd/SharedFolders/MountDir", "/"); err != nil { return err } if err := vbm("guestproperty", "set", d.MachineName, "/VirtualBox/GuestAdd/SharedFolders/MountPrefix", "/"); err != nil { return err } if shareDir != "" { log.Debugf("setting up shareDir") if _, err := os.Stat(shareDir); err != nil && !os.IsNotExist(err) { log.Debugf("setting up share failed: %s", err) return err } else if !os.IsNotExist(err) { // parts of the VBox internal code are buggy with share names that start with "/" shareName = strings.TrimLeft(shareDir, "/") // translate to msys git path if runtime.GOOS == "windows" { mountName, err := translateWindowsMount(shareDir) if err != nil { return err } shareName = mountName } log.Debugf("adding shared folder: name=%q dir=%q", shareName, shareDir) // 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 } // use ssh to set keys sshClient, err := d.getLocalSSHClient() if err != nil { return err } // add pub key for user pubKey, err := ioutil.ReadFile(d.publicSSHKeyPath()) if err != nil { return err } if out, err := sshClient.Output(fmt.Sprintf( "mkdir -p /home/%s/.ssh", d.GetSSHUsername(), )); err != nil { log.Error(out) return err } if out, err := sshClient.Output(fmt.Sprintf( "printf '%%s' '%s' | tee /home/%s/.ssh/authorized_keys", string(pubKey), d.GetSSHUsername(), )); err != nil { log.Error(out) return err } ip, err := d.GetIP() if err != nil { return err } d.IPAddress = ip return nil }
func (d *Driver) Create() error { var err error d.setMachineNameIfNotSet() // Download boot2docker ISO from Internet b2dutils := utils.NewB2dUtils("", "", isoFilename) if err := b2dutils.CopyIsoToMachineDir(d.Boot2DockerURL, d.MachineName); err != nil { return err } log.Infof("Logging into XenServer %s...", d.Server) c, err := d.GetXenAPIClient() if err != nil { return err } // Generate SSH Keys log.Infof("Creating SSH key...") if err := ssh.GenerateSSHKey(d.GetSSHKeyPath()); err != nil { return err } log.Infof("Creating ISO VDI...") // Get the SR var sr *xsclient.SR if d.SR == "" { sr, err = c.GetDefaultSR() } else { sr, err = c.GetUniqueSRByNameLabel(d.SR) } if err != nil { return err } isoFileInfo, err := os.Stat(d.ISO) if err != nil { return err } // Create the VDI isoVdi, err := sr.CreateVdi(isoFilename, isoFileInfo.Size()) if err != nil { log.Errorf("Unable to create ISO VDI '%s': %v", isoFilename, err) return err } // Import the VDI if err = d.importVdi(isoVdi, d.ISO, time.Duration(d.UploadTimeout)*time.Second); err != nil { return err } isoVdiUuid, err := isoVdi.GetUuid() if err != nil { return err } log.Infof("Creating Disk VDI...") err = d.generateDiskImage() if err != nil { return err } // Create the VDI diskVdi, err := sr.CreateVdi("bootdocker disk", int64(d.DiskSize)*1024*1024) if err != nil { log.Errorf("Unable to create ISO VDI '%s': %v", "bootdocker disk", err) return err } if err = d.importVdi(diskVdi, d.TAR, time.Duration(d.UploadTimeout)*time.Second); err != nil { return err } diskVdiUuid, err := diskVdi.GetUuid() if err != nil { return err } log.Infof("Creating VM...") vm0, err := c.GetUniqueVMByNameLabel(osTemplateLabelName) if err != nil { return err } // Clone VM from VM template vm, err := vm0.Clone(fmt.Sprintf("__gui__%s", d.MachineName)) if err != nil { return err } vmMacSeed, err := pseudoUuid() if err != nil { return err } hostname, err := os.Hostname() if err != nil { log.Errorf("Unable get local hostname") } otherConfig := map[string]string{ "base_template_name": osTemplateLabelName, "install-methods": "cdrom,nfs,http,ftp", "linux_template": "true", "mac_seed": vmMacSeed, "docker-machine-creator": hostname, } err = vm.SetOtherConfig(otherConfig) if err != nil { return err } log.Infof("Provision VM...") err = vm.Provision() if err != nil { return err } // Set machine name err = vm.SetNameLabel(d.MachineName) if err != nil { return err } // Set vCPU number err = vm.SetVCPUsMax(d.CPU) if err != nil { return err } err = vm.SetVCPUsAtStartup(d.CPU) if err != nil { return err } platform_params := map[string]string{ "acpi": "1", "apic": "true", "cores-per-socket": "1", "device_id": "0001", "nx": "true", "pae": "true", "vga": "std", "videoram": "8", "viridian": "false", } err = vm.SetPlatform(platform_params) if err != nil { return err } // Set machine memory size err = vm.SetStaticMemoryRange(uint64(d.Memory)*1024*1024, uint64(d.Memory)*1024*1024) if err != nil { return err } log.Infof("Add ISO VDI to VM...") diskVdi, err = c.GetVdiByUuid(isoVdiUuid) if err != nil { return err } err = vm.ConnectVdi(diskVdi, xsclient.Disk, "0") if err != nil { return err } log.Infof("Add Disk VDI to VM...") diskVdi, err = c.GetVdiByUuid(diskVdiUuid) if err != nil { return err } err = vm.ConnectVdi(diskVdi, xsclient.Disk, "1") if err != nil { return err } log.Infof("Add Network to VM...") var networks []*xsclient.Network if d.Network == "" { networks1, err := c.GetNetworks() if err != nil { return err } for _, network := range networks1 { otherConfig, err := network.GetOtherConfig() if err != nil { return err } isInternal, ok := otherConfig["is_host_internal_management_network"] if ok && isInternal == "true" { continue } automaitc, ok := otherConfig["automatic"] if ok && automaitc == "false" { continue } networks = append(networks, network) } } else { network, err := c.GetUniqueNetworkByNameLabel(d.Network) if err != nil { return err } networks = append(networks, network) } if len(networks) == 0 { return fmt.Errorf("Unable get available networks for %v", d.MachineName) } vifDevices, err := vm.GetAllowedVIFDevices() if err != nil { return err } if len(vifDevices) < len(networks) { log.Warnf("VM(%s) networks number is limited to %d.", d.MachineName, len(vifDevices)) networks = networks[:len(vifDevices)] } for i, network := range networks { _, err = vm.ConnectNetwork(network, vifDevices[i]) if err != nil { return err } } log.Infof("Starting VM...") if d.Host == "" { if err = vm.Start(false, false); err != nil { return err } } else { host, err := c.GetUniqueHostByNameLabel(d.Host) if err != nil { return err } if err = vm.StartOn(host, false, false); err != nil { return err } } if err := d.wait(time.Duration(d.WaitTimeout) * time.Second); err != nil { return err } log.Infof("VM Created.") return nil }