From 042bd0d652484b98bbe78fe3098c9f04bb6740bd Mon Sep 17 00:00:00 2001 From: Todd Zullinger Date: Sun, 15 Mar 2009 21:27:23 -0400 Subject: Add options for signing packages --- puppet-host-package | 20 ++++++++++++++++++++ puppethost.py | 43 +++++++++++++++++++++++++++++++++++++------ 2 files changed, 57 insertions(+), 6 deletions(-) diff --git a/puppet-host-package b/puppet-host-package index 195a1df..f609836 100755 --- a/puppet-host-package +++ b/puppet-host-package @@ -47,6 +47,10 @@ def _main(): # FIXME improve the help string parser.add_option('-S', '--dest-ssldir', dest='destssldir', metavar='dir', help='Directory where ssl certs are packaged') + parser.add_option('--sign', dest='sign', action='store_true', + help='Sign packages [%default]') + parser.add_option('--sign-as', dest='key', default='', metavar='keyid', + help='The key to use for signing (name or keyid)') parser.add_option('-t', '--template', dest='template', metavar='file', help='RPM spec file template [%default]') parser.add_option('-v', '--verbose', dest='verbose', action='count', @@ -85,6 +89,11 @@ def _main(): if not os.path.isfile(opts.template): raise SystemExit('Template file (%s) does not exist' % opts.template) + if opts.key: + opts.sign = True + + packages = [] + for hostname in args: if opts.verbose: print '\nCreating a host package for %s' % hostname @@ -102,6 +111,17 @@ def _main(): print error continue + packages.extend(host.packages) + + if packages and opts.sign: + if opts.verbose: + keyid = opts.key and opts.key or 'default key' + print 'Signing packages using %s' % keyid + try: + puppethost.sign(packages, key=opts.key, verbose=opts.verbose) + except puppethost.PuppetHostError, error: + raise SystemExit(error) + if __name__ == '__main__': try: _main() except KeyboardInterrupt: diff --git a/puppethost.py b/puppethost.py index 9842fbd..7f4204e 100644 --- a/puppethost.py +++ b/puppethost.py @@ -36,6 +36,7 @@ defaults = { 'force_package': False, 'release': '1', 'rpmdir': os.path.abspath(os.curdir), + 'sign': True, 'ssldir': '/etc/puppet/ssl', 'template': '%(ssldir)s/template.spec', 'verbose': 1, @@ -66,6 +67,37 @@ if os.path.exists(config): package_types = ['deb', 'rpm'] +def sign(packages, key='', verbose=defaults['verbose']): + for type in package_types: + pkgs = [p for t,p in packages if t == type] + if not pkgs: + continue + try: + sign_func = getattr(sys.modules[__name__], '_' + type + 'sign') + except AttributeError: + raise NotImplementedError( + 'Signing of %s packages is not implemented' % type) + sign_func(pkgs, key) + +def _rpmsign(rpms, key='', tries=3): + cmd = 'rpm --addsign' + if key: + cmd = cmd + ' --define "_gpg_name %s"' % key + cmd += ' ' + ' '.join(rpms) + while tries: + tries -= 1 + status, output = commands.getstatusoutput(cmd) + if status: + if tries: + print 'Error signing rpms:\n', output + print 'Try again (%d left)' % tries + continue + raise PuppetHostError('Error signing rpms:\n%s' % output) + else: + print 'Sucessfully signed %d rpm(s)' % len(rpms) + break + return True + class PuppetHostError(StandardError): pass @@ -83,9 +115,8 @@ class PuppetHost(object): self.opts = opts self.datefmt = '%Y%m%d' - self.debfile = '' - self.rpmfile = '' - self.tarfile = '' + self.packages = [] + self.tarball = '' self._version = '' def gencert(self): @@ -146,7 +177,7 @@ class PuppetHost(object): arcname = '%s%s' % (name, f.replace(self.opts['ssldir'], '')) tar.add(f, arcname) tar.close() - self.tarfile = tarball + self.tarball = tarball if self.opts['verbose']: print 'done' @@ -156,7 +187,7 @@ class PuppetHost(object): rpmdir = self.opts['rpmdir'] tmpdir = tempfile.mkdtemp('', 'puppet-host-') - if not self.tarfile or not os.path.exists(self.tarfile): + if not self.tarball or not os.path.exists(self.tarball): try: self.tar(tmpdir) except: self._cleanup(tmpdir) @@ -204,7 +235,7 @@ class PuppetHost(object): print 'done' self._cleanup(tmpdir) - self.rpmfile = rpm + self.packages.append(('rpm', rpm)) def _check_files(self): """Check for the files we care about""" -- cgit