func (cloudManager *EC2SpotManager) TerminateInstance(host *host.Host) error { // terminate the instance if host.Status == evergreen.HostTerminated { errMsg := fmt.Errorf("Can not terminate %v - already marked as "+ "terminated!", host.Id) evergreen.Logger.Errorf(slogger.ERROR, errMsg.Error()) return errMsg } spotDetails, err := cloudManager.describeSpotRequest(host.Id) if err != nil { ec2err, ok := err.(*ec2.Error) if ok && ec2err.Code == EC2ErrorSpotRequestNotFound { // EC2 says the spot request is not found - assume this means amazon // terminated our spot instance evergreen.Logger.Logf(slogger.WARN, "EC2 could not find spot instance '%v', "+ "marking as terminated", host.Id) return host.Terminate() } return evergreen.Logger.Errorf(slogger.ERROR, "Couldn't terminate, "+ "failed to get spot request info for %v: %v", host.Id, err) } evergreen.Logger.Logf(slogger.INFO, "Cancelling spot request %v", host.Id) //First cancel the spot request ec2Handle := getUSEast(*cloudManager.awsCredentials) _, err = ec2Handle.CancelSpotRequests([]string{host.Id}) if err != nil { return evergreen.Logger.Errorf(slogger.ERROR, "Failed to cancel spot request for host %v: %v", host.Id, err) } //Canceling the spot request doesn't terminate the instance that fulfilled it, // if it was fulfilled. We need to terminate the instance explicitly if spotDetails.InstanceId != "" { evergreen.Logger.Logf(slogger.INFO, "Spot request %v cancelled, now terminating instance %v", spotDetails.InstanceId, host.Id) resp, err := ec2Handle.TerminateInstances([]string{spotDetails.InstanceId}) if err != nil { return evergreen.Logger.Errorf(slogger.INFO, "Failed to terminate host %v: %v", host.Id, err) } for _, stateChange := range resp.StateChanges { evergreen.Logger.Logf(slogger.INFO, "Terminated %v", stateChange.InstanceId) } } else { evergreen.Logger.Logf(slogger.INFO, "Spot request %v cancelled (no instances have fulfilled it)", host.Id) } // set the host status as terminated and update its termination time return host.Terminate() }
//TerminateInstance destroys a droplet. func (digoMgr *DigitalOceanManager) TerminateInstance(host *host.Host) error { hostIdAsInt, err := strconv.Atoi(host.Id) if err != nil { return evergreen.Logger.Errorf(slogger.ERROR, "Can't terminate '%v': DigitalOcean host id's must be integers", host.Id) } response, err := digoMgr.account.DestroyDroplet(hostIdAsInt) if err != nil { return evergreen.Logger.Errorf(slogger.ERROR, "Failed to destroy droplet '%v': %v", host.Id, err) } if response.Status != "OK" { return evergreen.Logger.Errorf(slogger.ERROR, "Failed to destroy droplet '%v': error message %v", err, response.ErrorMessage) } return host.Terminate() }
//TerminateInstance destroys a container. func (dockerMgr *DockerManager) TerminateInstance(host *host.Host) error { dockerClient, _, err := generateClient(&host.Distro) if err != nil { return err } err = dockerClient.StopContainer(host.Id, TimeoutSeconds) if err != nil { return evergreen.Logger.Errorf(slogger.ERROR, "Failed to stop container '%v': %v", host.Id, err) } err = dockerClient.RemoveContainer( docker.RemoveContainerOptions{ ID: host.Id, }, ) if err != nil { return evergreen.Logger.Errorf(slogger.ERROR, "Failed to remove container '%v': %v", host.Id, err) } return host.Terminate() }
func (cloudManager *EC2Manager) TerminateInstance(host *host.Host) error { // terminate the instance if host.Status == evergreen.HostTerminated { errMsg := fmt.Errorf("Can not terminate %v - already marked as "+ "terminated!", host.Id) evergreen.Logger.Errorf(slogger.ERROR, errMsg.Error()) return errMsg } ec2Handle := getUSEast(*cloudManager.awsCredentials) resp, err := ec2Handle.TerminateInstances([]string{host.Id}) if err != nil { return err } for _, stateChange := range resp.StateChanges { evergreen.Logger.Logf(slogger.INFO, "Terminated %v", stateChange.InstanceId) } // set the host status as terminated and update its termination time return host.Terminate() }