Richard Liu 6 years ago
commit d7a15cc9d2
  1. 143
      aws-experiment-launch/deploy.py
  2. 44
      aws-experiment-launch/utils/utils.py

@ -1,12 +1,14 @@
import boto3
import argparse
import sys
import base64
import boto3
import datetime
import json
import os
import sys
import time
import datetime
from threading import Thread
from Queue import Queue
import base64
from threading import Thread
from utils import utils
@ -30,25 +32,10 @@ CURRENT_SESSION = datetime.datetime.fromtimestamp(
PLACEMENT_GROUP = "PLACEMENT-" + CURRENT_SESSION
NODE_NAME_SUFFIX = "NODE-" + CURRENT_SESSION
def run_one_region_codedeploy(region_number, commit_id):
#todo: explore the use ec2 resource and not client. e.g. create_instances -- Might make for better code.
"""
for getting instance ids:---
ec2 = boto3.resource('ec2', region_name=region_name])
result = ec2.instances.filter(Filters=[{'Name': 'instance-state-name', 'Values': ['running']}])
for instance in result:
instances.append(instance.id)
for getting public ips : --
ec2 = boto3.resource('ec2')
instance
"""
region_name = config[region_number][REGION_NAME]
NODE_NAME = region_number + "-" + NODE_NAME_SUFFIX
session = boto3.Session(region_name=region_name)
ec2_client = session.client('ec2')
filters = [{'Name': 'tag:Name','Values': [NODE_NAME]}]
instance_ids = get_instance_ids(ec2_client.describe_instances(Filters=filters))
def run_one_region_codedeploy(region_number, region_config, node_name_tag, commit_id):
ec2_client, session = utils.create_ec2_client(region_number, region_config)
filters = [{'Name': 'tag:Name','Values': [node_name_tag]}]
instance_ids = utils.get_instance_ids(ec2_client.describe_instances(Filters=filters))
print("Number of instances: %d" % len(instance_ids))
@ -66,50 +53,15 @@ def run_one_region_codedeploy(region_number, commit_id):
codedeploy = session.client('codedeploy')
application_name = APPLICATION_NAME
deployment_group = APPLICATION_NAME + "-" + str(commit_id)[6] + "-" + CURRENT_SESSION
deployment_group = APPLICATION_NAME + "-" + commit_id[:6] + "-" + CURRENT_SESSION
repo = REPO
print("Setting up to deploy commit_id %s on region %s"%(commit_id,region_number))
response = get_application(codedeploy, application_name)
deployment_group = get_deployment_group(
codedeploy, region_number, application_name, deployment_group)
depId = deploy(codedeploy, application_name,
deployment_group, repo, commit_id)
return region_number, depId
def get_deployment_group(codedeploy, region_number,application_name, deployment_group):
NODE_NAME = region_number + "-" + NODE_NAME_SUFFIX
response = codedeploy.create_deployment_group(
applicationName=application_name,
deploymentGroupName=deployment_group,
deploymentConfigName='CodeDeployDefault.AllAtOnce',
serviceRoleArn='arn:aws:iam::656503231766:role/BenchMarkCodeDeployServiceRole',
deploymentStyle={
'deploymentType': 'IN_PLACE',
'deploymentOption': 'WITHOUT_TRAFFIC_CONTROL'
},
ec2TagFilters = [
{
'Key': 'Name',
'Value': NODE_NAME,
'Type': 'KEY_AND_VALUE'
}
]
)
return deployment_group
def get_application(codedeploy, application_name):
response = codedeploy.list_applications()
if application_name in response['applications']:
return response
else:
response = codedeploy.create_application(
applicationName=application_name,
computePlatform='Server'
)
return response
print("Setting up to deploy commit_id %s on region %s" % (commit_id, region_number))
utils.get_application(codedeploy, application_name)
deployment_group = utils.create_deployment_group(
codedeploy, region_number, application_name, deployment_group, node_name_tag)
deployment_id = deploy(codedeploy, application_name, deployment_group, repo, commit_id)
return region_number, deployment_id
def deploy(codedeploy, application_name, deployment_group, repo, commit_id):
@ -130,39 +82,39 @@ def deploy(codedeploy, application_name, deployment_group, repo, commit_id):
'revisionType': 'GitHub',
'gitHubLocation': {
'repository': repo,
'commit_id': commit_id,
'commitId': commit_id,
}
}
)
depId = res["deploymentId"]
print("Deployment ID: " + depId)
deployment_id = res["deploymentId"]
print("Deployment ID: " + deployment_id)
# The deployment is launched at this point, so exit unless asked to wait
# until it finishes
info = {'status': 'Created'}
start = time.time()
while info['status'] not in ('Succeeded', 'Failed', 'Stopped',) and (time.time() - start < 600.0):
info = codedeploy.get_deployment(deploymentId=depId)['deploymentInfo']
info = codedeploy.get_deployment(deploymentId=deployment_id)['deploymentInfo']
print(info['status'])
time.sleep(15)
if info['status'] == 'Succeeded':
print("\nDeploy Succeeded")
return depId
else:
print("\nDeploy Failed")
print(info)
return depId
return deployment_id
def run_one_region_codedeploy_wrapper(region_number, commit_id, queue):
region_number, depId = run_one_region_codedeploy(region_number, commit_id)
queue.put((region_number, depId))
def run_one_region_codedeploy_wrapper(region_number, region_config, node_name_tag, commit_id, queue):
region_number, deployment_id = run_one_region_codedeploy(region_number, region_config, node_name_tag, commit_id)
queue.put((region_number, deployment_id))
def launch_code_deploy(region_list, commit_id):
def launch_code_deploy(region_list, region_config, commit_id):
queue = Queue()
jobs = []
for i in range(len(region_list)):
region_number = region_list[i]
for region_tuppple in region_list:
# node_name_tag comes first.
node_name_tag, region_number = region_tuppple
my_thread = Thread(target=run_one_region_codedeploy_wrapper, args=(
region_number, commit_id, queue))
region_number, region_config, node_name_tag, commit_id, queue))
my_thread.start()
jobs.append(my_thread)
for my_thread in jobs:
@ -170,31 +122,24 @@ def launch_code_deploy(region_list, commit_id):
results = [queue.get() for job in jobs]
return results
def get_instance_ids(describe_instances_response):
instance_ids = []
for reservation in describe_instances_response["Reservations"]:
for instance in reservation["Instances"]:
instance_ids.append(instance["InstanceId"])
return instance_ids
if __name__ == "__main__":
parser = argparse.ArgumentParser(
description='This script helps you start instances across multiple regions')
parser.add_argument('--regions', type=str, dest='regions',
default='3', help="Supply a csv list of all regions")
parser.add_argument('--instances', type=str, dest='numInstances',
default='1', help='number of instances')
parser.add_argument('--configuration', type=str,
dest='config', default='configuration.txt')
parser.add_argument('--instance_output', type=str, dest='instance_output',
default='instance_output.txt',
help='the file contains node_name_tag and region number of created instances.')
parser.add_argument('--region_config', type=str, dest='region_config', default='configuration.txt')
parser.add_argument('--commit_id', type=str, dest='commit_id',
default='1f7e6e7ca7cf1c1190cedec10e791c01a29971cf')
args = parser.parse_args()
config = utils.read_region_config(args.config)
region_list = [item.strip() for item in args.regions.split(',')]
instances_list = [item.strip() for item in args.numInstances.split(',')]
assert len(region_list) == len(instances_list), "number of regions: %d != number of instances per region: %d" % (
len(region_list), len(instances_list))
commit_id = args.commit_id
results = launch_code_deploy(region_list, commit_id)
print(results)
if not os.path.isfile(args.instance_output) or not commit_id:
print "%s does not exist" % args.instance_output
sys.exit(1)
with open(args.instance_output, "r") as fin:
region_list = [line.split(" ") for line in fin.readlines()]
region_list = [(item[0].strip(), item[1].strip()) for item in region_list]
results = launch_code_deploy(region_list, args.region_config, commit_id)
print(results)

