Пример #1
0
def upload_binary_to_custom_s3_bucket(botname, filepath, zipfile, bucket):
    ''' Uploads a binary and source directory to a custom S3 bucket. '''
    s3_client = boto3.client('s3', **CUSTOM_AWS_CREDS)

    binary_obj = botname
    if zipfile is not None:
        zip_obj = '{}-src.zip'.format(botname)

    try:
        s3_client.upload_file(filepath,
                              bucket,
                              binary_obj,
                              ExtraArgs={'ACL': 'public-read'})
        if zipfile is not None:
            s3_client.upload_file(zipfile,
                                  bucket,
                                  zip_obj,
                                  ExtraArgs={'ACL': 'public-read'})
    except ClientError as e:
        error('Uploading binary and source to custom S3 failed.')
        print(e)
        exit(1)

    if zipfile is not None:
        info('Uploaded source `{}` and binary `{}` successfully!'.format(
            zip_obj, binary_obj))
    else:
        info('Uploaded binary `{}` successfully!'.format(binary_obj))
Пример #2
0
def check_player_in_db(name):
    resp = requests.post(PLAYER_REPO_SERVER + '/check', data={'name': name})
    if resp.text == 'exists':
        error('A bot named `{}` already exists!'.format(name))
        exit(1)
    elif resp.text == 'bad request':
        error('A malformed request was made')
        exit(1)
Пример #3
0
def get_user():
    try:
        athena_user = str(getpass.getuser())
    except Exception as e:
        error('Could not get student username.')
        print(e)
        exit(1)

    info('Found username `{}`.'.format(athena_user))

    return athena_user
Пример #4
0
def add_player_to_db(name, official_name, desc):
    data = {'name': name, 'official_name': official_name, 'desc': desc}
    resp = requests.post(PLAYER_REPO_SERVER + '/add', data=data)
    resp_json = json.loads(resp.text)
    if 'error' in resp_json:
        err = resp_json['error']
        error('Failed to add player `{}` to our custom database: {}'.format(
            name, err))
        exit(1)
    else:
        info(resp.text)
Пример #5
0
def test_6172_s3_bucket_valid():
    # Test for bucket existence.
    s3 = boto3.resource('s3')
    bucket = s3.Bucket(STUDENT_BUCKET)

    try:
        s3.meta.client.head_bucket(Bucket=STUDENT_BUCKET)
    except botocore.exceptions.ClientError as e:
        error_code = int(e.response['Error']['Code'])

        if error_code == 404:
            error(
                'Amazon S3 Bucket `{}` does not exist.'.format(STUDENT_BUCKET))
        else:
            error('Could not get Amazon S3 bucket.')
            print(e)
            exit(1)

    info('Using bucket `{}`.'.format(STUDENT_BUCKET))
Пример #6
0
def main(binary, srcpath, botname, botdesc):
    ALLOWED_CHARS = set(
        '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_')
    if not all(c in ALLOWED_CHARS for c in botname):
        error(
            'Bot name must only contain alphanumeric characters or the underscore.'
        )
        exit(1)

    if not os.path.isfile(binary):
        error('`{}` is not a file.'.format(binary))
        exit(1)

    if srcpath is not None and not os.path.isdir(srcpath):
        error('`{}` is not a directory.'.format(srcpath))
        exit(1)

    check_player_in_db(botname)

    if srcpath is None:
        info('No source directory has been provided. '
             'Are you sure you want to upload a binary '
             'without the corresponding source?')
        if input('(y / n)').lower() != 'y':
            info('User canceled upload operation.')
            exit(1)

    zip_path = None
    if srcpath is not None:
        zip_path = zip_source_code(srcpath)
        info('Zipped source code at `{}` to `{}`.'.format(srcpath, zip_path))

    athena_user, iam_user = get_user()
    official_name = '{}.{}'.format(athena_user, botname)

    info('Bot official_name is `{}`.'.format(official_name))

    # Upload binary to custom bucket
    upload_binary_to_custom_s3_bucket(botname, binary, zip_path,
                                      CUSTOM_S3_BUCKET)

    # Upload binary to 6.172 S3 bucket
    test_6172_s3_bucket_valid()
    upload_binary_to_6172_s3_bucket(botname, binary, iam_user, athena_user)

    # Register bot with custom database
    add_player_to_db(botname, official_name, botdesc)
