summaryrefslogtreecommitdiff
path: root/packages/brpm
diff options
context:
space:
mode:
Diffstat (limited to 'packages/brpm')
-rwxr-xr-xpackages/brpm216
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())