Add instance lifecycle property to detect spot instances (#4260)
This commit is contained in:
parent
edca235623
commit
6d9abe1111
@ -526,6 +526,7 @@ class Instance(TaggedEC2Resource, BotoInstance, CloudFormationModel):
|
|||||||
super(Instance, self).__init__()
|
super(Instance, self).__init__()
|
||||||
self.ec2_backend = ec2_backend
|
self.ec2_backend = ec2_backend
|
||||||
self.id = random_instance_id()
|
self.id = random_instance_id()
|
||||||
|
self.lifecycle = kwargs.get("lifecycle", "")
|
||||||
self.image_id = image_id
|
self.image_id = image_id
|
||||||
self._state = InstanceState("running", 16)
|
self._state = InstanceState("running", 16)
|
||||||
self._reason = ""
|
self._reason = ""
|
||||||
@ -1001,6 +1002,8 @@ class InstanceBackend(object):
|
|||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
new_instance.setup_defaults()
|
new_instance.setup_defaults()
|
||||||
|
if kwargs.get("instance_market_options"):
|
||||||
|
new_instance.lifecycle = "spot"
|
||||||
# Tag all created volumes.
|
# Tag all created volumes.
|
||||||
for _, device in new_instance.get_block_device_mapping:
|
for _, device in new_instance.get_block_device_mapping:
|
||||||
volumes = self.describe_volumes(volume_ids=[device.volume_id])
|
volumes = self.describe_volumes(volume_ids=[device.volume_id])
|
||||||
@ -5172,6 +5175,7 @@ class SpotInstanceRequest(BotoSpotRequest, TaggedEC2Resource):
|
|||||||
security_group_ids=self.launch_specification.groups,
|
security_group_ids=self.launch_specification.groups,
|
||||||
spot_fleet_id=self.spot_fleet_id,
|
spot_fleet_id=self.spot_fleet_id,
|
||||||
tags=self.tags,
|
tags=self.tags,
|
||||||
|
lifecycle="spot",
|
||||||
)
|
)
|
||||||
instance = reservation.instances[0]
|
instance = reservation.instances[0]
|
||||||
return instance
|
return instance
|
||||||
|
@ -62,6 +62,10 @@ class InstanceResponse(BaseResponse):
|
|||||||
"associate_public_ip": self._get_param("AssociatePublicIpAddress"),
|
"associate_public_ip": self._get_param("AssociatePublicIpAddress"),
|
||||||
"tags": self._parse_tag_specification("TagSpecification"),
|
"tags": self._parse_tag_specification("TagSpecification"),
|
||||||
"ebs_optimized": self._get_param("EbsOptimized") or False,
|
"ebs_optimized": self._get_param("EbsOptimized") or False,
|
||||||
|
"instance_market_options": self._get_param(
|
||||||
|
"InstanceMarketOptions.MarketType"
|
||||||
|
)
|
||||||
|
or {},
|
||||||
"instance_initiated_shutdown_behavior": self._get_param(
|
"instance_initiated_shutdown_behavior": self._get_param(
|
||||||
"InstanceInitiatedShutdownBehavior"
|
"InstanceInitiatedShutdownBehavior"
|
||||||
),
|
),
|
||||||
@ -382,6 +386,7 @@ EC2_RUN_INSTANCES = (
|
|||||||
<amiLaunchIndex>{{ instance.ami_launch_index }}</amiLaunchIndex>
|
<amiLaunchIndex>{{ instance.ami_launch_index }}</amiLaunchIndex>
|
||||||
<instanceType>{{ instance.instance_type }}</instanceType>
|
<instanceType>{{ instance.instance_type }}</instanceType>
|
||||||
<launchTime>{{ instance.launch_time }}</launchTime>
|
<launchTime>{{ instance.launch_time }}</launchTime>
|
||||||
|
<instanceLifecycle>{{ instance.lifecycle }}</instanceLifecycle>
|
||||||
<placement>
|
<placement>
|
||||||
<availabilityZone>{{ instance.placement}}</availabilityZone>
|
<availabilityZone>{{ instance.placement}}</availabilityZone>
|
||||||
<groupName/>
|
<groupName/>
|
||||||
@ -533,6 +538,7 @@ EC2_DESCRIBE_INSTANCES = (
|
|||||||
<productCodes/>
|
<productCodes/>
|
||||||
<instanceType>{{ instance.instance_type }}</instanceType>
|
<instanceType>{{ instance.instance_type }}</instanceType>
|
||||||
<launchTime>{{ instance.launch_time }}</launchTime>
|
<launchTime>{{ instance.launch_time }}</launchTime>
|
||||||
|
<instanceLifecycle>{{ instance.lifecycle }}</instanceLifecycle>
|
||||||
<placement>
|
<placement>
|
||||||
<availabilityZone>{{ instance.placement }}</availabilityZone>
|
<availabilityZone>{{ instance.placement }}</availabilityZone>
|
||||||
<groupName/>
|
<groupName/>
|
||||||
|
@ -177,6 +177,7 @@ class Instance(TaggedEC2Object):
|
|||||||
self.monitoring_state = None
|
self.monitoring_state = None
|
||||||
self.spot_instance_request_id = None
|
self.spot_instance_request_id = None
|
||||||
self.subnet_id = None
|
self.subnet_id = None
|
||||||
|
self.lifecycle = None
|
||||||
self.vpc_id = None
|
self.vpc_id = None
|
||||||
self.private_ip_address = None
|
self.private_ip_address = None
|
||||||
self.ip_address = None
|
self.ip_address = None
|
||||||
|
@ -39,6 +39,7 @@ class LaunchSpecification(EC2Object):
|
|||||||
self.ramdisk = None
|
self.ramdisk = None
|
||||||
self.monitored = False
|
self.monitored = False
|
||||||
self.subnet_id = None
|
self.subnet_id = None
|
||||||
|
self.lifecycle = None
|
||||||
self._in_monitoring_element = False
|
self._in_monitoring_element = False
|
||||||
self.block_device_mapping = None
|
self.block_device_mapping = None
|
||||||
self.instance_profile = None
|
self.instance_profile = None
|
||||||
|
@ -257,3 +257,59 @@ def test_request_spot_instances_setting_instance_id():
|
|||||||
request = conn.get_all_spot_instance_requests()[0]
|
request = conn.get_all_spot_instance_requests()[0]
|
||||||
assert request.state == "active"
|
assert request.state == "active"
|
||||||
assert request.instance_id == "i-12345678"
|
assert request.instance_id == "i-12345678"
|
||||||
|
|
||||||
|
|
||||||
|
@mock_ec2
|
||||||
|
def test_request_spot_instances_instance_lifecycle():
|
||||||
|
client = boto3.client("ec2", region_name="us-east-1")
|
||||||
|
request = client.request_spot_instances(SpotPrice="0.5")
|
||||||
|
|
||||||
|
response = client.describe_instances()
|
||||||
|
|
||||||
|
instance = response["Reservations"][0]["Instances"][0]
|
||||||
|
instance["InstanceLifecycle"].should.equal("spot")
|
||||||
|
|
||||||
|
|
||||||
|
@mock_ec2
|
||||||
|
def test_launch_spot_instance_instance_lifecycle():
|
||||||
|
client = boto3.client("ec2", region_name="us-east-1")
|
||||||
|
|
||||||
|
kwargs = {
|
||||||
|
"KeyName": "foobar",
|
||||||
|
"ImageId": "ami-pytest",
|
||||||
|
"MinCount": 1,
|
||||||
|
"MaxCount": 1,
|
||||||
|
"InstanceType": "c4.2xlarge",
|
||||||
|
"TagSpecifications": [
|
||||||
|
{"ResourceType": "instance", "Tags": [{"Key": "key", "Value": "val"}]},
|
||||||
|
],
|
||||||
|
"InstanceMarketOptions": {"MarketType": "spot"},
|
||||||
|
}
|
||||||
|
|
||||||
|
client.run_instances(**kwargs)["Instances"][0]
|
||||||
|
|
||||||
|
response = client.describe_instances()
|
||||||
|
instance = response["Reservations"][0]["Instances"][0]
|
||||||
|
instance["InstanceLifecycle"].should.equal("spot")
|
||||||
|
|
||||||
|
|
||||||
|
@mock_ec2
|
||||||
|
def test_launch_instance_instance_lifecycle():
|
||||||
|
client = boto3.client("ec2", region_name="us-east-1")
|
||||||
|
|
||||||
|
kwargs = {
|
||||||
|
"KeyName": "foobar",
|
||||||
|
"ImageId": "ami-pytest",
|
||||||
|
"MinCount": 1,
|
||||||
|
"MaxCount": 1,
|
||||||
|
"InstanceType": "c4.2xlarge",
|
||||||
|
"TagSpecifications": [
|
||||||
|
{"ResourceType": "instance", "Tags": [{"Key": "key", "Value": "val"}]},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
client.run_instances(**kwargs)["Instances"][0]
|
||||||
|
|
||||||
|
response = client.describe_instances()
|
||||||
|
instance = response["Reservations"][0]["Instances"][0]
|
||||||
|
instance["InstanceLifecycle"].should.equal("")
|
||||||
|
Loading…
x
Reference in New Issue
Block a user