#!/usr/bin/python # vi: ts=4 expandtab import os import sys import shutil import glob import tempita from distutils import version as ver # This is more just for running from the bin folder so that # cloud-init binary can find the cloudinit module 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 util from cloudinit import version # 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 info(msg): print("INFO: %s" % (msg)) def warn(msg): print("WARNING: %s" % (msg)) def generate_spec_contents(tmpl_fn): # Version junk cmd = [os.path.join(os.pardir, 'tools', 'read-version')] (stdout, _stderr) = util.subp(cmd) i_version = stdout.strip() # Ensure ok match! if ver.StrictVersion(i_version) != version.version(): raise RuntimeError("Version found does not match the code version") # Tmpl params subs = {} subs['version'] = i_version (stdout, _stderr) = util.subp(['bzr', 'revno']) subs['revno'] = "%s" % (stdout.strip()) subs['release'] = "%s" % (subs['revno']) subs['archive_name'] = '%{name}-%{version}-' + subs['revno'] + '.tar.gz' subs['bd_requires'] = ['python-devel', 'python-setuptools'] requires = [] cmd = [os.path.join(os.pardir, 'tools', 'read-dependencies')] (stdout, _stderr) = util.subp(cmd) pkgs = stdout.splitlines() # Map to known packages for e in pkgs: e = e.lower().strip() tgt_pkg = None for n in PKG_MP.keys(): if e.find(n) != -1: tgt_pkg = PKG_MP.get(n) if not tgt_pkg: raise RuntimeError(("Do not know how to translate %s to " " a known package") % (e)) else: requires.append(tgt_pkg) base_name = 'cloud-init-%s-%s' % (i_version, subs['revno']) subs['requires'] = requires (stdout, _stderr) = util.subp([os.path.join(os.getcwd(), 'rpm-changelog')]) subs['changelog'] = stdout # See: http://www.zarb.org/~jasonc/macros.php # Pickup any special files docs = [ 'TODO', 'LICENSE', 'ChangeLog', 'Requires', '%{_defaultdocdir}/cloud-init/*', ] subs['docs'] = docs configs = [ 'cloud/cloud.cfg', 'cloud/cloud.cfg.d/*.cfg', 'cloud/cloud.cfg.d/README', 'cloud/templates/*', ] subs['configs'] = configs other_files = [ '%{_bindir}/*', '/usr/lib/cloud-init/*', ] subs['files'] = other_files with open(tmpl_fn, 'r') as fh: tmpl = tempita.Template(fh.read()) contents = tmpl.substitute(**subs) return (base_name, '%s.tar.gz' % (base_name), contents) def main(): # Clean out the root dir and make sure the dirs we want are in place root_dir = os.path.expanduser("~/rpmbuild") info("Cleaning %s" % (root_dir)) if os.path.isdir(root_dir): util.delete_dir_contents(root_dir) arc_dir = os.path.join(root_dir, 'SOURCES') util.ensure_dirs([root_dir, arc_dir]) # Form the spec file to be used tmpl_fn = os.path.join(os.getcwd(), 'brpm.tmpl') info("Generated spec file from template %s" % (tmpl_fn)) (base_name, arc_name, contents) = generate_spec_contents(tmpl_fn) spec_fn = os.path.join(root_dir, 'cloud-init.spec') util.write_file(spec_fn, contents) info("Wrote spec file to %s" % (spec_fn)) # Archive the code and files that we want to with util.tempdir() as td: src_dir = os.path.join(td, base_name) os.makedirs(src_dir) for fn in os.listdir(os.pardir): if fn.startswith("."): continue full_fn = os.path.abspath(os.path.join(os.pardir, fn)) if os.path.isfile(full_fn): shutil.copy(full_fn, os.path.join(src_dir, fn)) else: shutil.copytree(full_fn, os.path.join(src_dir, fn), ignore=shutil.ignore_patterns('*.pyc', '.bzr', 'tmp*', '*bzr*')) arc_fn = os.path.join(arc_dir, arc_name) cmd = ['tar', '-zcvf', arc_fn, '-C', td] cmd.extend(os.listdir(td)) util.subp(cmd) info("Archived code at %s" % (arc_fn)) # Now build it! cmd = ['rpmbuild', '-ba', spec_fn] info("Running rpmbuild %s" % (cmd)) util.subp(cmd) info("Rpmbuild completed!") # 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 fn in globs: n = os.path.basename(fn) tgt_fn = os.path.join(os.getcwd(), n) util.copy(fn, tgt_fn) info("Copied %s to %s" % (n, tgt_fn)) return 0 if __name__ == '__main__': sys.exit(main())