summaryrefslogtreecommitdiff
path: root/packages/brpm
diff options
context:
space:
mode:
authorJoshua Harlow <harlowja@yahoo-inc.com>2012-06-25 16:59:39 -0700
committerJoshua Harlow <harlowja@yahoo-inc.com>2012-06-25 16:59:39 -0700
commitc36c782d3c3913611b86edeb7d371c54ced4b8bd (patch)
tree1ecbfc9de0ea710155e4b51f3558ee740a3d3773 /packages/brpm
parent3b05473d57f5aaadf4cd0b57b7138d9ff2141808 (diff)
downloadvyos-cloud-init-c36c782d3c3913611b86edeb7d371c54ced4b8bd.tar.gz
vyos-cloud-init-c36c782d3c3913611b86edeb7d371c54ced4b8bd.zip
Get rpm building working with a template.
Diffstat (limited to 'packages/brpm')
-rwxr-xr-xpackages/brpm270
1 files changed, 260 insertions, 10 deletions
diff --git a/packages/brpm b/packages/brpm
index f2c3dac4..5feade24 100755
--- a/packages/brpm
+++ b/packages/brpm
@@ -6,9 +6,19 @@ import subprocess
import sys
import tempfile
import re
+import textwrap
+import shutil
+import zipfile
+
+import glob
import tempita
+from datetime import datetime
+from datetime import date
+
+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(
@@ -16,28 +26,268 @@ possible_topdir = os.path.normpath(os.path.join(os.path.abspath(
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
+
+import contextlib
+
+# 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'
+}
+
+
+@contextlib.contextmanager
+def chdir(where_to):
+ cur_cwd = os.path.abspath(os.getcwd())
+ where_to = os.path.abspath(where_to)
+ os.chdir(where_to)
+ yield where_to
+ os.chdir(cur_cwd)
+
+
PWD = os.getcwd()
def info(msg):
- sys.stderr.write("INFO: %s\n" % (msg))
+ print("INFO: %s" % (msg))
def warn(msg):
- sys.stderr.write("WARNING: %s\n" % (msg))
+ print("WARNING: %s" % (msg))
-def main():
- if not os.path.isfile(os.path.join(PWD, 'brpm.tmpl')):
- warn("Can not find required template file 'brpm.tmpl'")
- return 1
- if not os.path.isfile(os.path.join(os.pardir, 'setup.py')):
- warn("Can not find required root 'setup.py' file")
- return 1
+def cut_up(entry, maxline=80):
+ if len(entry) < maxline:
+ return entry
+ else:
+ c = entry[0:maxline]
+ return "%s..." % (c)
+
+
+def extract_entry(collecting):
+ a_entry = {}
+ for t in ['tags', 'revno', 'author', 'timestamp', 'committer']:
+ look_for = "%s:" % (t)
+ for v in collecting:
+ if v.startswith(look_for):
+ a_entry[t] = v[len(look_for):].strip()
+ break
+ i = -1
+ for a, v in enumerate(collecting):
+ if v.startswith("message:"):
+ i = a
+ break
+ if i != -1:
+ msg_lines = collecting[i + 1:]
+ n_lines = []
+ for m in msg_lines:
+ m = m.strip()
+ if not m:
+ continue
+ m = m.replace("\n", " ")
+ n_lines.append("" + m.lstrip())
+ message = " ".join(n_lines).lstrip()
+ a_entry['message'] = message
+ return a_entry
+
+
+def build_changelog(history=-1):
+ cmd = ['bzr', 'log', '--timezone=utc']
+ (stdout, _stderr) = util.subp(cmd)
+ # Clean the format up
+ entries = stdout.splitlines()
+ all_entries = []
+ collecting = []
+ for e in entries:
+ if e.startswith("---"):
+ if collecting:
+ a_entry = extract_entry(collecting)
+ if a_entry:
+ all_entries.append(a_entry)
+ collecting = []
+ else:
+ collecting.append(e)
+ a_entry = extract_entry(collecting)
+ if a_entry:
+ all_entries.append(a_entry)
+
+ if history > 0:
+ take_entries = list(all_entries[0:history])
+ else:
+ take_entries = list(all_entries)
+
+ # Merge those with same date
+ date_entries = {}
+ for e in take_entries:
+ author = e.get('author')
+ if not author:
+ author = e.get('committer')
+ if not author:
+ continue
+ timestamp = e.get('timestamp')
+ if not timestamp:
+ continue
+ msg = e.get('message')
+ if not msg:
+ continue
+ revno = e.get('revno')
+ if not revno:
+ continue
+ # http://bugs.python.org/issue6641
+ timestamp = timestamp.replace("+0000", '').strip()
+ ds = datetime.strptime(timestamp, '%a %Y-%m-%d %H:%M:%S')
+ c_ds = ds.date()
+ if c_ds not in date_entries:
+ ap_entry = {}
+ ap_entry['messages'] = []
+ ap_entry['authors'] = []
+ ap_entry['revnos'] = []
+ date_entries[c_ds] = ap_entry
+ ap_entry = date_entries[c_ds]
+ ap_entry['messages'].append(msg)
+ ap_entry['authors'].append(author)
+ ap_entry['revnos'].append(revno)
+
+ dates = sorted(date_entries.keys())
+ chglog = []
+ for ds in reversed(dates):
+ e = date_entries[ds]
+ authors = ", ".join(set(e['authors']))
+ revnos = ", ".join(list(sorted(e['revnos'])))
+ top_line = "%s %s - %s" % (ds.strftime("%a %b %d %Y"),
+ authors, revnos)
+ chglog.append("* %s" % (top_line))
+ for msg in e['messages']:
+ chglog.append("- %s" % (cut_up(msg)))
+ return "\n".join(chglog)
+
+
+def generate_spec_contents(tmpl_fn):
+ # Version junk
cmd = [os.path.join(os.pardir, 'tools', 'read-version')]
- version = subprocess.check_Call(cmd)
+ (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
+ subs['changelog'] = build_changelog()
+
+ # 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():
+ root_dir = os.path.expanduser("~/rpmbuild")
+ info("Cleaning %s" % (root_dir))
+ util.delete_dir_contents(root_dir)
+ arc_dir = os.path.join(root_dir, 'SOURCES')
+ util.ensure_dirs([root_dir, arc_dir])
+ 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))
+ 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))
+ cmd = ['rpmbuild', '-ba', spec_fn]
+ info("Running rpmbuild %s" % (cmd))
+ util.subp(cmd)
+ info("Rpmbuild completed!")
+ 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