You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
salt/SOURCES/salt-py3-2019.2.1-rpmsign.p...

215 lines
9.2 KiB

diff -Naur a/salt/modules/rpmbuild_pkgbuild.py b/salt/modules/rpmbuild_pkgbuild.py
--- a/salt/modules/rpmbuild_pkgbuild.py 2019-07-02 10:15:07.035874718 -0600
+++ b/salt/modules/rpmbuild_pkgbuild.py 2019-07-02 10:55:34.147934899 -0600
@@ -140,7 +140,9 @@
tgtattrs = tgt.split('-')
if tgtattrs[0] == 'amzn':
distset = '--define "dist .{0}1"'.format(tgtattrs[0])
- elif tgtattrs[1] in ['6', '7']:
+ elif tgtattrs[0] == 'amzn2':
+ distset = '--define "dist .{0}"'.format(tgtattrs[0])
+ elif tgtattrs[1] in ['6', '7', '8']:
distset = '--define "dist .el{0}"'.format(tgtattrs[1])
else:
distset = ''
@@ -173,6 +175,19 @@
return deps_list
+def _check_repo_gpg_phrase_utils():
+ '''
+ Check for /usr/libexec/gpg-preset-passphrase is installed
+ '''
+ util_name = '/usr/libexec/gpg-preset-passphrase'
+ if __salt__['file.file_exists'](util_name):
+ return True
+ else:
+ raise CommandExecutionError(
+ 'utility \'{0}\' needs to be installed'.format(util_name)
+ )
+
+
def make_src_pkg(dest_dir, spec, sources, env=None, template=None, saltenv='base', runas='root'):
'''
Create a source rpm from the given spec file and sources
@@ -450,8 +465,14 @@
Use a passphrase with the signing key presented in ``keyid``.
Passphrase is received from Pillar data which could be passed on the
- command line with ``pillar`` parameter. For example:
+ command line with ``pillar`` parameter.
+ .. versionadded:: 2018.2.1
+
+ RHEL 8 and above leverages gpg-agent and gpg-preset-passphrase for
+ caching keys, etc.
+
+ For example:
.. code-block:: bash
pillar='{ "gpg_passphrase" : "my_passphrase" }'
@@ -485,10 +506,27 @@
'''
SIGN_PROMPT_RE = re.compile(r'Enter pass phrase: ', re.M)
- define_gpg_name = ''
+ local_keygrip_to_use = None
+ local_key_fingerprint = None
local_keyid = None
local_uids = None
+ define_gpg_name = ''
phrase = ''
+ retrc = 0
+ use_gpg_agent = False
+
+ res = {
+ 'retcode': 1,
+ 'stdout': '',
+ 'stderr': 'initialization value'
+ }
+
+ if gnupghome and env is None:
+ env = {}
+ env['GNUPGHOME'] = gnupghome
+
+ if __grains__.get('osmajorrelease') >= 7:
+ use_gpg_agent = True
if keyid is not None:
# import_keys
@@ -517,8 +555,29 @@
if keyid == gpg_key['keyid'][8:]:
local_uids = gpg_key['uids']
local_keyid = gpg_key['keyid']
+ if use_gpg_agent:
+ local_keygrip_to_use = gpg_key['fingerprint']
+ local_key_fingerprint = gpg_key['fingerprint']
break
+ if use_gpg_agent:
+ cmd = 'gpg --with-keygrip --list-secret-keys'
+ local_keys2_keygrip = __salt__['cmd.run'](cmd, runas=runas, env=env)
+ local_keys2 = iter(local_keys2_keygrip.splitlines())
+ try:
+ for line in local_keys2:
+ if line.startswith('sec'):
+ line_fingerprint = next(local_keys2).lstrip().rstrip()
+ if local_key_fingerprint == line_fingerprint:
+ lkeygrip = next(local_keys2).split('=')
+ local_keygrip_to_use = lkeygrip[1].lstrip().rstrip()
+ break
+ except StopIteration:
+ raise SaltInvocationError(
+ 'unable to find keygrip associated with fingerprint \'{0}\' for keyid \'{1}\''
+ .format(local_key_fingerprint, local_keyid)
+ )
+
if local_keyid is None:
raise SaltInvocationError(
'The key ID \'{0}\' was not found in GnuPG keyring at \'{1}\''
@@ -527,6 +586,15 @@
if use_passphrase:
phrase = __salt__['pillar.get']('gpg_passphrase')
+ if use_gpg_agent:
+ _check_repo_gpg_phrase_utils()
+ cmd = '/usr/libexec/gpg-preset-passphrase --verbose --preset --passphrase "{0}" {1}'.format(phrase, local_keygrip_to_use)
+ retrc = __salt__['cmd.retcode'](cmd, runas=runas, env=env)
+ if retrc != 0:
+ raise SaltInvocationError(
+ 'Failed to preset passphrase, error {1}, '
+ 'check logs for further details'.format(retrc)
+ )
if local_uids:
define_gpg_name = '--define=\'%_signature gpg\' --define=\'%_gpg_name {0}\''.format(
@@ -553,43 +621,54 @@
number_retries = timeout / interval
times_looped = 0
error_msg = 'Failed to sign file {0}'.format(abs_file)
- cmd = 'rpm {0} --addsign {1}'.format(define_gpg_name, abs_file)
- preexec_fn = functools.partial(salt.utils.user.chugid_and_umask, runas, None)
- try:
- stdout, stderr = None, None
- proc = salt.utils.vt.Terminal(
- cmd,
- shell=True,
- preexec_fn=preexec_fn,
- stream_stdout=True,
- stream_stderr=True
- )
- while proc.has_unread_data:
- stdout, stderr = proc.recv()
- if stdout and SIGN_PROMPT_RE.search(stdout):
- # have the prompt for inputting the passphrase
- proc.sendline(phrase)
- else:
- times_looped += 1
+ if use_gpg_agent:
+ cmd = 'rpmsign --verbose --key-id={0} --addsign {1}'.format(local_keyid, abs_file)
+ retrc |= __salt__['cmd.retcode'](cmd, runas=runas, cwd=repodir, use_vt=True, env=env)
+ if retrc != 0:
+ raise SaltInvocationError(
+ 'Signing encountered errors for command \'{0}\', '
+ 'return error {1}, check logs for further details'.format(
+ cmd,
+ retrc)
+ )
+ else:
+ cmd = 'rpm {0} --addsign {1}'.format(define_gpg_name, abs_file)
+ preexec_fn = functools.partial(salt.utils.user.chugid_and_umask, runas, None)
+ try:
+ stdout, stderr = None, None
+ proc = salt.utils.vt.Terminal(
+ cmd,
+ shell=True,
+ preexec_fn=preexec_fn,
+ stream_stdout=True,
+ stream_stderr=True
+ )
+ while proc.has_unread_data:
+ stdout, stderr = proc.recv()
+ if stdout and SIGN_PROMPT_RE.search(stdout):
+ # have the prompt for inputting the passphrase
+ proc.sendline(phrase)
+ else:
+ times_looped += 1
+
+ if times_looped > number_retries:
+ raise SaltInvocationError(
+ 'Attemping to sign file {0} failed, timed out after {1} seconds'
+ .format(abs_file, int(times_looped * interval))
+ )
+ time.sleep(interval)
- if times_looped > number_retries:
+ proc_exitstatus = proc.exitstatus
+ if proc_exitstatus != 0:
raise SaltInvocationError(
- 'Attemping to sign file {0} failed, timed out after {1} seconds'
- .format(abs_file, int(times_looped * interval))
+ 'Signing file {0} failed with proc.status {1}'
+ .format(abs_file, proc_exitstatus)
)
- time.sleep(interval)
-
- proc_exitstatus = proc.exitstatus
- if proc_exitstatus != 0:
- raise SaltInvocationError(
- 'Signing file {0} failed with proc.status {1}'
- .format(abs_file, proc_exitstatus)
- )
- except salt.utils.vt.TerminalException as err:
- trace = traceback.format_exc()
- log.error(error_msg, err, trace)
- finally:
- proc.close(terminate=True, kill=True)
+ except salt.utils.vt.TerminalException as err:
+ trace = traceback.format_exc()
+ log.error(error_msg, err, trace)
+ finally:
+ proc.close(terminate=True, kill=True)
cmd = 'createrepo --update {0}'.format(repodir)
return __salt__['cmd.run_all'](cmd, runas=runas)