diff options
Diffstat (limited to 'packages/brpm')
-rwxr-xr-x | packages/brpm | 216 |
1 files changed, 216 insertions, 0 deletions
diff --git a/packages/brpm b/packages/brpm new file mode 100755 index 00000000..1d05bd2a --- /dev/null +++ b/packages/brpm @@ -0,0 +1,216 @@ +#!/usr/bin/python + +import contextlib +import glob +import os +import shutil +import subprocess +import sys +import tempfile +import re + +import argparse + +# Use the util functions from cloudinit +possible_topdir = os.path.normpath(os.path.join(os.path.abspath( + sys.argv[0]), os.pardir, os.pardir)) +if os.path.exists(os.path.join(possible_topdir, "cloudinit", "__init__.py")): + sys.path.insert(0, possible_topdir) + +from cloudinit import templater +from cloudinit import util + +from datetime import datetime + + +# Mapping of expected packages to there full name... +PKG_MP = { + 'boto': 'python-boto', + 'tempita': 'python-tempita', + 'prettytable': 'python-prettytable', + 'oauth': 'python-oauth', + 'configobj': 'python-configobj', + 'yaml': 'PyYAML', + 'argparse': 'python-argparse' +} + + +def get_log_header(version): + # Try to find the version in the tags output + cmd = ['bzr', 'tags'] + (stdout, _stderr) = util.subp(cmd) + a_rev = None + for t in stdout.splitlines(): + ver, rev = t.split(None) + if ver == version: + a_rev = rev + break + if not a_rev: + return format_change_line(datetime.now(), + '??', version) + + # Extract who made that tag as the header + cmd = ['bzr', 'log', '-r%s' % (a_rev), '--timezone=utc'] + (stdout, _stderr) = util.subp(cmd) + kvs = { + 'comment': version, + } + + for line in stdout.splitlines(): + if line.startswith('committer:'): + kvs['who'] = line[len('committer:'):].strip() + if line.startswith('timestamp:'): + ts = line[len('timestamp:'):] + ts = ts.strip() + # http://bugs.python.org/issue6641 + ts = ts.replace("+0000", '').strip() + ds = datetime.strptime(ts, '%a %Y-%m-%d %H:%M:%S') + kvs['ds'] = ds + + return format_change_line(**kvs) + + +def format_change_line(ds, who, comment=None): + # Rpmbuild seems to be pretty strict about the date format + d = ds.strftime("%a %b %d %Y") + d += " - %s" % (who) + if comment: + d += " - %s" % (comment) + return "* %s" % (d) + + +def generate_spec_contents(args, tmpl_fn): + + # Figure out the version and revno + cmd = [sys.executable, + util.abs_join(os.pardir, 'tools', 'read-version')] + (stdout, _stderr) = util.subp(cmd) + version = stdout.strip() + + cmd = ['bzr', 'revno'] + (stdout, _stderr) = util.subp(cmd) + revno = stdout.strip() + + # Tmpl params + subs = {} + subs['version'] = version + subs['revno'] = revno + subs['release'] = revno + subs['archive_name'] = '%{name}-%{version}-' + revno + '.tar.gz' + subs['bd_requires'] = ['python-devel', 'python-setuptools'] + + cmd = [sys.executable, + util.abs_join(os.pardir, 'tools', 'read-dependencies')] + (stdout, _stderr) = util.subp(cmd) + + # Map to known packages + pkgs = [p.lower().strip() for p in stdout.splitlines()] + + # Map to known packages + requires = [] + for p in pkgs: + tgt_pkg = None + for name in PKG_MP.keys(): + if p.find(name) != -1: + tgt_pkg = PKG_MP.get(name) + break + if not tgt_pkg: + raise RuntimeError(("Do not know how to translate %s to " + " a known package") % (p)) + else: + requires.append(tgt_pkg) + subs['requires'] = requires + + # Format a nice changelog (as best as we can) + changelog = util.load_file(util.abs_join(os.pardir, 'ChangeLog')) + changelog_lines = [] + for line in changelog.splitlines(): + if not line.strip(): + continue + if re.match(r"^\s*[\d][.][\d][.][\d]:\s*", line): + line = line.strip(":") + header = get_log_header(line) + changelog_lines.append(header) + else: + changelog_lines.append(line) + subs['changelog'] = "\n".join(changelog_lines) + + if args.boot == 'initd': + subs['init_d'] = True + subs['init_d_local'] = False + elif args.boot == 'initd-local': + subs['init_d'] = True + subs['init_d_local'] = True + else: + subs['init_d'] = False + subs['init_d_local'] = False + + if args.boot == 'systemd': + subs['systemd'] = True + else: + subs['systemd'] = False + + subs['init_sys'] = args.boot + return templater.render_from_file(tmpl_fn, params=subs) + + +def main(): + + parser = argparse.ArgumentParser() + parser.add_argument("-b", "--boot", dest="boot", + help="select boot type (default: %(default)s)", + metavar="TYPE", default='initd', + choices=('initd', 'systemd', 'initd-local')) + parser.add_argument("-v", "--verbose", dest="verbose", + help=("run verbosely" + " (default: %(default)s)"), + default=False, + action='store_true') + args = parser.parse_args() + capture = True + if args.verbose: + capture = False + + # Clean out the root dir and make sure the dirs we want are in place + root_dir = os.path.expanduser("~/rpmbuild") + if os.path.isdir(root_dir): + shutil.rmtree(root_dir) + arc_dir = util.abs_join(root_dir, 'SOURCES') + util.ensure_dirs([root_dir, arc_dir]) + + # Archive the code + cmd = [sys.executable, + util.abs_join(os.getcwd(), 'make-tarball')] + (stdout, _stderr) = util.subp(cmd) + archive_fn = stdout.strip() + real_archive_fn = os.path.join(arc_dir, os.path.basename(archive_fn)) + shutil.move(archive_fn, real_archive_fn) + + # Form the spec file to be used + tmpl_fn = util.abs_join(os.getcwd(), 'redhat', 'cloud-init.spec') + contents = generate_spec_contents(args, tmpl_fn) + spec_fn = os.path.join(root_dir, 'cloud-init.spec') + util.write_file(spec_fn, contents) + + # Now build it! + cmd = ['rpmbuild', '-ba', spec_fn] + util.subp(cmd, capture=capture) + + # Copy the items built to our local dir + globs = [] + globs.extend(glob.glob("%s/*.rpm" % + (os.path.join(root_dir, 'RPMS', 'noarch')))) + globs.extend(glob.glob("%s/*.rpm" % + (os.path.join(root_dir, 'RPMS')))) + globs.extend(glob.glob("%s/*.rpm" % + (os.path.join(root_dir, 'SRPMS')))) + for rpm_fn in globs: + tgt_fn = util.abs_join(os.getcwd(), os.path.basename(rpm_fn)) + shutil.move(rpm_fn, tgt_fn) + print(tgt_fn) + + return 0 + + +if __name__ == '__main__': + sys.exit(main()) |