From 7e388c9f2028570ad6d85cf3eca4b2a6438f9cdb Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Mon, 30 Jun 2014 13:22:36 -0700 Subject: [PATCH] background_exec: run something in the background This is a contextmanager task that will run some command in the background for the duration of any subsequent tasks, and kill it in the cleanup phase. Signed-off-by: Sage Weil --- teuthology/task/background_exec.py | 75 ++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 teuthology/task/background_exec.py diff --git a/teuthology/task/background_exec.py b/teuthology/task/background_exec.py new file mode 100644 index 0000000000000..a5d506c544e06 --- /dev/null +++ b/teuthology/task/background_exec.py @@ -0,0 +1,75 @@ +""" +Background task +""" + +import contextlib +import logging +import os + +from teuthology import misc +from ..orchestra import run + +log = logging.getLogger(__name__) + +@contextlib.contextmanager +def task(ctx, config): + """ + Run a background task. + + Run the given command on a client, similar to exec. However, when + we hit the finally because the subsequent task is ready to exit, kill + the child process. + + We do not do any error code checking here since we are forcefully killing + off the child when we are done. + + If the command a list, we simply join it with ;'s. + + Example: + + tasks: + - install: + - background_exec: + client.0: while true ; do date ; sleep 1 ; done + client.1: + - while true + - do id + - sleep 1 + - done + - exec: + client.0: + - sleep 10 + + """ + assert isinstance(config, dict), "task background got invalid config" + + testdir = misc.get_testdir(ctx) + + tasks = {} + for role, cmd in config.iteritems(): + (remote,) = ctx.cluster.only(role).remotes.iterkeys() + log.info('Running background command on role %s host %s', role, remote.name) + if isinstance(cmd, list): + cmd = '; '.join(cmd) + cmd.replace('$TESTDIR', testdir) + tasks[remote.name] = remote.run( + args=[ + 'sudo', + 'TESTDIR=%s' % testdir, + 'daemon-helper', 'kill', '--kill-group', + 'bash', '-c', cmd, + ], + wait=False, + stdin=run.PIPE, + check_status=False, + logger=log.getChild(remote.name) + ) + + try: + yield + + finally: + for name, task in tasks.iteritems(): + log.info('Stopping background command on %s', name) + task.stdin.close() + run.wait(tasks.itervalues()) -- 2.39.5