diff --git a/src/applications/drydock/blueprint/DrydockAmazonEC2HostBlueprintImplementation.php b/src/applications/drydock/blueprint/DrydockAmazonEC2HostBlueprintImplementation.php --- a/src/applications/drydock/blueprint/DrydockAmazonEC2HostBlueprintImplementation.php +++ b/src/applications/drydock/blueprint/DrydockAmazonEC2HostBlueprintImplementation.php @@ -215,6 +215,9 @@ $this->log(pht( 'Spot instance request ID is %s', $spot_request_id)); + $resource->setAttribute('spot-request-id', $spot_request_id); + $resource->save(); + // Wait until the spot instance request exists. while (true) { try { @@ -826,26 +829,56 @@ } } - $this->log(pht( - 'Requesting instance \'%s\' be terminated.', - $resource->getAttribute('instance-id'))); + if ($resource->getAttribute('instance-id') !== '') { + $this->log(pht( + 'Requesting instance \'%s\' be terminated.', + $resource->getAttribute('instance-id'))); - try { - // Terminate the EC2 instance. - $this->getAWSEC2Future() - ->setRawAWSQuery( - 'TerminateInstances', - array( - 'InstanceId.0' => $resource->getAttribute('instance-id'),)) - ->resolve(); - } catch (PhutilAWSException $exx) { - if (substr_count($exx->getMessage(), 'InvalidInstanceID.NotFound') > 0) { - return; - } else { - throw $exx; + try { + // Terminate the EC2 instance. + $this->getAWSEC2Future() + ->setRawAWSQuery( + 'TerminateInstances', + array( + 'InstanceId.0' => $resource->getAttribute('instance-id'),)) + ->resolve(); + } catch (PhutilAWSException $exx) { + if (substr_count( + $exx->getMessage(), + 'InvalidInstanceID.NotFound') > 0) { + return; + } else { + throw $exx; + } } - } + } else if ($resource->getAttribute('spot-request-id') !== '') { + $this->log(pht( + 'Requesting spot request \'%s\' be cancelled.', + $resource->getAttribute('spot-request-id'))); + try { + // Cancel the spot request. + $this->getAWSEC2Future() + ->setRawAWSQuery( + 'CancelSpotInstanceRequests', + array( + 'SpotInstanceRequestId.0' => + $resource->getAttribute('spot-request-id'),)) + ->resolve(); + } catch (PhutilAWSException $exx) { + if (substr_count( + $exx->getMessage(), + 'InvalidSpotInstanceRequestID.NotFound') > 0) { + return; + } else { + throw $exx; + } + } + } else { + $this->log(pht( + 'This resource did not have an instance ID, '. + 'so no cleanup was performed.')); + } } protected function executeAcquireLease(