summaryrefslogtreecommitdiff
path: root/meta/classes/sign_rpm.bbclass
blob: 39f877a23cdd5c08a18b426351a622793626f846 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# Class for generating signed RPM packages.
#
# Configuration variables used by this class:
# RPM_GPG_PASSPHRASE_FILE
#           Path to a file containing the passphrase of the signing key.
# RPM_GPG_NAME
#           Name of the key to sign with. Alternatively you can define
#           %_gpg_name macro in your ~/.oerpmmacros file.
# RPM_GPG_PUBKEY
#           Path to a file containing the public key (in "armor" format)
#           corresponding the signing key.
# GPG_BIN
#           Optional variable for specifying the gpg binary/wrapper to use for
#           signing.
# GPG_PATH
#           Optional variable for specifying the gnupg "home" directory:
#
inherit sanity

RPM_SIGN_PACKAGES='1'


_check_gpg_name () {
    macrodef=`rpm -E '%_gpg_name'`
    [ "$macrodef" == "%_gpg_name" ] && return 1 || return 0
}


def rpmsign_wrapper(d, files, passphrase, gpg_name=None):
    import pexpect

    # Find the correct rpm binary
    rpm_bin_path = d.getVar('STAGING_BINDIR_NATIVE', True) + '/rpm'
    cmd = rpm_bin_path + " --addsign "
    if gpg_name:
        cmd += "--define '%%_gpg_name %s' " % gpg_name
    else:
        try:
            bb.build.exec_func('_check_gpg_name', d)
        except bb.build.FuncFailed:
            raise_sanity_error("You need to define RPM_GPG_NAME in bitbake "
                               "config or the %_gpg_name RPM macro defined "
                               "(e.g. in  ~/.oerpmmacros", d)
    if d.getVar('GPG_BIN', True):
        cmd += "--define '%%__gpg %s' " % d.getVar('GPG_BIN', True)
    if d.getVar('GPG_PATH', True):
        cmd += "--define '_gpg_path %s' " % d.getVar('GPG_PATH', True)
    cmd += ' '.join(files)

    # Need to use pexpect for feeding the passphrase
    proc = pexpect.spawn(cmd)
    try:
        proc.expect_exact('Enter pass phrase:', timeout=15)
        proc.sendline(passphrase)
        proc.expect(pexpect.EOF, timeout=900)
        proc.close()
    except pexpect.TIMEOUT as err:
        bb.warn('rpmsign timeout: %s' % err)
        proc.terminate()
    else:
        if os.WEXITSTATUS(proc.status) or not os.WIFEXITED(proc.status):
            bb.warn('rpmsign failed: %s' % proc.before.strip())
    return proc.exitstatus


python sign_rpm () {
    import glob

    rpm_gpg_pass_file = (d.getVar("RPM_GPG_PASSPHRASE_FILE", True) or "")
    if rpm_gpg_pass_file:
        with open(rpm_gpg_pass_file) as fobj:
            rpm_gpg_passphrase = fobj.readlines()[0].rstrip('\n')
    else:
        raise_sanity_error("You need to define RPM_GPG_PASSPHRASE_FILE in the config", d)

    rpm_gpg_name = (d.getVar("RPM_GPG_NAME", True) or "")

    rpms = glob.glob(d.getVar('RPM_PKGWRITEDIR', True) + '/*')

    if rpmsign_wrapper(d, rpms, rpm_gpg_passphrase, rpm_gpg_name) != 0:
        raise bb.build.FuncFailed("RPM signing failed")
}