// virtualbox doesn't support templates func (s *executor) createVM(vmName string) (err error) { baseImage := s.Config.VirtualBox.BaseName if baseImage == "" { return errors.New("Missing Image setting from VirtualBox configuration") } _, err = vbox.Status(vmName) if err != nil { vbox.Unregister(vmName) } if !vbox.Exist(vmName) { baseSnapshot := s.determineBaseSnapshot(baseImage) if baseSnapshot == "" { s.Debugln("Creating testing VM from VM", baseImage, "...") } else { s.Debugln("Creating testing VM from VM", baseImage, "snapshot", baseSnapshot, "...") } err = vbox.CreateOsVM(baseImage, vmName, baseSnapshot) if err != nil { return err } } s.Debugln("Identify SSH Port...") s.sshPort, err = vbox.FindSSHPort(s.vmName) if err != nil { s.Debugln("Creating localhost ssh forwarding...") vmSSHPort := s.Config.SSH.Port if vmSSHPort == "" { vmSSHPort = "22" } s.sshPort, err = vbox.ConfigureSSH(vmName, vmSSHPort) if err != nil { return err } } s.Debugln("Using local", s.sshPort, "SSH port to connect to VM...") s.Debugln("Bootstraping VM...") err = vbox.Start(s.vmName) if err != nil { return err } s.Debugln("Waiting for VM to become responsive...") time.Sleep(10) err = s.verifyMachine(s.vmName, s.sshPort) if err != nil { return err } return nil }
func (s *executor) Prepare(globalConfig *common.Config, config *common.RunnerConfig, build *common.Build) error { err := s.AbstractExecutor.Prepare(globalConfig, config, build) if err != nil { return err } if s.BuildShell.PassFile { return errors.New("virtualbox doesn't support shells that require script file") } if s.Config.SSH == nil { return errors.New("Missing SSH config") } if s.Config.VirtualBox == nil { return errors.New("Missing VirtualBox configuration") } if s.Config.VirtualBox.BaseName == "" { return errors.New("Missing BaseName setting from VirtualBox configuration") } version, err := vbox.Version() if err != nil { return err } s.Println("Using VirtualBox version", version, "executor...") if s.Config.VirtualBox.DisableSnapshots { s.vmName = s.Config.VirtualBox.BaseName + "-" + s.Build.ProjectUniqueName() if vbox.Exist(s.vmName) { s.Debugln("Deleting old VM...") vbox.Stop(s.vmName) vbox.Delete(s.vmName) vbox.Unregister(s.vmName) } } else { s.vmName = fmt.Sprintf("%s-runner-%s-concurrent-%d", s.Config.VirtualBox.BaseName, s.Build.Runner.ShortDescription(), s.Build.RunnerID) } if vbox.Exist(s.vmName) { s.Println("Restoring VM from snapshot...") err := s.restoreFromSnapshot() if err != nil { s.Println("Previous VM failed. Deleting, because", err) vbox.Stop(s.vmName) vbox.Delete(s.vmName) vbox.Unregister(s.vmName) } } if !vbox.Exist(s.vmName) { s.Println("Creating new VM...") err := s.createVM(s.vmName) if err != nil { return err } if !s.Config.VirtualBox.DisableSnapshots { s.Println("Creating default snapshot...") err = vbox.CreateSnapshot(s.vmName, "Started") if err != nil { return err } } } s.Debugln("Checking VM status...") status, err := vbox.Status(s.vmName) if err != nil { return err } if !vbox.IsStatusOnlineOrTransient(status) { s.Println("Starting VM...") err := vbox.Start(s.vmName) if err != nil { return err } } if status != vbox.Running { s.Debugln("Waiting for VM to run...") err = vbox.WaitForStatus(s.vmName, vbox.Running, 60) if err != nil { return err } } s.Debugln("Identify SSH Port...") sshPort, err := vbox.FindSSHPort(s.vmName) s.sshPort = sshPort if err != nil { return err } s.Println("Waiting VM to become responsive...") err = s.verifyMachine(s.vmName, s.sshPort) if err != nil { return err } s.provisioned = true s.Println("Starting SSH command...") s.sshCommand = ssh.Client{ Config: *s.Config.SSH, Stdout: s.BuildTrace, Stderr: s.BuildTrace, } s.sshCommand.Port = s.sshPort s.sshCommand.Host = "localhost" s.Debugln("Connecting to SSH server...") err = s.sshCommand.Connect() if err != nil { return err } return nil }