From 030bc7c23d74dc6063768d8a5333448ef5f3fcf1 Mon Sep 17 00:00:00 2001 From: Sandon Van Ness Date: Tue, 5 Feb 2013 12:53:08 -0800 Subject: [PATCH] Added support for multiple types of machines. Added the ability to support multiple types of machines with --machine-type added to teuthology-lock when used with --lock-many or --machine-type with teuthology --lock (automated tests). It defaults to 'plana' and the 'vps' type is currently unused but should be in the future. Signed-off-by: Sandon Van Ness Reviewed-by: Josh Durgin --- teuthology/lock.py | 11 ++++++++--- teuthology/locker/api.py | 5 +++-- teuthology/locker/config.py | 1 + teuthology/run.py | 13 +++++++++++-- teuthology/task/internal.py | 11 +++++++---- 5 files changed, 30 insertions(+), 11 deletions(-) diff --git a/teuthology/lock.py b/teuthology/lock.py index e9f8312718..0163c02008 100644 --- a/teuthology/lock.py +++ b/teuthology/lock.py @@ -24,11 +24,11 @@ def send_request(method, url, body=None, headers=None): method, url, body, resp.status) return (False, None, resp.status) -def lock_many(ctx, num, user=None, description=None): +def lock_many(ctx, num, machinetype, user=None, description=None): if user is None: user = teuthology.get_user() success, content, status = send_request('POST', _lock_url(ctx), - urllib.urlencode(dict(user=user, num=num))) + urllib.urlencode(dict(user=user, num=num, machinetype=machinetype))) if success: machines = json.loads(content) log.debug('locked {machines}'.format(machines=', '.join(machines.keys()))) @@ -180,6 +180,11 @@ Lock, unlock, or query lock status of machines. default=None, help='update description', ) + parser.add_argument( + '--machine-type', + default='plana', + help='Type of machine to lock', + ) parser.add_argument( '--status', default=None, @@ -322,7 +327,7 @@ Lock, unlock, or query lock status of machines. else: machines_to_update.append(machine) elif ctx.num_to_lock: - result = lock_many(ctx, ctx.num_to_lock, user) + result = lock_many(ctx, ctx.num_to_lock, ctx.machine_type, user) if not result: ret = 1 else: diff --git a/teuthology/locker/api.py b/teuthology/locker/api.py index 881e718594..4eac75b913 100644 --- a/teuthology/locker/api.py +++ b/teuthology/locker/api.py @@ -75,6 +75,7 @@ class Lock: def POST(self): user = web.input('user')['user'] num = int(web.input('num')['num']) + machinetype = dict(machinetype=(web.input(machinetype='plana')['machinetype'])) if num < 1: raise web.BadRequest() @@ -84,8 +85,8 @@ class Lock: try: # transaction will be rolled back if an exception is raised with DB.transaction(): - results = list(DB.select('machine', what='name, sshpubkey', - where='locked = false AND up = true', + results = list(DB.select('machine', machinetype, what='name, sshpubkey', + where='locked = false AND up = true AND type =$machinetype', limit=num)) if len(results) < num: raise web.HTTPError(status='503 Service Unavailable') diff --git a/teuthology/locker/config.py b/teuthology/locker/config.py index 17453a2d95..090e8a0b0f 100644 --- a/teuthology/locker/config.py +++ b/teuthology/locker/config.py @@ -5,6 +5,7 @@ The schema can be created with:: CREATE TABLE machine ( name varchar(255), + type enum('burnupi','plana','vps') NOT NULL DEFAULT 'plana', up boolean NOT NULL, locked boolean NOT NULL, locked_since timestamp NOT NULL DEFAULT '0000-00-00T00:00:00', diff --git a/teuthology/run.py b/teuthology/run.py index 6136b091ea..d9f3ea278f 100644 --- a/teuthology/run.py +++ b/teuthology/run.py @@ -55,6 +55,11 @@ def parse_args(): default=False, help='lock machines for the duration of the run', ) + parser.add_argument( + '--machine-type', + default=None, + help='Type of machine to lock/run tests on.', + ) parser.add_argument( '--block', action='store_true', @@ -93,7 +98,11 @@ def main(): roles = len(ctx.config['roles']) assert targets >= roles, \ '%d targets are needed for all roles but found %d listed.' % (roles, targets) - + + machine_type = ctx.machine_type + if machine_type is None: + machine_type = ctx.config.get('machine_type', 'plana') + if ctx.block: assert ctx.lock, \ 'the --block option is only supported with the --lock option' @@ -143,7 +152,7 @@ def main(): if ctx.lock: assert 'targets' not in ctx.config, \ 'You cannot specify targets in a config file when using the --lock option' - init_tasks.append({'internal.lock_machines': len(ctx.config['roles'])}) + init_tasks.append({'internal.lock_machines': (len(ctx.config['roles']), machine_type)}) init_tasks.extend([ {'internal.save_config': None}, diff --git a/teuthology/task/internal.py b/teuthology/task/internal.py index 0503eb1347..cbbb87c48c 100644 --- a/teuthology/task/internal.py +++ b/teuthology/task/internal.py @@ -60,7 +60,9 @@ def base(ctx, config): @contextlib.contextmanager def lock_machines(ctx, config): log.info('Locking machines...') - assert isinstance(config, int), 'config must be an integer' + assert isinstance(config[0], int), 'config must be an integer' + machine_type = config[1] + config = config[0] while True: # make sure there are enough machines up @@ -72,12 +74,13 @@ def lock_machines(ctx, config): continue else: assert 0, 'error listing machines' - num_up = len(filter(lambda machine: machine['up'], machines)) + num_up = len(filter(lambda machine: machine['up'] and machine['type'] == machine_type, machines)) + print num_up assert num_up >= config, 'not enough machines are up' # make sure there are machines for non-automated jobs to run num_free = len(filter( - lambda machine: machine['up'] and machine['locked'] == 0, + lambda machine: machine['up'] and machine['locked'] == 0 and machine['type'] == machine_type, machines )) if num_free < 6 and ctx.owner.startswith('scheduled'): @@ -88,7 +91,7 @@ def lock_machines(ctx, config): else: assert 0, 'not enough machines free' - newly_locked = lock.lock_many(ctx, config, ctx.owner, ctx.archive) + newly_locked = lock.lock_many(ctx, config, machine_type, ctx.owner, ctx.archive) if len(newly_locked) == config: ctx.config['targets'] = newly_locked log.info('\n '.join(['Locked targets:', ] + yaml.safe_dump(ctx.config['targets'], default_flow_style=False).splitlines())) -- 2.39.5