func()

in executors/parallels/executor_parallels.go [156:292]


func (s *executor) Prepare(options common.ExecutorPrepareOptions) error {
	err := s.AbstractExecutor.Prepare(options)
	if err != nil {
		return err
	}

	if s.BuildShell.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 s.Config.Parallels.DisableSnapshots {
		s.vmName = s.Config.Parallels.BaseName + "-" + s.Build.ProjectUniqueName()
		if prl.Exist(s.vmName) {
			s.Debugln("Deleting old VM...")
			prl.Kill(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.Kill(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 !s.Config.Parallels.DisableSnapshots {
			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

	// TODO: integration tests do fail on this due
	// Unable to open new session in this virtual machine.
	// Make sure the latest version of Parallels Tools is installed in this virtual machine and it has finished booting
	s.Debugln("Updating VM date...")
	err = prl.TryExec(s.vmName, 20, "sudo", "ntpdate", "-u", "time.apple.com")
	if err != nil {
		return err
	}

	ipAddr, err := s.waitForIPAddress(s.vmName, 60)
	if err != nil {
		return err
	}

	s.Debugln("Starting SSH command...")
	s.sshCommand = ssh.Client{
		Config: *s.Config.SSH,
		Stdout: s.Trace,
		Stderr: s.Trace,
	}
	s.sshCommand.Host = ipAddr

	s.Debugln("Connecting to SSH server...")
	err = s.sshCommand.Connect()
	if err != nil {
		return err
	}
	return nil
}