From 05146fa425d94a77ba35b43ac3b0a5c633163d4e Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Tue, 22 Aug 2017 16:07:47 -0700 Subject: initial snapshot: LAVA job creation based on templates Change-Id: I5d545d3531f4c4190453724738076bd4eddfc4d6 Signed-off-by: Jerome Brunet Signed-off-by: Loys Ollivier Signed-off-by: Kevin Hilman --- utils/agljobtemplate.py | 73 +++++++++++++++++++++++++++++++++++++++++++++++++ utils/create-jobs.py | 68 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 141 insertions(+) create mode 100644 utils/agljobtemplate.py create mode 100755 utils/create-jobs.py (limited to 'utils') diff --git a/utils/agljobtemplate.py b/utils/agljobtemplate.py new file mode 100644 index 0000000..749d4bf --- /dev/null +++ b/utils/agljobtemplate.py @@ -0,0 +1,73 @@ +#!/usr/bin/env python2 +# -*- coding: utf-8 -*- + +import os +import sys +import jinja2 + + +def get_extension(path): + return path.split('.')[-1] + + +class Agljobtemplate(object): + + DEFAULT_PATH = "templates" + MACHINES_DIR = "machines" + TESTS_DIR = "tests" + RFS_TYPE = ['nfs', 'nbd', 'ramdisk'] + + def __init__(self, path=DEFAULT_PATH): + self._template_path = os.path.normpath(path) + if not (os.path.isdir(self._template_path) and os.access(self._template_path, os.F_OK)): + raise OSError, "Cannot access {}".format(self._template_path) + + if self.machines is None: + raise RuntimeError, "No machine directory found at {}".format(self._template_path) + + def __list_jinjas(self, directory): + d = os.path.join(self._template_path, directory) + return [os.path.splitext(os.path.basename(f))[0] for f in os.listdir(d) if f.endswith('.jinja2')] + + @property + def machines(self): + """ List the availables machines + """ + return self.__list_jinjas(self.MACHINES_DIR) + + @property + def tests(self): + """ List the availables tests + """ + return self.__list_jinjas(self.TESTS_DIR) + + @property + def rfs_types(self): + return self.RFS_TYPE + + def render_job(self, url, machine, job_name="AGL-short-smoke", priority="medium", tests=[], rfs_type="nbd"): + test_templates = [] + + if machine not in self.machines: + raise RuntimeError, "{} is not a available machine".format(machine) + + for t in tests: + if t in self.tests: + test_templates.append(os.path.join(self.TESTS_DIR, t + '.jinja2')) + else: + raise RuntimeError, "{} is not an available test".format(t) + + # Populate jinja substitution dict + job = {} + job['name'] = job_name + job['yocto_machine'] = machine + job['priority'] = priority + job['urlbase'] = url + job['test_templates'] = test_templates + job['rootfs_type'] = rfs_type + + env = jinja2.Environment(loader=jinja2.FileSystemLoader(self._template_path)) + env.filters['get_extension'] = get_extension + template = env.get_template(os.path.join(self.MACHINES_DIR, machine + ".jinja2")) + + return template.render(job) diff --git a/utils/create-jobs.py b/utils/create-jobs.py new file mode 100755 index 0000000..1c15bb6 --- /dev/null +++ b/utils/create-jobs.py @@ -0,0 +1,68 @@ +#!/usr/bin/env python2 +# -*- coding: utf-8 -*- + +import agljobtemplate +import argparse +import urlparse + + +def parse_cmdline(machines, tests, rfs_types): + parser = argparse.ArgumentParser(description="AGL create job", + formatter_class=argparse.ArgumentDefaultsHelpFormatter) + parser.add_argument('--version', '-v', action='version', version='%(prog)s 1.0') + parser.add_argument('machine', action='store', choices=machines, + help="machine to generate the job for") + parser.add_argument('--priority', '-p', action='store', dest='priority', + help="job priority", + default='medium') + parser.add_argument('--urlbase', '-u', action='store', dest='urlbase', + help="url fetch base", + default='https://download.automotivelinux.org/AGL/upload/ci/') + parser.add_argument('--boot', action='store', dest='rfs_type', nargs=1, required=True, + choices=rfs_types, help='select boot type') + parser.add_argument('--test', dest='tests', action='store', choices=tests + ['all'], + help="add these test to the job", nargs='*', default=[]) + parser.add_argument('-o', '--output', dest='job_file', action='store', + help="destination file") + parser.add_argument('-n', '--name', dest='job_name', action='store', + help="job name", default='AGL-short-smoke-wip') + parser.add_argument('-j', '--jobid', dest='job_id', action='store', + help='job id for link creation: URLBASE/JOB_ID', required=True) + parser.add_argument('-i', '--jobidx', dest='job_index', action='store', + help='job index for link creation: URLBASE/JOB_ID/JOB_INDEX', default='1') + + return parser.parse_args() + + +def main(): + ajt = agljobtemplate.Agljobtemplate('templates') + args = parse_cmdline(ajt.machines, ajt.tests, ajt.rfs_types) + + if args.tests is not None and 'all' in args.tests: + args.tests = ajt.tests + + if args.job_id is not None: + args.urlbase = urlparse.urljoin(args.urlbase, args.job_id + '/') + args.job_name += ' - {}'.format(args.job_id) + + if args.job_index is not None: + args.urlbase = urlparse.urljoin(args.urlbase, args.job_index) + args.job_name += ' - {}'.format(args.job_index) + + job = ajt.render_job(args.urlbase, args.machine, tests=args.tests, priority=args.priority, + rfs_type=args.rfs_type[0], job_name=args.job_name) + + if args.job_file is None: + print job + else: + try: + with open(args.job_file, 'w') as j: + j.write(job) + except IOError as e: + print "{}: {}".format(e.strerror, args.job_file) + exit(e.errno) + else: + print "Job written to: {}".format(args.job_file) + +if __name__ == '__main__': + main() -- cgit 1.2.3-korg