Beispiel #1
0
def extend_autostop(uuid):
    """Extend the autostop timer."""
    if not re_uuid.match(uuid):
        abort(400)
    cursor = get_cursor()
    cursor.execute('SELECT * FROM trials WHERE id = %s', (uuid,))
    row = cursor.fetchone()
    if not row:
        abort(404)
    trial = rowdict(row, cursor.description)
    trial_cfg = cfgdict(app.config, trial['trial_name'])
    autostop = trial_cfg.get('autostop')
    if not autostop:
        abort(400)
    client = get_ravello_client(trial['trial_name'])
    application = client.get_application(trial['application_id'])
    exp_req = {'expirationFromNowSeconds': autostop*3600}
    client.set_application_expiration(application, exp_req)
    state = application_state(application)
    if state == 'STOPPED':
        client.start_application(application)
    elif state not in ('STARTING', 'STARTED'):
        abort(400)
    utcnow = datetime.utcnow().replace(tzinfo=pytz.UTC)
    trial['autostop_at'] = utcnow + timedelta(seconds=autostop*3600)
    fields = qset('autostop_at')
    cursor.execute('UPDATE trials set {0} WHERE id = %(id)s'.format(fields), trial)
    response = make_response()
    response.status_code = 204  # No content
    return response
Beispiel #2
0
def get_trial_dyn(uuid):
    """Get trial dynamic metadata."""
    if not re_uuid.match(uuid):
        abort(400)
    cursor = get_cursor()
    cursor.execute('SELECT * FROM trials WHERE id = %s', (uuid,))
    row = cursor.fetchone()
    if not row:
        abort(404)
    trial = rowdict(row, cursor.description)
    meta = {'id': trial['id'], 'status': trial['status']}
    utcnow = datetime.utcnow().replace(tzinfo=pytz.UTC)
    meta['expires_in'] = format_interval(trial['expires_at'] - utcnow)
    if trial['autostop_at']:
        meta['autostop_in'] = format_interval(trial['autostop_at'] - utcnow)
    if trial['status'] != 'READY':
        return jsonify(meta)
    client = get_ravello_client(trial['trial_name'])
    app = client.get_application(trial['application_id'])
    deploy = app.get('deployment', {})
    meta['cloud'] = deploy.get('cloud')
    meta['region'] = deploy.get('regionName')
    state = application_state(app)
    if isinstance(state, list):
        if 'STARTING' in state:
            state = 'STARTING'
        elif 'STOPPING' in state:
            state = 'STOPPING'
        else:
            state = 'UNKNOWN'
    meta['status'] = state
    addr = get_service_addr(app, 'ssh')
    if addr:
        meta['ssh_addr'] = addr[0]
    addr = get_service_addr(app, 'http')
    if addr:
        meta['http_url'] = 'http://{2}:{1}/'.format(*addr)
    return jsonify(meta)
