From 802dca3400b900c8f1d531f59f14c98b6b46e8e9 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 24 Oct 2017 17:00:21 -0400 Subject: [PATCH] papr2kube: Experiment to convert papr to Kubernetes jobs After setup: ``` oc cluster up ... oc adm policy add-scc-to-group anyuid system:authenticated ``` ``` ./papr/papr2kube.py --limit 1 ostreedev/ostree 886a5d79280b92d336a4eecc9da287fa8b697542 ~/src/github/ostreedev/ostree/.papr.yml > ostree-papr-kube.yml oc create -f ostree-papr-kube.yml ``` Then I can e.g. watch a build with: `oc logs -f jobs/papr-ostreedev-ostree-886a5d7928-0` --- papr/papr2kube.py | 108 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100755 papr/papr2kube.py diff --git a/papr/papr2kube.py b/papr/papr2kube.py new file mode 100755 index 0000000..23982ad --- /dev/null +++ b/papr/papr2kube.py @@ -0,0 +1,108 @@ +#!/usr/bin/env python3 + +# Convert a papr YAML file into a Kubernetes Job + +import os +import sys +import re +import time +import yaml +import traceback +import argparse +import subprocess + +# XXX: switch to relative imports when we're a proper module +from papr import PKG_DIR +import papr.utils.parser as paprparser + +GH_NAME_REGEX = re.compile('^[A-Za-z0-9_.-]+$') + +def paprsuite2kubejob(gh_org, gh_repo, commitsha, suiteidx, suite): + commitsha_short = commitsha[0:10] + name = 'papr-{}-{}-{}-{}'.format(gh_org, gh_repo, commitsha_short, suiteidx) + metadata = {'name': name} + cmd = 'set -xeuo pipefail\n' + for test in suite['tests']: + cmd += test + '\n' + volumes = [ + {'name': 'builddir', 'emptyDir': {}} + ] + containers = [{ + 'name': name, + 'image': suite['container']['image'], + 'volumeMounts': [ + { 'name': 'builddir', + 'mountPath': '/srv', + } + ], + 'securityContext': {'runAsUser': 0}, + 'workingDir': '/srv/build', + 'command': ["/usr/bin/bash", "-c", cmd], + }] + initContainers = [ + { 'name': 'init-git', + 'image': 'registry.centos.org/centos/centos:7', + 'volumeMounts': [ + { 'name': 'builddir', + 'mountPath': '/srv', + } + ], + 'securityContext': {'runAsUser': 0}, + 'workingDir': '/srv/', + 'command': ['/bin/sh', '-c', + '''set -xeuo pipefail; yum -y install git + git clone --depth=100 https://github.com/{gh_org}/{gh_repo} build + cd build + git checkout {commitsha}'''.format(gh_org=gh_org, gh_repo=gh_repo, commitsha=commitsha)] + } + ] + r = {'apiVersion': 'batch/v1', + 'kind': 'Job', + 'metadata': metadata, + 'spec': { + 'template': { + 'metadata': dict(metadata), + 'spec': { + 'volumes': volumes, + 'initContainers': initContainers, + 'containers': containers, + 'restartPolicy': 'Never' + }, + }, + }, + } + return r + +def main(): + "Main entry point." + + parser = argparse.ArgumentParser(description='Convert .papr.yml to Kuberentes Jobs') + parser.add_argument('--limit', action='store', type=int, help='Emit at most N jobs') + parser.add_argument('ghid', action='store', help='github repo') + parser.add_argument('commitsha', action='store', help='commit sha') + parser.add_argument('path', action='store', help='Path to papr YAML (normally .papr.yml)') + args = parser.parse_args() + + (org,proj) = args.ghid.split('/', 1) + assert GH_NAME_REGEX.match(org) + assert GH_NAME_REGEX.match(proj) + + suite_parser = paprparser.SuiteParser(args.path) + suites = suite_parser.parse() + + stream = sys.stdout + stream.write('# Generated from papr YAML: {}\n'.format(os.path.basename(args.path))) + jobs = [] + joblist = {'apiVersion': 'v1', + 'kind': 'List', + 'items': jobs} + for i,suite in enumerate(suites): + if not suite.get('container'): + continue + jobs.append(paprsuite2kubejob(org, proj, args.commitsha, i, suite)) + if len(jobs) == args.limit: + break + yaml.dump(joblist, stream=stream, explicit_start=True) + +if __name__ == '__main__': + sys.exit(main())