Пример #7
0
def upload_binary_to_6172_s3_bucket(botname, binary, iam_user, athena_user):
    ''' Uploads a binary to the student bucket. '''

    s3_client = boto3.client('s3')
    upload_key = '/'.join(
        [OBJECT_KEY_PREFIX, iam_user, OBJECT_KEY_BINARIES, botname])

    info('Uploading bot `{}` located at path '
         '`{}` to ~/s3home/{}/{} on instance.'.format(
             botname,
             binary,
             OBJECT_KEY_BINARIES,
             botname,
         ))

    try:
        s3_client.upload_file(binary,
                              STUDENT_BUCKET,
                              upload_key,
                              ExtraArgs={'ACL': 'bucket-owner-full-control'})
    except Exception as e:
        error('Was not able to upload bot to the Amazon S3 bucket.')
        print(e)
        exit(1)

    # Register the binary with the server.
    info('Registering bot `{}` with server...'.format(botname))

    endpoint = 'http://{}/upload/{}/{}'.format(REG_SERVER, botname,
                                               athena_user)
    try:
        resp = requests.get(endpoint)
    except Exception as e:
        error('Cannot contact registration server `{}`.'.format(REG_SERVER))
        print(e)
        exit(1)

    if len(resp.text) > 0:
        error('Server error: {}'.format(resp.text))
        exit(1)
    else:
        info('Registration success!')
Пример #8
0
def round_robin(players, time_control, round_robin_rounds, username):
    # Get the list of uploaded binaries
    pipe = subprocess.Popen(['autotest-list', '10000'],
                            stdout=subprocess.PIPE,
                            universal_newlines=True)
    staff_binaries = set(['reference', 'reference_plusplus'])
    binaries = set()

    output = pipe.communicate()[0]
    for line in output.split('\n'):
        player = line.split(' ')[0]

        if player.startswith(username):
            binaries.add(player)

    all_binaries = staff_binaries.union(binaries)

    info(
        'All available competitors (add #<number> to multiply total time, e.g. reference*4 has 4x time): '
    )
    for binary in binaries:
        info('* {}'.format(binary))

    for i in range(0, len(players)):
        if players[i] not in staff_binaries and not players[i].startswith(
                username):
            players[i] = '{}.{}'.format(username, players[i])

    for p in players:
        base_p, _ = parse_player_name(p)
        if base_p not in all_binaries:
            error('Bot `{}` has not been uploaded to the 6.172 server.'.format(
                p))
            exit(1)

    # No need to modify anything below this line.
    autotest_filename = '/tmp/tmp.6172_autotest-{}'.format(uuid.uuid4())
    with open(autotest_filename, 'w') as f:
        f.write('***Manual Game List***\n')
        f.write('{}.\n'.format(username))

        tc_inc = TIME_CONTROL_MAP[time_control]['tc_inc']
        tc_pool = TIME_CONTROL_MAP[time_control]['tc_pool']

        # Schedule round robin rounds
        for i in range(round_robin_rounds):
            for p1 in players:
                for p2 in players:
                    # Set up time multipliers.
                    p1_base, p1_mul = parse_player_name(p1)
                    p2_base, p2_mul = parse_player_name(p2)

                    if p1_base == p2_base:
                        continue

                    game_str = '{} {} {} {} true {} {}'.format(
                        p1_base, p2_base,
                        int(tc_pool * p1_mul), tc_inc * p1_mul,
                        int(tc_pool * p2_mul), tc_inc * p2_mul)

                    info('Queuing game: {}'.format(game_str))
                    f.write('{}\n'.format(game_str))

    subprocess.call(['autotest-lowlevelrun', autotest_filename])