]> git.apps.os.sepia.ceph.com Git - teuthology.git/commitdiff
background_exec: run something in the background 233/head
authorSage Weil <sage@inktank.com>
Mon, 30 Jun 2014 20:22:36 +0000 (13:22 -0700)
committerSage Weil <sage@inktank.com>
Mon, 30 Jun 2014 20:35:53 +0000 (13:35 -0700)
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 <sage@inktank.com>
teuthology/task/background_exec.py [new file with mode: 0644]

diff --git a/teuthology/task/background_exec.py b/teuthology/task/background_exec.py
new file mode 100644 (file)
index 0000000..a5d506c
--- /dev/null
@@ -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())