aboutsummaryrefslogtreecommitdiffstats
path: root/utils
diff options
context:
space:
mode:
authorKevin Hilman <khilman@baylibre.com>2017-08-22 16:07:47 -0700
committerKevin Hilman <khilman@baylibre.com>2017-09-01 15:52:07 -0700
commit05146fa425d94a77ba35b43ac3b0a5c633163d4e (patch)
tree1d68bd51a1dfe8cc6c5e19fe517dbb19f3b67725 /utils
parent263fa00cd42334c69897ebad72fcd9d6acd89aeb (diff)
initial snapshot: LAVA job creation based on templates
Change-Id: I5d545d3531f4c4190453724738076bd4eddfc4d6 Signed-off-by: Jerome Brunet <jbrunet@baylibre.com> Signed-off-by: Loys Ollivier <lollivier@baylibre.com> Signed-off-by: Kevin Hilman <khilman@baylibre.com>
Diffstat (limited to 'utils')
-rw-r--r--utils/agljobtemplate.py73
-rwxr-xr-xutils/create-jobs.py68
2 files changed, 141 insertions, 0 deletions
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()