@ -36,7 +36,7 @@ def create_ec2_client(region_number, region_config):
config = read_region_config(region_config)
region_name = config[region_number][REGION_NAME]
session = boto3.Session(region_name=region_name)
return session.client('ec2')
return session.client('ec2'), session
def collect_public_ips_from_ec2_client(ec2_client, node_name_tag):
filters = [{'Name': 'tag:Name','Values': [node_name_tag]}]
@ -48,10 +48,42 @@ def collect_public_ips_from_ec2_client(ec2_client, node_name_tag):
return ip_list
def collect_public_ips(region_number, node_name_tag, region_config):
ec2_client = create_ec2_client(region_number, region_config)
ec2_client, _ = create_ec2_client(region_number, region_config)
ip_list = collect_public_ips_from_ec2_client(ec2_client, node_name_tag)
return ip_list
def get_application(codedeploy, application_name):
response = codedeploy.list_applications()
if application_name in response['applications']:
return response
else:
response = codedeploy.create_application(
applicationName=application_name,
computePlatform='Server'
)
return response
def create_deployment_group(codedeploy, region_number,application_name, deployment_group, node_name_tag):
_ = codedeploy.create_deployment_group(
applicationName=application_name,
deploymentGroupName=deployment_group,
deploymentConfigName='CodeDeployDefault.AllAtOnce',
serviceRoleArn='arn:aws:iam::656503231766:role/BenchMarkCodeDeployServiceRole',
deploymentStyle={
'deploymentType': 'IN_PLACE',
'deploymentOption': 'WITHOUT_TRAFFIC_CONTROL'
},
ec2TagFilters = [
{
'Key': 'Name',
'Value': node_name_tag,
'Type': 'KEY_AND_VALUE'
}
]
)
# Checking??
return deployment_group
def generate_distribution_config2(region_number, node_name_tag, region_config,
shard_number, client_number, distribution_config):
ip_list = collect_public_ips(region_number, node_name_tag, region_config)
@ -96,6 +128,14 @@ def get_one_availability_zone(ec2_client):
else:
return None
# Get instance_ids from describe_instances_response.
def get_instance_ids(describe_instances_response):
instance_ids = []
if describe_instances_response["Reservations"]:
for reservation in describe_instances_response["Reservations"]:
instance_ids.extend(instance["InstanceId"] for instance in reservation["Instances"] if instance.get("InstanceId"))
return instance_ids
# used for testing only.
# if __name__ == "__main__":
# ip_list = collect_public_ips('4', "4-NODE-23-36-01-2018-07-05", "configuration.txt")

Loading…
Cancel
Save