The core protocol of WoopChain
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
woop/aws-experiment-launch/utils/spot_fleet.py

119 lines
4.9 KiB

import utils
import logger
import launch_template
LOGGER = logger.getLogger(__file__)
def create_launch_specification(region_number, instanceType):
return {
# Region irrelevant fields
'IamInstanceProfile': {
'Name': utils.IAM_INSTANCE_PROFILE
},
'InstanceType': instanceType,
'UserData': utils.USER_DATA_BASE64,
# Region relevant fields
'SecurityGroups': [
{
# In certain scenarios, we have to use group id instead of group name
# https://github.com/boto/boto/issues/350#issuecomment-27359492
'GroupId': utils.CONFIG[region_number][utils.REGION_SECURITY_GROUP_ID]
}
],
'ImageId': utils.CONFIG[region_number][utils.REGION_AMI],
'KeyName': utils.CONFIG[region_number][utils.REGION_KEY],
'TagSpecifications': [
{
'ResourceType': 'instance',
'Tags': [
{
'Key': 'Name',
'Value': utils.get_node_name_tag(region_number)
}
]
}
],
# 'WeightedCapacity': 123.0,
# 'Placement': {
# # 'AvailabilityZone': get_one_availability_zone(ec2_client)
# }
}
def create_launch_specification_list(region_number, instance_type_list):
return list(map(lambda type: create_launch_specification(region_number, type), instance_type_list))
def get_launch_template(region_number, instance_type):
return {
'LaunchTemplateSpecification': {
'LaunchTemplateName': launch_template.get_launch_template_name(region_number),
'Version': '1'
},
'Overrides': [
{
'InstanceType': instance_type
}
]
}
def get_launch_template_list(region_number, instance_type_list):
return list(map(lambda type: get_launch_template(region_number, type), instance_type_list))
def request_spot_fleet(ec2_client, region_number, number_of_instances, instance_type_list):
LOGGER.info("Requesting spot fleet")
LOGGER.info("Creating node_name_tag: %s" %
utils.get_node_name_tag(region_number))
# https://boto3.readthedocs.io/en/latest/reference/services/ec2.html#EC2.Client.request_spot_fleet
response = ec2_client.request_spot_fleet(
# DryRun=True,
SpotFleetRequestConfig={
# https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/spot-fleet.html#spot-fleet-allocation-strategy
'AllocationStrategy': 'diversified',
'IamFleetRole': 'arn:aws:iam::656503231766:role/RichardFleetRole',
'LaunchSpecifications': create_launch_specification_list(region_number, instance_type_list),
# 'SpotPrice': 'string', # The maximum price per unit hour that you are willing to pay for a Spot Instance. The default is the On-Demand price.
'TargetCapacity': number_of_instances,
'Type': 'maintain'
}
)
return response["SpotFleetRequestId"]
def request_spot_fleet_with_on_demand(ec2_client, region_number, number_of_instances, number_of_on_demand, instance_type_list):
LOGGER.info("Requesting spot fleet")
LOGGER.info("Creating node_name_tag: %s" %
utils.get_node_name_tag(region_number))
# https://boto3.readthedocs.io/en/latest/reference/services/ec2.html#EC2.Client.request_spot_fleet
response = ec2_client.request_spot_fleet(
# DryRun=True,
SpotFleetRequestConfig={
# https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/spot-fleet.html#spot-fleet-allocation-strategy
'AllocationStrategy': 'diversified',
'IamFleetRole': 'arn:aws:iam::656503231766:role/RichardFleetRole',
'LaunchTemplateConfigs': get_launch_template_list(region_number, instance_type_list),
# 'SpotPrice': 'string', # The maximum price per unit hour that you are willing to pay for a Spot Instance. The default is the On-Demand price.
'TargetCapacity': number_of_instances,
'OnDemandTargetCapacity': number_of_on_demand,
'Type': 'maintain'
}
)
return response
def get_instance_ids(client, request_id):
res = client.describe_spot_fleet_instances(
SpotFleetRequestId=request_id
)
return [ inst["InstanceId"] for inst in res["ActiveInstances"] ]
def run_one_region(region_number, number_of_instances, fout, fout2):
client = utils.create_client(utils.CONFIG, region_number)
instance_type_list = ['t2.micro', 't2.small', 'm3.medium']
# node_name_tag = request_spot_fleet_with_on_demand(
# client, region_number, int(number_of_instances), 1, instance_type_list)
request_id = request_spot_fleet(
client, region_number, int(number_of_instances), instance_type_list)
instance_ids = get_instance_ids(client, request_id)
print(instance_ids) # TODO@ricl, no data here since the request is not fulfilled.