Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 1 | # Class for generating signed RPM packages. |
| 2 | # |
| 3 | # Configuration variables used by this class: |
| 4 | # RPM_GPG_PASSPHRASE_FILE |
| 5 | # Path to a file containing the passphrase of the signing key. |
| 6 | # RPM_GPG_NAME |
Patrick Williams | f1e5d69 | 2016-03-30 15:21:19 -0500 | [diff] [blame^] | 7 | # Name of the key to sign with. May be key id or key name. |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 8 | # GPG_BIN |
| 9 | # Optional variable for specifying the gpg binary/wrapper to use for |
| 10 | # signing. |
Patrick Williams | f1e5d69 | 2016-03-30 15:21:19 -0500 | [diff] [blame^] | 11 | # GPG_PATH |
| 12 | # Optional variable for specifying the gnupg "home" directory: |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 13 | # |
| 14 | inherit sanity |
| 15 | |
| 16 | RPM_SIGN_PACKAGES='1' |
| 17 | |
| 18 | |
Patrick Williams | f1e5d69 | 2016-03-30 15:21:19 -0500 | [diff] [blame^] | 19 | python () { |
| 20 | # Check configuration |
| 21 | for var in ('RPM_GPG_NAME', 'RPM_GPG_PASSPHRASE_FILE'): |
| 22 | if not d.getVar(var, True): |
| 23 | raise_sanity_error("You need to define %s in the config" % var, d) |
| 24 | |
| 25 | # Set the expected location of the public key |
| 26 | d.setVar('RPM_GPG_PUBKEY', os.path.join(d.getVar('STAGING_ETCDIR_NATIVE'), |
| 27 | 'RPM-GPG-PUBKEY')) |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 28 | } |
| 29 | |
| 30 | |
| 31 | def rpmsign_wrapper(d, files, passphrase, gpg_name=None): |
| 32 | import pexpect |
| 33 | |
| 34 | # Find the correct rpm binary |
| 35 | rpm_bin_path = d.getVar('STAGING_BINDIR_NATIVE', True) + '/rpm' |
Patrick Williams | f1e5d69 | 2016-03-30 15:21:19 -0500 | [diff] [blame^] | 36 | cmd = rpm_bin_path + " --addsign --define '_gpg_name %s' " % gpg_name |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 37 | if d.getVar('GPG_BIN', True): |
| 38 | cmd += "--define '%%__gpg %s' " % d.getVar('GPG_BIN', True) |
Patrick Williams | f1e5d69 | 2016-03-30 15:21:19 -0500 | [diff] [blame^] | 39 | if d.getVar('GPG_PATH', True): |
| 40 | cmd += "--define '_gpg_path %s' " % d.getVar('GPG_PATH', True) |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 41 | cmd += ' '.join(files) |
| 42 | |
| 43 | # Need to use pexpect for feeding the passphrase |
| 44 | proc = pexpect.spawn(cmd) |
| 45 | try: |
| 46 | proc.expect_exact('Enter pass phrase:', timeout=15) |
| 47 | proc.sendline(passphrase) |
| 48 | proc.expect(pexpect.EOF, timeout=900) |
| 49 | proc.close() |
| 50 | except pexpect.TIMEOUT as err: |
Patrick Williams | f1e5d69 | 2016-03-30 15:21:19 -0500 | [diff] [blame^] | 51 | bb.warn('rpmsign timeout: %s' % err) |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 52 | proc.terminate() |
Patrick Williams | f1e5d69 | 2016-03-30 15:21:19 -0500 | [diff] [blame^] | 53 | else: |
| 54 | if os.WEXITSTATUS(proc.status) or not os.WIFEXITED(proc.status): |
| 55 | bb.warn('rpmsign failed: %s' % proc.before.strip()) |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 56 | return proc.exitstatus |
| 57 | |
| 58 | |
| 59 | python sign_rpm () { |
| 60 | import glob |
| 61 | |
Patrick Williams | f1e5d69 | 2016-03-30 15:21:19 -0500 | [diff] [blame^] | 62 | with open(d.getVar("RPM_GPG_PASSPHRASE_FILE", True)) as fobj: |
| 63 | rpm_gpg_passphrase = fobj.readlines()[0].rstrip('\n') |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 64 | |
| 65 | rpm_gpg_name = (d.getVar("RPM_GPG_NAME", True) or "") |
| 66 | |
| 67 | rpms = glob.glob(d.getVar('RPM_PKGWRITEDIR', True) + '/*') |
| 68 | |
| 69 | if rpmsign_wrapper(d, rpms, rpm_gpg_passphrase, rpm_gpg_name) != 0: |
| 70 | raise bb.build.FuncFailed("RPM signing failed") |
| 71 | } |
Patrick Williams | f1e5d69 | 2016-03-30 15:21:19 -0500 | [diff] [blame^] | 72 | |
| 73 | do_package_index[depends] += "signing-keys:do_export_public_keys" |