func (s *executor) determineBaseSnapshot(baseImage string) string { var err error baseSnapshot := s.Config.VirtualBox.BaseSnapshot if baseSnapshot == "" { baseSnapshot, err = vbox.GetCurrentSnapshot(baseImage) if err != nil { if s.Config.VirtualBox.DisableSnapshots { s.Debugln("No snapshots found for base VM", baseImage) return "" } baseSnapshot = "Base State" } } if baseSnapshot != "" && !vbox.HasSnapshot(baseImage, baseSnapshot) { if s.Config.VirtualBox.DisableSnapshots { s.Warningln("Snapshot", baseSnapshot, "not found in base VM", baseImage) return "" } s.Debugln("Creating snapshot", baseSnapshot, "from current base VM", baseImage, "state...") err = vbox.CreateSnapshot(baseImage, baseSnapshot) if err != nil { s.Warningln("Failed to create snapshot", baseSnapshot, "from base VM", baseImage) return "" } } return baseSnapshot }
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 }