Beispiel #3
0
def complete_create_trial(uuid):
    """Complete the creation of a trial."""
    conn = connect_database()
    cursor = conn.cursor()
    cursor.execute('SELECT * FROM trials WHERE id = %s', (uuid,))
    row = cursor.fetchone()
    if row is None:
        raise ValueError('trial {!r} does not exist'.format(uuid))
    trial = rowdict(row, cursor.description)
    trial_cfg = cfgdict(app.config, trial['trial_name'])
    trial['ssh_private_key'], trial['ssh_public_key'] = generate_keypair()
    ravello = connect_ravello(trial['trial_name'])
    blueprint_id = trial_cfg['blueprint']
    description = 'Trial ({0}/{1})'.format(trial['trial_name'], filter_ascii(trial['name']))
    application = {'name': 'trial-{0}'.format(uuid),
                   'description': description,
                   'baseBlueprintId': blueprint_id}
    application = ravello.create_application(application)
    trial['application_id'] = application['id']
    # If cloudinit is available, we can use that to deploy the ssh key.
    cloudinit = trial_cfg['cloudinit']
    if cloudinit:
        pubkey = {'name': 'trial-{0}'.format(uuid),
                  'publicKey': trial['ssh_public_key']}
        pubkey = ravello.create_keypair(pubkey)
        for vm in application.get('design', {}).get('vms', []):
            vm['keypairId'] = pubkey['id']
        application = ravello.update_application(application)
    autostop = trial_cfg.get('autostop')
    if autostop:
        exp_req = {'expirationFromNowSeconds': autostop*3600}
        ravello.set_application_expiration(application, exp_req)
        nowutc = datetime.utcnow().replace(tzinfo=pytz.UTC)
        trial['autostop_at'] = nowutc + timedelta(seconds=autostop*3600)
    else:
        trial['autostop_at'] = None
    publish_cfg = cfgdict(app.config, '{0}_publish'.format(trial['trial_name']), 'publish')
    publish_req = {'preferredCloud': publish_cfg.get('cloud'),
                   'preferredRegion': publish_cfg.get('region'),
                   'optimizationLevel':  publish_cfg.get('optimization'),
                   'startAllVms': True}
    publish_req = dict(((k,v) for k,v in publish_req.items() if v is not None))
    ravello.publish_application(application['id'], publish_req)
    trial['status'] = 'BUILDING'
    fields = qset('ssh_private_key', 'ssh_public_key', 'application_id',
                  'status', 'autostop_at')
    cursor.execute('UPDATE trials set {0} WHERE id = %(id)s'.format(fields), trial)
    conn.commit()
    # At this point send the email.
    send_email(trial['email'], 'registered.txt', trial)
    # Wait for the application to come up
    ravello.wait_for(application, lambda app: application_state(app) == 'STARTED', 900)
    # Wait for ssh to come up.
    application = ravello.reload(application)
    ssh_addr = get_service_addr(application, 'ssh')
    ssh_timeout = trial_cfg.get('ssh_timeout', 300)
    if not wait_for_service(ssh_addr[:2], ssh_timeout):
        raise RuntimeError('error waiting for ssh service')
    privkey = trial_cfg.get('ssh_key')
    if not cloudinit and privkey:
        ssh = connect_ssh(ssh_addr[:2], privkey, 'root')
        pubkey = trial['ssh_public_key'].rstrip()
        ssh.communicate(textwrap.dedent("""\
                cat >> .ssh/authorized_keys << EOM 
                {0}
                EOM
                chmod 600 .ssh/authorized_keys
                """).format(pubkey).encode('ascii'))
        ssh.wait()
        if ssh.returncode != 0:
            raise RuntimeError('error deploying ssh key through ssh')
    # Optionally wait for another service
    service = trial_cfg.get('service')
    if service:
        svc_addr = get_service_addr(application, service)
        svc_timeout = trial_cfg.get('service_timeout', 300)
        if not wait_for_service(svc_addr[:2], svc_timeout):
            raise RuntimeError('error waiting for {!r} service'.format(service))
    # Do we need to reboot?
    reboot = trial_cfg.get('reboot')
    if reboot:
        time.sleep(trial_cfg.get('reboot_delay', 60))
        ssh = connect_ssh(ssh_addr[:2], privkey, 'root')
        ssh.communicate('shutdown -r now'.encode('ascii'))
        ssh.wait()
        time.sleep(trial_cfg.get('reboot_timeout', 30))
        if not wait_for_service(ssh_addr[:2], ssh_timeout):
            raise RuntimeError('ssh did not come up after reboot')
        # Wait again for the service..
        if service and not wait_for_service(svc_addr[:2], svc_timeout):
            raise RuntimeError('error waiting for {!r} service'.format(service))
    # Mark as READY!
    time.sleep(trial_cfg.get('final_delay', 0))
    trial['status'] = 'READY'
    fields = qset('status')
    cursor.execute('UPDATE trials SET {0} WHERE id = %(id)s'.format(fields), trial)
    conn.commit()
    cursor.close()
    conn.close()