def _send_results_to_cloud(filename, slack_webhook_url): ''' Send JSON results to the moon. ''' with open(filename) as file: results = [json.loads(line) for line in file] headers = {'Content-Type': 'application/json'} # The first and last lines have the start and end times. commit = subprocess.check_output('git rev-parse HEAD'.split()).decode('utf-8')[:12] output = dict(results=results[1:-1], commit=commit) output.update(results[0]) output.update(results[-1]) string = json.dumps(output, indent=2) connection = connect_s3(fabconf.get('AWS_ACCESS_KEY'), fabconf.get('AWS_SECRET_KEY')) for key_name in ('acceptance-test-nights.json', 'acceptance-test-nights-{:.0f}.json'.format(time.time())): key = connection.get_bucket('chimecms-test-results').new_key(key_name) key.set_contents_from_string(string, policy='public-read', headers=headers) url = key.generate_url(expires_in=0, query_auth=False, force_http=True) print('Uploaded to', url) if slack_webhook_url: _send_results_to_slack(output, slack_webhook_url)
def _connect_to_ec2(): ''' Returns a boto connection object ''' from fabconf import fabconf print(yellow('Connecting to EC2...')) conn = boto.ec2.connect_to_region( fabconf.get('EC2_REGION'), aws_access_key_id=fabconf.get('AWS_ACCESS_KEY'), aws_secret_access_key=fabconf.get('AWS_SECRET_KEY') ) return conn
def test_chime(setup=True, despawn=True, despawn_on_failure=False): ''' Create a chime instance and run selenium tests. Takes two optional params: setup, and despawn. When setup is True, it will set up the server to work with Chime. When despawn is True, it will terminate the instance after running the tests. Accepted values for setup/despawn to be considered True are 'True', 't', 'true', and 'y'. Using any other value will either not run the setup scripts or keep the instance alive, respectively. Additionally, the branch that should be tested can be specified with the branch argument ''' from fabconf import fabconf env.user = fabconf.get('SERVER_USERNAME') env.key_filename = fabconf.get('SSH_PRIVATE_KEY_PATH') public_dns = _find_or_make_a_host() if _looks_true(setup): _server_setup(public_dns) print(green('Running tests...')) time.sleep(2) handle, output_filename = tempfile.mkstemp(prefix='tests-', suffix='.txt') os.environ['OUTPUT_FILE'] = output_filename os.close(handle) print('Saving output to', output_filename) try: with open(output_filename, 'w') as output: print(json.dumps(dict(start=time.time())), file=output) local('nosetests --processes=9 --process-timeout=300 ' + fabconf.get('FAB_CONFIG_PATH') + '/../test/acceptance') with open(output_filename, 'a') as output: print(json.dumps(dict(ok=True, end=time.time())), file=output) if _looks_true(despawn): _despawn(public_dns) except: with open(output_filename, 'a') as output: print(json.dumps(dict(ok=False, end=time.time())), file=output) if _looks_true(despawn_on_failure): _despawn(public_dns) raise finally: if _looks_true(os.environ.get('REPORT_TO_S3')): _send_results_to_cloud(output_filename, os.environ.get('SLACK_URL'))
def _load_hosts(): hostfile = fabconf.get('FAB_HOSTS_FILE') try: with open(hostfile, 'r') as f: hosts = f.read().split(',') return [h.strip() for h in hosts if h != ''] except IOError: return []
def spawn_instance(): ''' Creates a new EC2 instance and stores the resulting DNS in a hosts.txt file. ''' print(green('Spawning new instance...')) env.key_filename = fabconf.get('SSH_PRIVATE_KEY_PATH') env.host_string = _create_ec2_instance()
def redeploy(): env.user = fabconf.get('SERVER_USERNAME') _find_host() _server_setup() rsync_code() print(green("restarting chime")) sudo('service chime restart') print(green("done"))
def rsync_code(hostname=None): if not hostname: hostname = server_host() env.host_string = hostname env.user = fabconf.get('SERVER_USERNAME') print("going for user " + env.user) rsync_project(remote_dir='.', default_opts='-pthrz', ssh_opts='-o CheckHostIP=no -o UserKnownHostsFile=/dev/null -o StrictHostkeyChecking=no')
def despawn_instance(public_dns=None): ''' Destroys an EC2 instance. ''' if public_dns is None: public_dns = server_host() env.key_filename = fabconf.get('SSH_PRIVATE_KEY_PATH') print(yellow('Shutting down instance {dns}'.format(dns=public_dns))) _despawn_instance(public_dns, terminate=True)
def despawn_instance(public_dns=None): ''' Destroys an EC2 instance. ''' if public_dns is None: public_dns = server_host() env.key_filename = fabconf.get('SSH_PRIVATE_KEY_PATH') print(yellow('Shutting down instance {dns}'.format( dns=public_dns ))) _despawn_instance(public_dns, terminate=True)
def rsync_code(hostname=None): if not hostname: hostname = server_host() env.host_string = hostname env.user = fabconf.get('SERVER_USERNAME') print("going for user " + env.user) rsync_project( remote_dir='.', default_opts='-pthrz', ssh_opts= '-o CheckHostIP=no -o UserKnownHostsFile=/dev/null -o StrictHostkeyChecking=no' )
def boot_chime(): ''' Installs and boots up chime. Spawns an EC2 instance if no dns is given and boots up chime on that instance. ''' from fabconf import fabconf # set some login variables env.user = fabconf.get('SERVER_USERNAME') env.key_filename = fabconf.get('SSH_PRIVATE_KEY_PATH') hosts = _load_hosts() if len(hosts) == 0: public_dns = _create_ec2_instance() print(yellow('Waiting for server to come online...')) time.sleep(10) print(yellow('Writing public DNS to host file...')) _write_host_to_file(public_dns) else: env.hosts = hosts public_dns = hosts[0] _server_setup(public_dns)
def _create_ec2_instance(): ''' Actually creates the ec2 instance ''' from fabconf import fabconf conn = _connect_to_ec2() print(yellow('Booting up instance...')) # get all images returns a list of available images image = conn.get_all_images(fabconf.get('EC2_AMIS')) # use the first available image to create a new reservation # http://docs.pythonboto.org/en/latest/ref/ec2.html#boto.ec2.instance.Reservation reservation = image[0].run( 1, 1, key_name=fabconf.get('EC2_KEY_PAIR'), security_groups=[fabconf.get('AWS_SECURITY_GROUPS')], instance_type=fabconf.get('EC2_INSTANCE_TYPE')) # reservation contains a list of instances associated with it. # we are going to tag the new instance with our conf name tag instance = reservation.instances[0] conn.create_tags([instance.id], {'Name': fabconf.get('INSTANCE_NAME_TAG')}) conn.create_tags([instance.id], {'CreatedBy': fabconf.get('INSTANCE_CREATED_BY')}) while instance.state == 'pending': print(yellow('Instance state: {state}'.format(state=instance.state))) time.sleep(10) instance.update() print(green('Instance state: {state}'.format(state=instance.state))) print(green('Public DNS: {dns}'.format(dns=instance.public_dns_name))) return instance.public_dns_name
def _create_ec2_instance(): ''' Actually creates the ec2 instance ''' from fabconf import fabconf conn = _connect_to_ec2() print(yellow('Booting up instance...')) # get all images returns a list of available images image = conn.get_all_images(fabconf.get('EC2_AMIS')) # use the first available image to create a new reservation # http://docs.pythonboto.org/en/latest/ref/ec2.html#boto.ec2.instance.Reservation reservation = image[0].run( 1, 1, key_name=fabconf.get('EC2_KEY_PAIR'), security_groups=[fabconf.get('AWS_SECURITY_GROUPS')], instance_type=fabconf.get('EC2_INSTANCE_TYPE') ) # reservation contains a list of instances associated with it. # we are going to tag the new instance with our conf name tag instance = reservation.instances[0] conn.create_tags([instance.id], {'Name': fabconf.get('INSTANCE_NAME_TAG')}) conn.create_tags([instance.id], {'CreatedBy': fabconf.get('INSTANCE_CREATED_BY')}) while instance.state == 'pending': print(yellow('Instance state: {state}'.format(state=instance.state))) time.sleep(10) instance.update() print(green('Instance state: {state}'.format(state=instance.state))) print(green('Public DNS: {dns}'.format(dns=instance.public_dns_name))) return instance.public_dns_name
def _save_hosts(hosts): with open(fabconf.get('FAB_HOSTS_FILE'), 'w') as f: f.write(",".join(hosts))