Have spot requests launch instances.
This commit is contained in:
parent
24035877f6
commit
5c3d9b4ae1
@ -2517,6 +2517,8 @@ class SpotInstanceRequest(BotoSpotRequest, TaggedEC2Resource):
|
|||||||
default_group = self.ec2_backend.get_security_group_from_name("default")
|
default_group = self.ec2_backend.get_security_group_from_name("default")
|
||||||
ls.groups.append(default_group)
|
ls.groups.append(default_group)
|
||||||
|
|
||||||
|
self.instance = self.launch_instance()
|
||||||
|
|
||||||
def get_filter_value(self, filter_name):
|
def get_filter_value(self, filter_name):
|
||||||
if filter_name == 'state':
|
if filter_name == 'state':
|
||||||
return self.state
|
return self.state
|
||||||
@ -2529,6 +2531,18 @@ class SpotInstanceRequest(BotoSpotRequest, TaggedEC2Resource):
|
|||||||
|
|
||||||
return filter_value
|
return filter_value
|
||||||
|
|
||||||
|
def launch_instance(self):
|
||||||
|
reservation = self.ec2_backend.add_instances(
|
||||||
|
image_id=self.launch_specification.image_id, count=1, user_data=self.user_data,
|
||||||
|
instance_type=self.launch_specification.instance_type,
|
||||||
|
subnet_id=self.launch_specification.subnet_id,
|
||||||
|
key_name=self.launch_specification.key_name,
|
||||||
|
security_group_names=[],
|
||||||
|
security_group_ids=self.launch_specification.groups,
|
||||||
|
)
|
||||||
|
instance = reservation.instances[0]
|
||||||
|
return instance
|
||||||
|
|
||||||
|
|
||||||
@six.add_metaclass(Model)
|
@six.add_metaclass(Model)
|
||||||
class SpotRequestBackend(object):
|
class SpotRequestBackend(object):
|
||||||
|
@ -98,9 +98,9 @@ DESCRIBE_SPOT_FLEET_INSTANCES_TEMPLATE = """<DescribeSpotFleetInstancesResponse
|
|||||||
<activeInstanceSet>
|
<activeInstanceSet>
|
||||||
{% for spot_request in spot_requests %}
|
{% for spot_request in spot_requests %}
|
||||||
<item>
|
<item>
|
||||||
<instanceId>{{ spot_request.instance_id }}</instanceId>
|
<instanceId>{{ spot_request.instance.id }}</instanceId>
|
||||||
<spotInstanceRequestId>{{ spot_request.id }}</spotInstanceRequestId>
|
<spotInstanceRequestId>{{ spot_request.id }}</spotInstanceRequestId>
|
||||||
<instanceType>{{ spot_request.instance_type }}</instanceType>
|
<instanceType>{{ spot_request.instance.instance_type }}</instanceType>
|
||||||
</item>
|
</item>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</activeInstanceSet>
|
</activeInstanceSet>
|
||||||
|
@ -1881,6 +1881,12 @@ def test_stack_kms():
|
|||||||
@mock_cloudformation()
|
@mock_cloudformation()
|
||||||
@mock_ec2()
|
@mock_ec2()
|
||||||
def test_stack_spot_fleet():
|
def test_stack_spot_fleet():
|
||||||
|
conn = boto3.client('ec2', 'us-east-1')
|
||||||
|
|
||||||
|
vpc = conn.create_vpc(CidrBlock="10.0.0.0/8")['Vpc']
|
||||||
|
subnet = conn.create_subnet(VpcId=vpc['VpcId'], CidrBlock='10.0.0.0/16', AvailabilityZone='us-east-1a')['Subnet']
|
||||||
|
subnet_id = subnet['SubnetId']
|
||||||
|
|
||||||
spot_fleet_template = {
|
spot_fleet_template = {
|
||||||
'Resources': {
|
'Resources': {
|
||||||
"SpotFleet": {
|
"SpotFleet": {
|
||||||
@ -1896,7 +1902,7 @@ def test_stack_spot_fleet():
|
|||||||
"EbsOptimized": "false",
|
"EbsOptimized": "false",
|
||||||
"InstanceType": 't2.small',
|
"InstanceType": 't2.small',
|
||||||
"ImageId": "ami-1234",
|
"ImageId": "ami-1234",
|
||||||
"SubnetId": "subnet-123",
|
"SubnetId": subnet_id,
|
||||||
"WeightedCapacity": "2",
|
"WeightedCapacity": "2",
|
||||||
"SpotPrice": "0.13",
|
"SpotPrice": "0.13",
|
||||||
},
|
},
|
||||||
@ -1906,7 +1912,7 @@ def test_stack_spot_fleet():
|
|||||||
"ImageId": "ami-1234",
|
"ImageId": "ami-1234",
|
||||||
"Monitoring": { "Enabled": "true" },
|
"Monitoring": { "Enabled": "true" },
|
||||||
"SecurityGroups": [{"GroupId": "sg-123"}],
|
"SecurityGroups": [{"GroupId": "sg-123"}],
|
||||||
"SubnetId": "subnet-123",
|
"SubnetId": subnet_id,
|
||||||
"IamInstanceProfile": {"Arn": "arn:aws:iam::123456789012:role/fleet"},
|
"IamInstanceProfile": {"Arn": "arn:aws:iam::123456789012:role/fleet"},
|
||||||
"WeightedCapacity": "4",
|
"WeightedCapacity": "4",
|
||||||
"SpotPrice": "10.00",
|
"SpotPrice": "10.00",
|
||||||
@ -1929,7 +1935,6 @@ def test_stack_spot_fleet():
|
|||||||
stack_resources['StackResourceSummaries'].should.have.length_of(1)
|
stack_resources['StackResourceSummaries'].should.have.length_of(1)
|
||||||
spot_fleet_id = stack_resources['StackResourceSummaries'][0]['PhysicalResourceId']
|
spot_fleet_id = stack_resources['StackResourceSummaries'][0]['PhysicalResourceId']
|
||||||
|
|
||||||
conn = boto3.client('ec2', 'us-east-1')
|
|
||||||
spot_fleet_requests = conn.describe_spot_fleet_requests(SpotFleetRequestIds=[spot_fleet_id])['SpotFleetRequestConfigs']
|
spot_fleet_requests = conn.describe_spot_fleet_requests(SpotFleetRequestIds=[spot_fleet_id])['SpotFleetRequestConfigs']
|
||||||
len(spot_fleet_requests).should.equal(1)
|
len(spot_fleet_requests).should.equal(1)
|
||||||
spot_fleet_request = spot_fleet_requests[0]
|
spot_fleet_request = spot_fleet_requests[0]
|
||||||
@ -1948,6 +1953,6 @@ def test_stack_spot_fleet():
|
|||||||
launch_spec['EbsOptimized'].should.equal(False)
|
launch_spec['EbsOptimized'].should.equal(False)
|
||||||
launch_spec['ImageId'].should.equal("ami-1234")
|
launch_spec['ImageId'].should.equal("ami-1234")
|
||||||
launch_spec['InstanceType'].should.equal("t2.small")
|
launch_spec['InstanceType'].should.equal("t2.small")
|
||||||
launch_spec['SubnetId'].should.equal("subnet-123")
|
launch_spec['SubnetId'].should.equal(subnet_id)
|
||||||
launch_spec['SpotPrice'].should.equal("0.13")
|
launch_spec['SpotPrice'].should.equal("0.13")
|
||||||
launch_spec['WeightedCapacity'].should.equal(2.0)
|
launch_spec['WeightedCapacity'].should.equal(2.0)
|
||||||
|
@ -5,78 +5,87 @@ import sure # noqa
|
|||||||
|
|
||||||
from moto import mock_ec2
|
from moto import mock_ec2
|
||||||
|
|
||||||
SPOT_REQUEST_CONFIG = {
|
def get_subnet_id(conn):
|
||||||
'ClientToken': 'string',
|
vpc = conn.create_vpc(CidrBlock="10.0.0.0/8")['Vpc']
|
||||||
'SpotPrice': '0.12',
|
subnet = conn.create_subnet(VpcId=vpc['VpcId'], CidrBlock='10.0.0.0/16', AvailabilityZone='us-east-1a')['Subnet']
|
||||||
'TargetCapacity': 6,
|
subnet_id = subnet['SubnetId']
|
||||||
'IamFleetRole': 'arn:aws:iam::123456789012:role/fleet',
|
return subnet_id
|
||||||
'LaunchSpecifications': [{
|
|
||||||
'ImageId': 'ami-123',
|
|
||||||
'KeyName': 'my-key',
|
def spot_config(subnet_id, allocation_strategy="lowestPrice"):
|
||||||
'SecurityGroups': [
|
return {
|
||||||
{
|
'ClientToken': 'string',
|
||||||
'GroupId': 'sg-123'
|
'SpotPrice': '0.12',
|
||||||
},
|
'TargetCapacity': 6,
|
||||||
],
|
'IamFleetRole': 'arn:aws:iam::123456789012:role/fleet',
|
||||||
'UserData': 'some user data',
|
'LaunchSpecifications': [{
|
||||||
'InstanceType': 't2.small',
|
'ImageId': 'ami-123',
|
||||||
'BlockDeviceMappings': [
|
'KeyName': 'my-key',
|
||||||
{
|
'SecurityGroups': [
|
||||||
'VirtualName': 'string',
|
{
|
||||||
'DeviceName': 'string',
|
'GroupId': 'sg-123'
|
||||||
'Ebs': {
|
|
||||||
'SnapshotId': 'string',
|
|
||||||
'VolumeSize': 123,
|
|
||||||
'DeleteOnTermination': True|False,
|
|
||||||
'VolumeType': 'standard',
|
|
||||||
'Iops': 123,
|
|
||||||
'Encrypted': True|False
|
|
||||||
},
|
},
|
||||||
'NoDevice': 'string'
|
],
|
||||||
|
'UserData': 'some user data',
|
||||||
|
'InstanceType': 't2.small',
|
||||||
|
'BlockDeviceMappings': [
|
||||||
|
{
|
||||||
|
'VirtualName': 'string',
|
||||||
|
'DeviceName': 'string',
|
||||||
|
'Ebs': {
|
||||||
|
'SnapshotId': 'string',
|
||||||
|
'VolumeSize': 123,
|
||||||
|
'DeleteOnTermination': True|False,
|
||||||
|
'VolumeType': 'standard',
|
||||||
|
'Iops': 123,
|
||||||
|
'Encrypted': True|False
|
||||||
|
},
|
||||||
|
'NoDevice': 'string'
|
||||||
|
},
|
||||||
|
],
|
||||||
|
'Monitoring': {
|
||||||
|
'Enabled': True
|
||||||
},
|
},
|
||||||
],
|
'SubnetId': subnet_id,
|
||||||
'Monitoring': {
|
'IamInstanceProfile': {
|
||||||
'Enabled': True
|
'Arn': 'arn:aws:iam::123456789012:role/fleet'
|
||||||
},
|
|
||||||
'SubnetId': 'subnet-1234',
|
|
||||||
'IamInstanceProfile': {
|
|
||||||
'Arn': 'arn:aws:iam::123456789012:role/fleet'
|
|
||||||
},
|
|
||||||
'EbsOptimized': False,
|
|
||||||
'WeightedCapacity': 2.0,
|
|
||||||
'SpotPrice': '0.13'
|
|
||||||
}, {
|
|
||||||
'ImageId': 'ami-123',
|
|
||||||
'KeyName': 'my-key',
|
|
||||||
'SecurityGroups': [
|
|
||||||
{
|
|
||||||
'GroupId': 'sg-123'
|
|
||||||
},
|
},
|
||||||
],
|
'EbsOptimized': False,
|
||||||
'UserData': 'some user data',
|
'WeightedCapacity': 2.0,
|
||||||
'InstanceType': 't2.large',
|
'SpotPrice': '0.13'
|
||||||
'Monitoring': {
|
}, {
|
||||||
'Enabled': True
|
'ImageId': 'ami-123',
|
||||||
},
|
'KeyName': 'my-key',
|
||||||
'SubnetId': 'subnet-1234',
|
'SecurityGroups': [
|
||||||
'IamInstanceProfile': {
|
{
|
||||||
'Arn': 'arn:aws:iam::123456789012:role/fleet'
|
'GroupId': 'sg-123'
|
||||||
},
|
},
|
||||||
'EbsOptimized': False,
|
],
|
||||||
'WeightedCapacity': 4.0,
|
'UserData': 'some user data',
|
||||||
'SpotPrice': '10.00',
|
'InstanceType': 't2.large',
|
||||||
}],
|
'Monitoring': {
|
||||||
'AllocationStrategy': 'lowestPrice',
|
'Enabled': True
|
||||||
'FulfilledCapacity': 6,
|
},
|
||||||
}
|
'SubnetId': subnet_id,
|
||||||
|
'IamInstanceProfile': {
|
||||||
|
'Arn': 'arn:aws:iam::123456789012:role/fleet'
|
||||||
|
},
|
||||||
|
'EbsOptimized': False,
|
||||||
|
'WeightedCapacity': 4.0,
|
||||||
|
'SpotPrice': '10.00',
|
||||||
|
}],
|
||||||
|
'AllocationStrategy': allocation_strategy,
|
||||||
|
'FulfilledCapacity': 6,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@mock_ec2
|
@mock_ec2
|
||||||
def test_create_spot_fleet_with_lowest_price():
|
def test_create_spot_fleet_with_lowest_price():
|
||||||
conn = boto3.client("ec2", region_name='us-west-2')
|
conn = boto3.client("ec2", region_name='us-west-2')
|
||||||
|
subnet_id = get_subnet_id(conn)
|
||||||
|
|
||||||
spot_fleet_res = conn.request_spot_fleet(
|
spot_fleet_res = conn.request_spot_fleet(
|
||||||
SpotFleetRequestConfig=SPOT_REQUEST_CONFIG
|
SpotFleetRequestConfig=spot_config(subnet_id)
|
||||||
)
|
)
|
||||||
spot_fleet_id = spot_fleet_res['SpotFleetRequestId']
|
spot_fleet_id = spot_fleet_res['SpotFleetRequestId']
|
||||||
|
|
||||||
@ -103,7 +112,7 @@ def test_create_spot_fleet_with_lowest_price():
|
|||||||
launch_spec['KeyName'].should.equal("my-key")
|
launch_spec['KeyName'].should.equal("my-key")
|
||||||
launch_spec['Monitoring'].should.equal({"Enabled": True})
|
launch_spec['Monitoring'].should.equal({"Enabled": True})
|
||||||
launch_spec['SpotPrice'].should.equal("0.13")
|
launch_spec['SpotPrice'].should.equal("0.13")
|
||||||
launch_spec['SubnetId'].should.equal("subnet-1234")
|
launch_spec['SubnetId'].should.equal(subnet_id)
|
||||||
launch_spec['UserData'].should.equal("some user data")
|
launch_spec['UserData'].should.equal("some user data")
|
||||||
launch_spec['WeightedCapacity'].should.equal(2.0)
|
launch_spec['WeightedCapacity'].should.equal(2.0)
|
||||||
|
|
||||||
@ -115,8 +124,8 @@ def test_create_spot_fleet_with_lowest_price():
|
|||||||
@mock_ec2
|
@mock_ec2
|
||||||
def test_create_diversified_spot_fleet():
|
def test_create_diversified_spot_fleet():
|
||||||
conn = boto3.client("ec2", region_name='us-west-2')
|
conn = boto3.client("ec2", region_name='us-west-2')
|
||||||
diversified_config = SPOT_REQUEST_CONFIG.copy()
|
subnet_id = get_subnet_id(conn)
|
||||||
diversified_config['AllocationStrategy'] = 'diversified'
|
diversified_config = spot_config(subnet_id, allocation_strategy='diversified')
|
||||||
|
|
||||||
spot_fleet_res = conn.request_spot_fleet(
|
spot_fleet_res = conn.request_spot_fleet(
|
||||||
SpotFleetRequestConfig=diversified_config
|
SpotFleetRequestConfig=diversified_config
|
||||||
@ -126,14 +135,17 @@ def test_create_diversified_spot_fleet():
|
|||||||
instance_res = conn.describe_spot_fleet_instances(SpotFleetRequestId=spot_fleet_id)
|
instance_res = conn.describe_spot_fleet_instances(SpotFleetRequestId=spot_fleet_id)
|
||||||
instances = instance_res['ActiveInstances']
|
instances = instance_res['ActiveInstances']
|
||||||
len(instances).should.equal(2)
|
len(instances).should.equal(2)
|
||||||
|
instances[0]['InstanceType'].should.equal("t2.small")
|
||||||
|
instances[0]['InstanceId'].should.contain("i-")
|
||||||
|
|
||||||
|
|
||||||
@mock_ec2
|
@mock_ec2
|
||||||
def test_cancel_spot_fleet_request():
|
def test_cancel_spot_fleet_request():
|
||||||
conn = boto3.client("ec2", region_name='us-west-2')
|
conn = boto3.client("ec2", region_name='us-west-2')
|
||||||
|
subnet_id = get_subnet_id(conn)
|
||||||
|
|
||||||
spot_fleet_res = conn.request_spot_fleet(
|
spot_fleet_res = conn.request_spot_fleet(
|
||||||
SpotFleetRequestConfig=SPOT_REQUEST_CONFIG,
|
SpotFleetRequestConfig=spot_config(subnet_id),
|
||||||
)
|
)
|
||||||
spot_fleet_id = spot_fleet_res['SpotFleetRequestId']
|
spot_fleet_id = spot_fleet_res['SpotFleetRequestId']
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@ from nose.tools import assert_raises
|
|||||||
import datetime
|
import datetime
|
||||||
|
|
||||||
import boto
|
import boto
|
||||||
|
import boto3
|
||||||
import sure # noqa
|
import sure # noqa
|
||||||
from boto.exception import JSONResponseError
|
from boto.exception import JSONResponseError
|
||||||
|
|
||||||
@ -13,6 +14,11 @@ from moto.core.utils import iso_8601_datetime_with_milliseconds
|
|||||||
|
|
||||||
@mock_ec2
|
@mock_ec2
|
||||||
def test_request_spot_instances():
|
def test_request_spot_instances():
|
||||||
|
conn = boto3.client('ec2', 'us-east-1')
|
||||||
|
vpc = conn.create_vpc(CidrBlock="10.0.0.0/8")['Vpc']
|
||||||
|
subnet = conn.create_subnet(VpcId=vpc['VpcId'], CidrBlock='10.0.0.0/16', AvailabilityZone='us-east-1a')['Subnet']
|
||||||
|
subnet_id = subnet['SubnetId']
|
||||||
|
|
||||||
conn = boto.connect_ec2()
|
conn = boto.connect_ec2()
|
||||||
|
|
||||||
conn.create_security_group('group1', 'description')
|
conn.create_security_group('group1', 'description')
|
||||||
@ -29,7 +35,7 @@ def test_request_spot_instances():
|
|||||||
security_groups=['group1', 'group2'], user_data=b"some test data",
|
security_groups=['group1', 'group2'], user_data=b"some test data",
|
||||||
instance_type='m1.small', placement='us-east-1c',
|
instance_type='m1.small', placement='us-east-1c',
|
||||||
kernel_id="test-kernel", ramdisk_id="test-ramdisk",
|
kernel_id="test-kernel", ramdisk_id="test-ramdisk",
|
||||||
monitoring_enabled=True, subnet_id="subnet123", dry_run=True
|
monitoring_enabled=True, subnet_id=subnet_id, dry_run=True
|
||||||
)
|
)
|
||||||
ex.exception.reason.should.equal('DryRunOperation')
|
ex.exception.reason.should.equal('DryRunOperation')
|
||||||
ex.exception.status.should.equal(400)
|
ex.exception.status.should.equal(400)
|
||||||
@ -42,7 +48,7 @@ def test_request_spot_instances():
|
|||||||
security_groups=['group1', 'group2'], user_data=b"some test data",
|
security_groups=['group1', 'group2'], user_data=b"some test data",
|
||||||
instance_type='m1.small', placement='us-east-1c',
|
instance_type='m1.small', placement='us-east-1c',
|
||||||
kernel_id="test-kernel", ramdisk_id="test-ramdisk",
|
kernel_id="test-kernel", ramdisk_id="test-ramdisk",
|
||||||
monitoring_enabled=True, subnet_id="subnet123",
|
monitoring_enabled=True, subnet_id=subnet_id,
|
||||||
)
|
)
|
||||||
|
|
||||||
requests = conn.get_all_spot_instance_requests()
|
requests = conn.get_all_spot_instance_requests()
|
||||||
@ -64,7 +70,7 @@ def test_request_spot_instances():
|
|||||||
request.launch_specification.placement.should.equal('us-east-1c')
|
request.launch_specification.placement.should.equal('us-east-1c')
|
||||||
request.launch_specification.kernel.should.equal("test-kernel")
|
request.launch_specification.kernel.should.equal("test-kernel")
|
||||||
request.launch_specification.ramdisk.should.equal("test-ramdisk")
|
request.launch_specification.ramdisk.should.equal("test-ramdisk")
|
||||||
request.launch_specification.subnet_id.should.equal("subnet123")
|
request.launch_specification.subnet_id.should.equal(subnet_id)
|
||||||
|
|
||||||
|
|
||||||
@mock_ec2
|
@mock_ec2
|
||||||
|
Loading…
Reference in New Issue
Block a user