diff options
author | Adam Coldrick <adam.coldrick@codethink.co.uk> | 2015-02-18 15:52:21 +0000 |
---|---|---|
committer | Michael Drake <michael.drake@codethink.co.uk> | 2015-03-09 17:01:23 +0000 |
commit | 009b22cc1c79e0576e9d21218be1983aea87e5da (patch) | |
tree | 8587cdf6b3cd1e8447ebcfc262716489c4395f3f | |
parent | 1139cc409e99a82a1944428a9df4a1170fd0b272 (diff) | |
download | system-tests-009b22cc1c79e0576e9d21218be1983aea87e5da.tar.gz |
Add a Zuul job runner.
-rw-r--r-- | mason/__init__.py | 1 | ||||
-rw-r--r-- | mason/runners.py | 161 |
2 files changed, 162 insertions, 0 deletions
diff --git a/mason/__init__.py b/mason/__init__.py index 162f0e5..dc5a195 100644 --- a/mason/__init__.py +++ b/mason/__init__.py @@ -1,3 +1,4 @@ from . import deployment from . import publishers +from . import runners from . import util diff --git a/mason/runners.py b/mason/runners.py new file mode 100644 index 0000000..43fd26e --- /dev/null +++ b/mason/runners.py @@ -0,0 +1,161 @@ +# Copyright 2014 Codethink Ltd. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +import json +import logging +import os +import shutil + +import cliapp + +from . import util + +class JobRunner(object): + + """A generic Zuul job runner.""" + + logging.getLogger('mason.runners.JobRunner') + + def __init__(self, worker_server, config, function): + self._reset() + + self.worker_server = worker_server + self.plugin_config = config + self.function = function + + self.total_steps = 0 + + def _reset(self): + self.success = True + self.cancelled = False + self.job = None + self.job_arguments = None + self.current_step = 0 + + + def start_job(self, job): + self._reset() + self.job = job + + if self.job is not None: + print "starting job" + try: + self.job_arguments = json.loads(self.job.arguments.decode('utf-8')) + self.send_work_data() + self.run_job() + self.send_work_complete() + except Exception as e: + self.success = False + self.send_work_data(result='Exception: %s' % e) + self.job.sendWorkException(str(e).encode('utf-8')) + + def _get_work_data(self): + work_data = {'name': self.function, + 'location': os.uname()[1], + 'number': self.job.unique, + } + return work_data + + def send_work_data(self, data=None, result=''): + if data is None: + data = self._get_work_data() + if self.success: + data['result'] = 'SUCCESS' + else: + data['result'] = result + logging.debug(json.dumps(data)) + print data + self.job.sendWorkData(json.dumps(data)) + + def send_work_complete(self, data=None): + if data is None: + data = self._get_work_data() + self.send_work_data(data) + if self.success: + print 'sending work-complete' + self.job.sendWorkComplete(json.dumps(data)) + else: + print 'sending work-fail' + self.job.sendWorkFail() + + def stop_working(self, number=None): + if number is None or number == self.job.unique: + self.cancelled = True + + def run_job(self): + # This function is to be implemented by subclasses + pass + + def _do_next_step(self): + self._handle_cancellation() + self.current_step += 1 + data = self._get_work_data() + data['current-step'] = self.current_step + self.send_work_data(data) + + def _handle_cancellation(self): + if self.cancelled: + data = self._get_work_data() + data['result'] = 'Cancelled' + self.send_work_data(data) + self.job.sendWorkFail() + raise Exception('Job cancelled') + + def _do_git_config(self, name='Mason Test Runner', email='mason@runner'): + cliapp.runcmd(['git', 'config', '--global', 'user.name', name]) + cliapp.runcmd(['git', 'config', '--global', 'user.email', email]) + + @util.job_step + def _create_workspace(self): + os.chdir('/root') + self.commit = self.job_arguments['ZUUL_COMMIT'] + self.project = self.job_arguments['ZUUL_PROJECT'] + self.ref = self.job_arguments['ZUUL_REF'] + self.workspace = '/root/mason-workspace' + self.zuul_url = self.job_arguments['ZUUL_URL'] + + self._do_git_config() + + if os.path.exists(self.workspace): + shutil.rmtree(self.workspace) + + cliapp.runcmd(['morph', 'init', self.workspace]) + + zuul_gits_dir = 'var/lib/zuul/git/' + + repo_dir = os.path.join('/', zuul_gits_dir, self.project) + cliapp.runcmd(['morph', 'checkout', repo_dir, self.commit], + cwd=self.workspace) + + # Morph allows us to rename the system branch directory from the + # ludicrously long name that it chose for us. + temp_defs_checkout = os.path.join( + self.workspace, self.commit, zuul_gits_dir, self.project) + self.defs_checkout = os.path.join( + self.workspace, self.commit, self.project) + logging.debug( + 'Renaming system-branch directory from %s to %s', + temp_defs_checkout, self.defs_checkout) + os.renames(temp_defs_checkout, self.defs_checkout) + + self.morph_helper = util.MorphologyHelper(self.defs_checkout) + + def _remove_workspace(self): + cliapp.runcmd(['rm', '-rf', self.workspace]) + + @util.job_step + def _clean_up(self): + os.chdir('/root') + self._remove_workspace() |