func (s *ParallelsExecutor) createVM() error { baseImage := s.Config.Parallels.BaseName if baseImage == "" { return errors.New("Missing Image setting from Parallels config") } templateName := helpers.StringOrDefault(s.Config.Parallels.TemplateName, baseImage+"-template") // remove invalid template (removed?) templateStatus, _ := prl.Status(templateName) if templateStatus == prl.Invalid { prl.Unregister(templateName) } if !prl.Exist(templateName) { s.Debugln("Creating template from VM", baseImage, "...") err := prl.CreateTemplate(baseImage, templateName) if err != nil { return err } } s.Debugln("Creating runner from VM template...") err := prl.CreateOsVM(s.vmName, templateName) if err != nil { return err } s.Debugln("Bootstraping VM...") err = prl.Start(s.vmName) if err != nil { return err } s.Debugln("Waiting for VM to start...") err = prl.TryExec(s.vmName, 120, "exit", "0") if err != nil { return err } s.Debugln("Waiting for VM to become responsive...") err = s.verifyMachine(s.vmName) if err != nil { return err } return nil }
func (s *ParallelsExecutor) 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.ShellScript.PassFile { return errors.New("Parallels doesn't support shells that require script file") } if s.Config.SSH == nil { return errors.New("Missing SSH configuration") } if s.Config.Parallels == nil { return errors.New("Missing Parallels configuration") } if s.Config.Parallels.BaseName == "" { return errors.New("Missing BaseName setting from Parallels config") } version, err := prl.Version() if err != nil { return err } s.Println("Using Parallels", version, "executor...") // remove invalid VM (removed?) vmStatus, _ := prl.Status(s.vmName) if vmStatus == prl.Invalid { prl.Unregister(s.vmName) } if helpers.BoolOrDefault(s.Config.Parallels.DisableSnapshots, false) { s.vmName = s.Config.Parallels.BaseName + "-" + s.Build.ProjectUniqueName() if prl.Exist(s.vmName) { s.Debugln("Deleting old VM...") prl.Stop(s.vmName) prl.Delete(s.vmName) prl.Unregister(s.vmName) } } else { s.vmName = fmt.Sprintf("%s-runner-%s-concurrent-%d", s.Config.Parallels.BaseName, s.Build.Runner.ShortDescription(), s.Build.RunnerID) } if prl.Exist(s.vmName) { s.Println("Restoring VM from snapshot...") err := s.restoreFromSnapshot() if err != nil { s.Println("Previous VM failed. Deleting, because", err) prl.Stop(s.vmName) prl.Delete(s.vmName) prl.Unregister(s.vmName) } } if !prl.Exist(s.vmName) { s.Println("Creating new VM...") err := s.createVM() if err != nil { return err } if !helpers.BoolOrDefault(s.Config.Parallels.DisableSnapshots, false) { s.Println("Creating default snapshot...") err = prl.CreateSnapshot(s.vmName, "Started") if err != nil { return err } } } s.Debugln("Checking VM status...") status, err := prl.Status(s.vmName) if err != nil { return err } // Start VM if stopped if status == prl.Stopped || status == prl.Suspended { s.Println("Starting VM...") err := prl.Start(s.vmName) if err != nil { return err } } if status != prl.Running { s.Debugln("Waiting for VM to run...") err = prl.WaitForStatus(s.vmName, prl.Running, 60) if err != nil { return err } } s.Println("Waiting VM to become responsive...") err = s.verifyMachine(s.vmName) if err != nil { return err } s.provisioned = true s.Debugln("Updating VM date...") err = prl.TryExec(s.vmName, 20, "sudo", "ntpdate", "-u", "time.apple.com") if err != nil { return err } return nil }