Merge "Ansible launcher: add option to keep jobdir"
diff --git a/zuul/cmd/launcher.py b/zuul/cmd/launcher.py
index 86266b3..c9516f8 100644
--- a/zuul/cmd/launcher.py
+++ b/zuul/cmd/launcher.py
@@ -46,6 +46,9 @@
         parser.add_argument('--version', dest='version', action='version',
                             version=self._get_version(),
                             help='show zuul version')
+        parser.add_argument('--keep-jobdir', dest='keep_jobdir',
+                            action='store_true',
+                            help='keep local jobdirs after run completes')
         self.args = parser.parse_args()
 
     def reconfigure_handler(self, signum, frame):
@@ -73,7 +76,8 @@
         self.log = logging.getLogger("zuul.Launcher")
 
         LaunchServer = zuul.launcher.ansiblelaunchserver.LaunchServer
-        self.launcher = LaunchServer(self.config)
+        self.launcher = LaunchServer(self.config,
+                                     keep_jobdir=self.args.keep_jobdir)
         self.launcher.start()
 
         signal.signal(signal.SIGHUP, self.reconfigure_handler)
diff --git a/zuul/launcher/ansiblelaunchserver.py b/zuul/launcher/ansiblelaunchserver.py
index 1c68716..c764d1f 100644
--- a/zuul/launcher/ansiblelaunchserver.py
+++ b/zuul/launcher/ansiblelaunchserver.py
@@ -37,7 +37,8 @@
 
 
 class JobDir(object):
-    def __init__(self):
+    def __init__(self, keep=False):
+        self.keep = keep
         self.root = tempfile.mkdtemp()
         self.git_root = os.path.join(self.root, 'git')
         os.makedirs(self.git_root)
@@ -56,15 +57,17 @@
         return self
 
     def __exit__(self, etype, value, tb):
-        shutil.rmtree(self.root)
+        if not self.keep:
+            shutil.rmtree(self.root)
 
 
 class LaunchServer(object):
     log = logging.getLogger("zuul.LaunchServer")
     section_re = re.compile('site "(.*?)"')
 
-    def __init__(self, config):
+    def __init__(self, config, keep_jobdir=False):
         self.config = config
+        self.keep_jobdir = keep_jobdir
         self.hostname = socket.gethostname()
         self.node_workers = {}
         self.mpmanager = multiprocessing.Manager()
@@ -221,7 +224,7 @@
                             self.sites, args['name'], args['host'],
                             args['description'], args['labels'],
                             self.hostname, self.zmq_send_queue,
-                            self.termination_queue)
+                            self.termination_queue, self.keep_jobdir)
         self.node_workers[worker.name] = worker
 
         worker.process = multiprocessing.Process(target=worker.run)
@@ -279,7 +282,7 @@
 class NodeWorker(object):
     def __init__(self, config, jobs, builds, sites, name, host,
                  description, labels, manager_name, zmq_send_queue,
-                 termination_queue):
+                 termination_queue, keep_jobdir):
         self.log = logging.getLogger("zuul.NodeWorker.%s" % (name,))
         self.log.debug("Creating node worker %s" % (name,))
         self.config = config
@@ -299,6 +302,7 @@
         self.manager_name = manager_name
         self.zmq_send_queue = zmq_send_queue
         self.termination_queue = termination_queue
+        self.keep_jobdir = keep_jobdir
         self.running_job_lock = threading.Lock()
         self._job_complete_event = threading.Event()
         self._running_job = False
@@ -540,7 +544,7 @@
 
         self.log.debug("Job %s: beginning" % (job.unique,))
         self.builds[job.unique] = self.name
-        with JobDir() as jobdir:
+        with JobDir(self.keep_jobdir) as jobdir:
             self.log.debug("Job %s: job root at %s" %
                            (job.unique, jobdir.root))
             timeout = self.prepareAnsibleFiles(jobdir, job, args)