simp-rake-helpers 5.11.6 → 5.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +28 -0
- data/CONTRIBUTING.md +1 -1
- data/README.md +1 -1
- data/lib/simp/command_utils.rb +21 -0
- data/lib/simp/local_gpg_signing_key.rb +128 -79
- data/lib/simp/rake.rb +3 -17
- data/lib/simp/rake/build/pkg.rb +102 -40
- data/lib/simp/rake/helpers/version.rb +1 -1
- data/lib/simp/rake/pkg.rb +5 -1
- data/lib/simp/rake/pupmod/helpers.rb +2 -0
- data/lib/simp/rake/rubygem.rb +5 -1
- data/lib/simp/rpm.rb +10 -127
- data/lib/simp/rpm_signer.rb +321 -0
- data/spec/acceptance/00_pkg_rpm_custom_scriptlets_spec.rb +18 -19
- data/spec/acceptance/10_pkg_rpm_spec.rb +46 -48
- data/spec/acceptance/50_local_gpg_signing_key_spec.rb +7 -3
- data/spec/acceptance/55_build_pkg_signing_spec.rb +293 -42
- data/spec/acceptance/files/testpackage/README +8 -0
- data/spec/acceptance/files/testpackage/spec/classes/init_spec.rb +1 -0
- data/spec/acceptance/files/testpackage/spec/files/mock_something.rb +3 -0
- data/spec/acceptance/files/testpackage/utils/convert_v1_to_v2.rb +3 -0
- data/spec/acceptance/nodesets/default.yml +15 -2
- data/spec/acceptance/support/build_project_helpers.rb +32 -8
- data/spec/lib/simp/command_utils_spec.rb +29 -0
- data/spec/lib/simp/local_gpg_signing_key_spec.rb.beaker-only +115 -18
- data/spec/lib/simp/rake/pupmod/fixtures/simpmod/README.md +2 -2
- data/spec/lib/simp/rpm_signer_spec.rb +98 -0
- data/spec/lib/simp/rpm_spec.rb +0 -6
- metadata +12 -67
- data/.travis.yml +0 -41
- data/spec/acceptance/20_pkg_rpm_upgrade_spec.rb +0 -236
- data/spec/acceptance/files/custom_scriptlet_triggers/pupmod-new-package-2.1/CHANGELOG +0 -2
- data/spec/acceptance/files/custom_scriptlet_triggers/pupmod-new-package-2.1/Rakefile +0 -3
- data/spec/acceptance/files/custom_scriptlet_triggers/pupmod-new-package-2.1/build/rpm_metadata/custom/overrides +0 -14
- data/spec/acceptance/files/custom_scriptlet_triggers/pupmod-new-package-2.1/build/rpm_metadata/requires +0 -1
- data/spec/acceptance/files/custom_scriptlet_triggers/pupmod-new-package-2.1/metadata.json +0 -33
- data/spec/acceptance/files/custom_scriptlet_triggers/pupmod-new-package-3.0/CHANGELOG +0 -2
- data/spec/acceptance/files/custom_scriptlet_triggers/pupmod-new-package-3.0/Rakefile +0 -3
- data/spec/acceptance/files/custom_scriptlet_triggers/pupmod-new-package-3.0/build/rpm_metadata/custom/overrides +0 -14
- data/spec/acceptance/files/custom_scriptlet_triggers/pupmod-new-package-3.0/build/rpm_metadata/requires +0 -1
- data/spec/acceptance/files/custom_scriptlet_triggers/pupmod-new-package-3.0/metadata.json +0 -33
- data/spec/acceptance/files/custom_scriptlet_triggers/pupmod-old-package-1.0/CHANGELOG +0 -2
- data/spec/acceptance/files/custom_scriptlet_triggers/pupmod-old-package-1.0/Rakefile +0 -3
- data/spec/acceptance/files/custom_scriptlet_triggers/pupmod-old-package-1.0/build/rpm_metadata/requires +0 -1
- data/spec/acceptance/files/custom_scriptlet_triggers/pupmod-old-package-1.0/metadata.json +0 -33
- data/spec/acceptance/files/custom_scriptlet_triggers/pupmod-old-package-2.0/CHANGELOG +0 -2
- data/spec/acceptance/files/custom_scriptlet_triggers/pupmod-old-package-2.0/Rakefile +0 -3
- data/spec/acceptance/files/custom_scriptlet_triggers/pupmod-old-package-2.0/build/rpm_metadata/requires +0 -1
- data/spec/acceptance/files/custom_scriptlet_triggers/pupmod-old-package-2.0/metadata.json +0 -33
- data/spec/acceptance/files/custom_scriptlet_triggers/pupmod-old-package-2.2/CHANGELOG +0 -2
- data/spec/acceptance/files/custom_scriptlet_triggers/pupmod-old-package-2.2/Rakefile +0 -3
- data/spec/acceptance/files/custom_scriptlet_triggers/pupmod-old-package-2.2/build/rpm_metadata/custom/overrides +0 -14
- data/spec/acceptance/files/custom_scriptlet_triggers/pupmod-old-package-2.2/build/rpm_metadata/requires +0 -1
- data/spec/acceptance/files/custom_scriptlet_triggers/pupmod-old-package-2.2/metadata.json +0 -33
- data/spec/acceptance/files/mock_packages/pupmod-puppetlabs-stdlib.spec +0 -32
- data/spec/acceptance/files/mock_packages/pupmod-simp-foo.spec +0 -32
- data/spec/acceptance/files/mock_packages/pupmod-simp-simplib.spec +0 -32
- data/spec/acceptance/files/mock_packages/rpmbuild.sh +0 -25
- data/spec/acceptance/files/mock_packages/simp-adapter.spec +0 -43
- data/spec/acceptance/files/mock_packages/simp-adapter/etc/simp/adapter_config.yaml +0 -3
- data/spec/acceptance/files/mock_packages/simp-adapter/usr/local/sbin/simp_rpm_helper +0 -495
- data/spec/acceptance/files/package_upgrades/pupmod-simp-testpackage-1.0/CHANGELOG +0 -2
- data/spec/acceptance/files/package_upgrades/pupmod-simp-testpackage-1.0/Rakefile +0 -3
- data/spec/acceptance/files/package_upgrades/pupmod-simp-testpackage-1.0/build/rpm_metadata/requires +0 -2
- data/spec/acceptance/files/package_upgrades/pupmod-simp-testpackage-1.0/data/os/CentOS.yaml +0 -2
- data/spec/acceptance/files/package_upgrades/pupmod-simp-testpackage-1.0/data/os/RedHat.yaml +0 -2
- data/spec/acceptance/files/package_upgrades/pupmod-simp-testpackage-1.0/hiera.yaml +0 -14
- data/spec/acceptance/files/package_upgrades/pupmod-simp-testpackage-1.0/manifests/init.pp +0 -2
- data/spec/acceptance/files/package_upgrades/pupmod-simp-testpackage-1.0/metadata.json +0 -37
- data/spec/acceptance/files/package_upgrades/pupmod-simp-testpackage-2.0/CHANGELOG +0 -5
- data/spec/acceptance/files/package_upgrades/pupmod-simp-testpackage-2.0/Rakefile +0 -3
- data/spec/acceptance/files/package_upgrades/pupmod-simp-testpackage-2.0/build/rpm_metadata/requires +0 -2
- data/spec/acceptance/files/package_upgrades/pupmod-simp-testpackage-2.0/data/os/CentOS.yaml +0 -2
- data/spec/acceptance/files/package_upgrades/pupmod-simp-testpackage-2.0/data/os/RedHat.yaml +0 -2
- data/spec/acceptance/files/package_upgrades/pupmod-simp-testpackage-2.0/hiera.yaml +0 -14
- data/spec/acceptance/files/package_upgrades/pupmod-simp-testpackage-2.0/manifests/init.pp +0 -3
- data/spec/acceptance/files/package_upgrades/pupmod-simp-testpackage-2.0/metadata.json +0 -37
- data/spec/lib/simp/ci/files/job_broken_link_nodeset/spec/acceptance/suites/default/nodesets +0 -1
- data/spec/lib/simp/ci/files/job_invalid_nodeset/spec/acceptance/suites/default/nodesets +0 -1
- data/spec/lib/simp/ci/files/job_invalid_suite/spec/acceptance/suites/default/nodesets +0 -1
- data/spec/lib/simp/ci/files/job_missing_nodeset/spec/acceptance/suites/default/nodesets +0 -1
- data/spec/lib/simp/ci/files/job_missing_suite_and_nodeset/spec/acceptance/suites/default/nodesets +0 -1
- data/spec/lib/simp/ci/files/multiple_invalid_jobs/spec/acceptance/suites/default/nodesets +0 -1
- data/spec/lib/simp/ci/files/multiple_valid_jobs/spec/acceptance/suites/default/nodesets +0 -1
- data/spec/lib/simp/ci/files/no_gitlab_config_with_tests/spec/acceptance/suites/default/nodesets +0 -1
- data/spec/lib/simp/ci/files/no_gitlab_config_without_tests/spec/acceptance/suites/default/nodesets +0 -1
- data/spec/lib/simp/ci/files/suite_skeleton_only/spec/acceptance/nodesets/default.yml +0 -1
- data/spec/lib/simp/ci/files/suite_skeleton_only/spec/acceptance/suites/default/nodesets +0 -1
- data/spec/lib/simp/ci/files/valid_job_nodeset_dir_link/spec/acceptance/suites/default/nodesets +0 -1
- data/spec/lib/simp/ci/files/valid_job_nodeset_link/spec/acceptance/suites/default/nodesets/default.yml +0 -1
- data/spec/lib/simp/files/build/testpackage.spec +0 -1
- data/spec/lib/simp/rake/pupmod/fixtures/simpmod/spec/acceptance/nodesets/default.yml +0 -1
- data/spec/lib/simp/rake/pupmod/fixtures/simpmod/spec/acceptance/suites/default/nodesets +0 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1d979c12113e415884ec44b2880134bde9e20a3efc99495520e3518a994118f6
|
|
4
|
+
data.tar.gz: f9da255f0c077f662f00757ca2428b9375b1b4bd2d39de1b484c1a047d87c1f4
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 493c503f1ead3608b3718e113188ef08af8905d96fd7297f439adc4809c44e70f4ec6b1c3d08c1eb09458ef4ab1499db61ec3519f1d18ab297e1b8812c5620d1
|
|
7
|
+
data.tar.gz: bf8bd8cbbf5c36ac268a23e346554a6f7132523f5f32a3f76162fdc8d77dd01898362d51dadd6012e2e07efb08e61737c1398c123e09092b422b94e631a0b43a
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,31 @@
|
|
|
1
|
+
### 5.12.0 / 2021-02-16
|
|
2
|
+
- Ensure that pkg:install_gem uses the correct documentation options for the
|
|
3
|
+
version of Ruby in use.
|
|
4
|
+
- Disable brp-mangle-shebangs when building RPMs.
|
|
5
|
+
- Mitigated problem where gpg-agent daemon fails to start because
|
|
6
|
+
its socket path is longer than 108 characters.
|
|
7
|
+
- Changed the default location of the GPG keys directory used in the
|
|
8
|
+
pkg:key_prep and pkg:signrpms Rake tasks to <base_dir>/.dev_gpgkeys.
|
|
9
|
+
- Added a SIMP_PKG_build_keys_dir environment variable that overrides
|
|
10
|
+
the default location of the GPG keys directory used in the
|
|
11
|
+
pkg:key_prep and pkg:signrpms Rake tasks.
|
|
12
|
+
- Added SIMP_PKG_rpmsign_timeout environment variable that overrides
|
|
13
|
+
default timeout in seconds to wait for an individual RPM signing
|
|
14
|
+
operation to complete.
|
|
15
|
+
- Default timeout is 30 seconds.
|
|
16
|
+
- Most relevant when signing on RPMs on EL8 and the gpg-agent
|
|
17
|
+
started by rpmsign fails to start, but rpmsign does not detect
|
|
18
|
+
the failure and hangs.
|
|
19
|
+
- Improved pkg:signrpms error handling and reporting.
|
|
20
|
+
- Fixed bug in GPG handling for GPG 2.1+ in which an existing
|
|
21
|
+
GPG key that was not cached internally was not detected.
|
|
22
|
+
- Fixed bug where pkg:signrpms failed to sign RPMs on EL8.
|
|
23
|
+
- Fixed bug where pkg:checksig reported failure on EL8, even when
|
|
24
|
+
the signatures were valid.
|
|
25
|
+
- Deprecated the following top-level Rake tasks for Puppet modules:
|
|
26
|
+
- compare_latest_tag: use pkg:compare_latest_tag instead
|
|
27
|
+
- changelog_annotation: use pkg:create_tag_changelog instead
|
|
28
|
+
|
|
1
29
|
### 5.11.6 / 2021-02-03
|
|
2
30
|
* Fix GPG handling for GPG 2.1+
|
|
3
31
|
|
data/CONTRIBUTING.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
## Contributing
|
|
2
2
|
|
|
3
|
-
Please refer to the main [SIMP Project Contributing Guide](https://
|
|
3
|
+
Please refer to the main [SIMP Project Contributing Guide](https://simp-doc.readthedocs.io/en/stable/contributors_guide/index.html)
|
|
4
4
|
for details on contributing to this project.
|
data/README.md
CHANGED
|
@@ -39,7 +39,7 @@ The `simp-rake-helpers` gem provides common Rake tasks to support the SIMP build
|
|
|
39
39
|
|
|
40
40
|
### This gem is part of SIMP
|
|
41
41
|
|
|
42
|
-
This gem is part of (the build tooling for) the [System Integrity Management Platform](https://
|
|
42
|
+
This gem is part of (the build tooling for) the [System Integrity Management Platform](https://simp-project.com), a compliance-management framework built on [Puppet](https://puppetlabs.com/).
|
|
43
43
|
|
|
44
44
|
|
|
45
45
|
### Features
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
module Simp; end
|
|
2
|
+
module Simp::CommandUtils
|
|
3
|
+
require 'facter'
|
|
4
|
+
|
|
5
|
+
def which(cmd, fail=false)
|
|
6
|
+
@which_cache ||= {}
|
|
7
|
+
|
|
8
|
+
if @which_cache.has_key?(cmd)
|
|
9
|
+
command = @which_cache[cmd]
|
|
10
|
+
else
|
|
11
|
+
command = Facter::Core::Execution.which(cmd)
|
|
12
|
+
@which_cache[cmd] = command
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
msg = "Warning: Command #{cmd} not found on the system."
|
|
16
|
+
|
|
17
|
+
( fail ? raise(msg) : warn(msg) ) unless command
|
|
18
|
+
|
|
19
|
+
command
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
require 'securerandom'
|
|
2
2
|
require 'rake'
|
|
3
|
+
require 'simp/command_utils'
|
|
3
4
|
|
|
4
5
|
module Simp
|
|
5
6
|
# Ensure that a valid GPG signing key exists in a local directory
|
|
@@ -14,49 +15,52 @@ module Simp
|
|
|
14
15
|
# - New keys are generated using a temporary GPG agent with its own
|
|
15
16
|
# settings and socket.
|
|
16
17
|
#
|
|
17
|
-
# The local signing key's directory
|
|
18
|
+
# The local signing key's directory includes the following:
|
|
19
|
+
# gpg < 2.1.0 (EL7):
|
|
18
20
|
#
|
|
19
21
|
# ```
|
|
20
22
|
# #{key_name}/ # key directory
|
|
21
23
|
# +-- RPM-GPG-KEY-SIMP-#{key_name} # key file
|
|
22
24
|
# +-- gengpgkey # --gen-key params file **
|
|
25
|
+
# +-- gpg-agent-info.env # Lists location of gpg-agent socket + pid
|
|
26
|
+
# +-- run_gpg_agnet # Script used to start gpg-agent
|
|
23
27
|
# +-- pubring.gpg
|
|
24
28
|
# +-- secring.gpg
|
|
25
|
-
# +--
|
|
29
|
+
# +-- trustdb.gpg
|
|
26
30
|
# ```
|
|
27
31
|
#
|
|
28
|
-
#
|
|
32
|
+
# gpg >= 2.1.0 (EL8):
|
|
33
|
+
# ```
|
|
34
|
+
# #{key_name}/ # key directory
|
|
35
|
+
# +-- RPM-GPG-KEY-SIMP-#{key_name} # key file
|
|
36
|
+
# +-- gengpgkey # --gen-key params file **
|
|
37
|
+
# +-- openpgp-revocs.d/<fingerprint id>.rev
|
|
38
|
+
# +-- private-keys-v1.d/<user id>.key
|
|
39
|
+
# +-- pubring.kbx
|
|
40
|
+
# +-- trustdb.gpg
|
|
41
|
+
# ```
|
|
42
|
+
#
|
|
43
|
+
# `**` = `SIMP::RpmSigner.sign_rpms` will use the values in the `gengpgkey` file
|
|
29
44
|
# for the GPG signing key's email and passphrase
|
|
30
45
|
#
|
|
31
46
|
# If a new key is required, a project-only `gpg-agent` daemon is momentarily
|
|
32
47
|
# created to generate it, and destroyed after this is done. The daemon does
|
|
33
|
-
# not interact with any other `gpg-agent` daemons on the system
|
|
34
|
-
# launched on
|
|
35
|
-
# #{key_name/} directory.
|
|
36
|
-
#
|
|
37
|
-
# When instantiated, the daemon writes an "env-file" to the #{key_name}
|
|
38
|
-
# directory. This file specifies the location of the daemon's socket and
|
|
39
|
-
# pid.
|
|
40
|
-
#
|
|
41
|
-
# A typical env-file looks like:
|
|
42
|
-
#
|
|
43
|
-
# ```sh
|
|
44
|
-
# GPG_AGENT_INFO=/tmp/gpg-4yhfOB/S.gpg-agent:15495:1
|
|
45
|
-
# ```
|
|
48
|
+
# not interact with any other `gpg-agent` daemons on the system. It is
|
|
49
|
+
# launched on random socket(s) whose socket file(s) can be found as follows:
|
|
46
50
|
#
|
|
47
|
-
#
|
|
48
|
-
#
|
|
51
|
+
# Location Environment
|
|
52
|
+
# #{key_name} dir Docker container for EL8
|
|
53
|
+
# temp dir in /run/user/<uid>/gnupg EL8
|
|
54
|
+
# temp dir in /tmp EL7
|
|
49
55
|
#
|
|
50
|
-
# ```sh
|
|
51
|
-
# GPG_AGENT_INFO=/tmp/gpg-4yhfOB/S.gpg-agent:15495:1; export GPG_AGENT_INFO;\n"
|
|
52
|
-
# ```
|
|
53
56
|
class LocalGpgSigningKey
|
|
54
57
|
include FileUtils
|
|
58
|
+
include Simp::CommandUtils
|
|
55
59
|
|
|
56
|
-
# `SIMP::
|
|
60
|
+
# `SIMP::RpmSigner.sign_rpms` will look for a 'gengpgkey' file to
|
|
57
61
|
# non-interactively sign packages.
|
|
58
62
|
#
|
|
59
|
-
# @see SIMP::
|
|
63
|
+
# @see SIMP::RpmSigner.sign_rpms
|
|
60
64
|
GPG_GENKEY_PARAMS_FILENAME = 'gengpgkey'.freeze
|
|
61
65
|
|
|
62
66
|
# @param dir [String] path to gpg-agent / key directory
|
|
@@ -74,11 +78,12 @@ module Simp
|
|
|
74
78
|
@key_file = opts[:file] || "RPM-GPG-KEY-SIMP-#{@label.capitalize}"
|
|
75
79
|
@verbose = opts[:verbose] || false
|
|
76
80
|
|
|
81
|
+
# for EL7 only
|
|
77
82
|
@gpg_agent_env_file = 'gpg-agent-info.env'
|
|
78
83
|
@gpg_agent_script = 'run_gpg_agent'
|
|
79
84
|
end
|
|
80
85
|
|
|
81
|
-
# Return the version of GPG
|
|
86
|
+
# Return the version of GPG installed on the system
|
|
82
87
|
#
|
|
83
88
|
# @return [Gem::Version]
|
|
84
89
|
def gpg_version
|
|
@@ -111,17 +116,45 @@ module Simp
|
|
|
111
116
|
info
|
|
112
117
|
end
|
|
113
118
|
|
|
114
|
-
# Return the number of days left before the GPG signing key expires
|
|
119
|
+
# Return the number of days left before the GPG signing key expires or
|
|
120
|
+
# 0 if the key does not exist or the key is missing an expiration date.
|
|
115
121
|
def dev_key_days_left
|
|
122
|
+
which('gpg', true)
|
|
116
123
|
ensure_gpg_directory
|
|
117
|
-
days_left = 0
|
|
118
124
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
125
|
+
days_left = 0
|
|
126
|
+
cmd = "gpg --with-colons --homedir=#{@dir} --list-keys '<#{@key_email}>' 2>&1"
|
|
127
|
+
puts "Executing: #{cmd}" if @verbose
|
|
128
|
+
%x(#{cmd}).each_line do |line|
|
|
129
|
+
# See https://github.com/CSNW/gnupg/blob/master/doc/DETAILS
|
|
130
|
+
# Index Content
|
|
131
|
+
# 0 record type
|
|
132
|
+
# 6 expiration date
|
|
133
|
+
#
|
|
134
|
+
# If expiration date contains a 'T', it is in an ISO 8601 format
|
|
135
|
+
# (e.g., 20210223T091500). Otherwise it is seconds since the epoch.
|
|
136
|
+
#
|
|
137
|
+
fields = line.split(':')
|
|
138
|
+
if fields[0] && (fields[0] == 'pub')
|
|
139
|
+
raw_exp_date = fields[6]
|
|
140
|
+
unless raw_exp_date.nil? || raw_exp_date.strip.empty?
|
|
141
|
+
require 'date'
|
|
142
|
+
|
|
143
|
+
exp_date = nil
|
|
144
|
+
if raw_exp_date.include?('T')
|
|
145
|
+
exp_date = DateTime.parse(raw_exp_date).to_date
|
|
146
|
+
else
|
|
147
|
+
exp_date = Time.at(raw_exp_date.to_i).to_date
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
days_left = (exp_date - Date.today).to_i
|
|
151
|
+
days_left = 0 if days_left < 0
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
break
|
|
155
|
+
end
|
|
124
156
|
end
|
|
157
|
+
|
|
125
158
|
days_left
|
|
126
159
|
end
|
|
127
160
|
|
|
@@ -153,55 +186,16 @@ module Simp
|
|
|
153
186
|
|
|
154
187
|
clean_gpg_agent_directory
|
|
155
188
|
write_genkey_parameter_file
|
|
156
|
-
write_gpg_agent_startup_script
|
|
157
189
|
|
|
190
|
+
agent_info = nil
|
|
158
191
|
begin
|
|
159
192
|
if gpg_version < Gem::Version.new('2.1')
|
|
160
|
-
|
|
161
|
-
gpg_agent_output = %x(./#{@gpg_agent_script}).strip
|
|
162
|
-
|
|
163
|
-
# Provide a local socket (needed by the `gpg` command when
|
|
164
|
-
local_socket = File.join(Dir.pwd, 'S.gpg-agent')
|
|
165
|
-
|
|
166
|
-
# This condition was handled differently in previous logic.
|
|
167
|
-
#
|
|
168
|
-
# a.) As the surrounding logic works now, it will _always_ be a new
|
|
169
|
-
# agent by this point, because the directory is cleaned out
|
|
170
|
-
# b.) The agent's information will be read from the env-file it
|
|
171
|
-
# writes at startup
|
|
172
|
-
# c.) The old command `gpg-agent --homedir=#{Dir.pwd} /get serverpid`
|
|
173
|
-
# did not work on EL6 or EL7.
|
|
174
|
-
#
|
|
175
|
-
warn(empty_gpg_agent_message) if gpg_agent_output.empty?
|
|
176
|
-
|
|
177
|
-
agent_info = gpg_agent_info
|
|
178
|
-
|
|
179
|
-
# The socket is useful to get back info on the command line.
|
|
180
|
-
unless File.exist?(File.join(Dir.pwd, File.basename(agent_info[:socket])))
|
|
181
|
-
ln_s(agent_info[:socket], local_socket, :verbose => @verbose)
|
|
182
|
-
end
|
|
183
|
-
|
|
184
|
-
generate_key(agent_info[:info])
|
|
193
|
+
agent_info = start_gpg_agent_old
|
|
185
194
|
else
|
|
186
|
-
|
|
187
|
-
which('gpg-agent', true)
|
|
188
|
-
which('gpg-connect-agent', true)
|
|
189
|
-
|
|
190
|
-
# Start the GPG agent
|
|
191
|
-
%x{gpg-agent --homedir=#{Dir.pwd} >&/dev/null || gpg-agent --homedir=#{Dir.pwd} --daemon >&/dev/null}
|
|
192
|
-
|
|
193
|
-
agent_info = {}
|
|
194
|
-
|
|
195
|
-
# Provide a local socket (needed by the `gpg` command when
|
|
196
|
-
agent_info[:socket] = %x{echo 'GETINFO socket_name' | gpg-connect-agent --homedir=#{Dir.pwd}}.lines.first[1..-1].strip
|
|
197
|
-
|
|
198
|
-
# Get the pid
|
|
199
|
-
agent_info[:pid] = %x{echo 'GETINFO pid' | gpg-connect-agent --homedir=#{Dir.pwd}}.lines.first[1..-1].strip.to_i
|
|
200
|
-
|
|
201
|
-
generate_key(%{#{agent_info[:socket]}:#{agent_info[:pid]}:1})
|
|
195
|
+
agent_info = start_gpg_agent
|
|
202
196
|
end
|
|
203
197
|
ensure
|
|
204
|
-
kill_agent(agent_info[:pid])
|
|
198
|
+
kill_agent(agent_info[:pid]) if agent_info
|
|
205
199
|
end
|
|
206
200
|
|
|
207
201
|
agent_info
|
|
@@ -213,7 +207,7 @@ module Simp
|
|
|
213
207
|
#
|
|
214
208
|
# @return [String] Warning message
|
|
215
209
|
def empty_gpg_agent_message
|
|
216
|
-
|
|
210
|
+
<<~WARNING
|
|
217
211
|
WARNING: Tried to start an project-only gpg-agent daemon on a random socket by
|
|
218
212
|
running the script:
|
|
219
213
|
|
|
@@ -234,7 +228,6 @@ module Simp
|
|
|
234
228
|
#
|
|
235
229
|
# @param pid [String] The GPG Agent PID to kill
|
|
236
230
|
def kill_agent(pid)
|
|
237
|
-
rm('S.gpg-agent') if File.symlink?('S.gpg-agent')
|
|
238
231
|
if pid
|
|
239
232
|
Process.kill(0, pid)
|
|
240
233
|
Process.kill(15, pid)
|
|
@@ -254,8 +247,8 @@ module Simp
|
|
|
254
247
|
gpg_cmd = %(GPG_AGENT_INFO=#{gpg_agent_info_str} gpg --homedir="#{@dir}")
|
|
255
248
|
|
|
256
249
|
pipe = @verbose ? '| tee' : '>'
|
|
257
|
-
|
|
258
|
-
|
|
250
|
+
%x(#{gpg_cmd} --batch --gen-key #{GPG_GENKEY_PARAMS_FILENAME})
|
|
251
|
+
%x(#{gpg_cmd} --armor --export '<#{@key_email}>' #{pipe} "#{@key_file}")
|
|
259
252
|
|
|
260
253
|
if File.stat(@key_file).size == 0
|
|
261
254
|
fail "Error: Something went wrong generating #{@key_file}"
|
|
@@ -271,6 +264,62 @@ module Simp
|
|
|
271
264
|
{ info: info.strip, socket: matches[:socket], pid: matches[:pid].to_i }
|
|
272
265
|
end
|
|
273
266
|
|
|
267
|
+
# Start the gpg-agent
|
|
268
|
+
# @return Hash of agent info
|
|
269
|
+
# @raise if gpg-agent fails to start
|
|
270
|
+
def start_gpg_agent
|
|
271
|
+
which('gpg', true)
|
|
272
|
+
which('gpg-agent', true)
|
|
273
|
+
which('gpg-connect-agent', true)
|
|
274
|
+
|
|
275
|
+
# Start the GPG agent, if it is not already running
|
|
276
|
+
check_agent = "gpg-agent -q --homedir=#{Dir.pwd} >&/dev/null"
|
|
277
|
+
start_agent = "gpg-agent --homedir=#{Dir.pwd} --daemon >&/dev/null"
|
|
278
|
+
cmd = "#{check_agent} || #{start_agent}"
|
|
279
|
+
puts "Executing: #{cmd}" if @verbose
|
|
280
|
+
%x(#{cmd})
|
|
281
|
+
if $? && ($?.exitstatus != 0)
|
|
282
|
+
err_msg = [
|
|
283
|
+
'Failed to start gpg-agent during key creation.',
|
|
284
|
+
" Execute '#{start_agent.gsub(' >&/dev/null','')}' to debug."
|
|
285
|
+
].join("\n")
|
|
286
|
+
raise(err_msg)
|
|
287
|
+
end
|
|
288
|
+
|
|
289
|
+
agent_info = {}
|
|
290
|
+
|
|
291
|
+
# Provide a local socket (needed by the `gpg` command when
|
|
292
|
+
agent_info[:socket] = %x{echo 'GETINFO socket_name' | gpg-connect-agent --homedir=#{Dir.pwd}}.lines.first[1..-1].strip
|
|
293
|
+
|
|
294
|
+
# Get the pid
|
|
295
|
+
agent_info[:pid] = %x{echo 'GETINFO pid' | gpg-connect-agent --homedir=#{Dir.pwd}}.lines.first[1..-1].strip.to_i
|
|
296
|
+
|
|
297
|
+
generate_key(%{#{agent_info[:socket]}:#{agent_info[:pid]}:1})
|
|
298
|
+
|
|
299
|
+
agent_info
|
|
300
|
+
end
|
|
301
|
+
|
|
302
|
+
# Start the gpg-agent with options suitable for gpg version < 2.1
|
|
303
|
+
# @return Hash of agent info
|
|
304
|
+
def start_gpg_agent_old
|
|
305
|
+
write_gpg_agent_startup_script
|
|
306
|
+
gpg_agent_output = %x(./#{@gpg_agent_script}).strip
|
|
307
|
+
|
|
308
|
+
# By the time we get here, we can be assured we will be starting a
|
|
309
|
+
# new agent, because the directory is cleaned out.
|
|
310
|
+
#
|
|
311
|
+
# Follow-on gpg actions will read the agent's information from
|
|
312
|
+
# the env-file the agent writes at startup.
|
|
313
|
+
|
|
314
|
+
# We're using the --sh option which will spew out the agent config
|
|
315
|
+
# when the agent starts. If it is empty, this is a problem.
|
|
316
|
+
warn(empty_gpg_agent_message) if gpg_agent_output.empty?
|
|
317
|
+
|
|
318
|
+
agent_info = gpg_agent_info
|
|
319
|
+
generate_key(agent_info[:info])
|
|
320
|
+
agent_info
|
|
321
|
+
end
|
|
322
|
+
|
|
274
323
|
# Write the `gpg --genkey --batch` control parameter file
|
|
275
324
|
#
|
|
276
325
|
# @see "Unattended key generation" in /usr/share/doc/gnupg2-*/DETAILS for
|
|
@@ -311,7 +360,7 @@ module Simp
|
|
|
311
360
|
which('gpg-agent', true)
|
|
312
361
|
pinentry_cmd = which('pinentry-curses', true)
|
|
313
362
|
|
|
314
|
-
gpg_agent_script =
|
|
363
|
+
gpg_agent_script = <<~AGENT_SCRIPT
|
|
315
364
|
#!/bin/sh
|
|
316
365
|
|
|
317
366
|
gpg-agent --homedir=#{Dir.pwd} --daemon \
|
data/lib/simp/rake.rb
CHANGED
|
@@ -9,9 +9,12 @@ module Simp::Rake
|
|
|
9
9
|
require 'parallel'
|
|
10
10
|
require 'tempfile'
|
|
11
11
|
require 'facter'
|
|
12
|
+
require 'simp/command_utils'
|
|
12
13
|
require 'simp/rpm'
|
|
13
14
|
require 'simp/rake/pkg'
|
|
14
15
|
|
|
16
|
+
include Simp::CommandUtils
|
|
17
|
+
|
|
15
18
|
attr_reader(:puppetfile)
|
|
16
19
|
attr_reader(:module_paths)
|
|
17
20
|
|
|
@@ -96,23 +99,6 @@ module Simp::Rake
|
|
|
96
99
|
exec pager rescue exec "/bin/sh", "-c", pager
|
|
97
100
|
end
|
|
98
101
|
|
|
99
|
-
def which(cmd, fail=false)
|
|
100
|
-
@which_cache ||= {}
|
|
101
|
-
|
|
102
|
-
if @which_cache.has_key?(cmd)
|
|
103
|
-
command = @which_cache[cmd]
|
|
104
|
-
else
|
|
105
|
-
command = Facter::Core::Execution.which(cmd)
|
|
106
|
-
@which_cache[cmd] = command
|
|
107
|
-
end
|
|
108
|
-
|
|
109
|
-
msg = "Warning: Command #{cmd} not found on the system."
|
|
110
|
-
|
|
111
|
-
fail ? raise(msg) : warn(msg) unless command
|
|
112
|
-
|
|
113
|
-
command
|
|
114
|
-
end
|
|
115
|
-
|
|
116
102
|
def help
|
|
117
103
|
run_pager
|
|
118
104
|
|
data/lib/simp/rake/build/pkg.rb
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/rake -T
|
|
2
2
|
|
|
3
3
|
require 'simp/yum'
|
|
4
|
-
require 'simp/local_gpg_signing_key.rb'
|
|
5
4
|
require 'simp/rake/pkg'
|
|
6
5
|
require 'simp/rake/build/constants'
|
|
7
6
|
require 'simp/rake/build/rpmdeps'
|
|
@@ -17,9 +16,18 @@ module Simp::Rake::Build
|
|
|
17
16
|
def initialize( base_dir )
|
|
18
17
|
init_member_vars( base_dir )
|
|
19
18
|
|
|
19
|
+
@cpu_limit = get_cpu_limit
|
|
20
20
|
@verbose = ENV.fetch('SIMP_PKG_verbose','no') == 'yes'
|
|
21
21
|
@rpm_build_metadata = 'last_rpm_build_metadata.yaml'
|
|
22
22
|
@rpm_dependency_file = File.join(@base_dir, 'build', 'rpm', 'dependencies.yaml')
|
|
23
|
+
@build_keys_dir = ENV.fetch('SIMP_PKG_build_keys_dir', File.join(@base_dir, '.dev_gpgkeys'))
|
|
24
|
+
@long_gpg_socket_err_msg = <<~EOM
|
|
25
|
+
If the problem is 'socket name <xxx> is too long', use SIMP_PKG_build_keys_dir
|
|
26
|
+
to override
|
|
27
|
+
#{@build_keys_dir}
|
|
28
|
+
with a shorter path. The socket name must be < 108 characters.
|
|
29
|
+
|
|
30
|
+
EOM
|
|
23
31
|
|
|
24
32
|
define_tasks
|
|
25
33
|
end
|
|
@@ -66,7 +74,7 @@ module Simp::Rake::Build
|
|
|
66
74
|
@build_dirs.each_pair do |k,dirs|
|
|
67
75
|
Parallel.map(
|
|
68
76
|
Array(dirs),
|
|
69
|
-
:in_processes =>
|
|
77
|
+
:in_processes => @cpu_limit,
|
|
70
78
|
:progress => t.name
|
|
71
79
|
) do |dir|
|
|
72
80
|
Dir.chdir(dir) do
|
|
@@ -95,7 +103,7 @@ module Simp::Rake::Build
|
|
|
95
103
|
@build_dirs.each_pair do |k,dirs|
|
|
96
104
|
Parallel.map(
|
|
97
105
|
Array(dirs),
|
|
98
|
-
:in_processes =>
|
|
106
|
+
:in_processes => @cpu_limit,
|
|
99
107
|
:progress => t.name
|
|
100
108
|
) do |dir|
|
|
101
109
|
Dir.chdir(dir) do
|
|
@@ -109,36 +117,49 @@ module Simp::Rake::Build
|
|
|
109
117
|
desc <<-EOM
|
|
110
118
|
Prepare a GPG signing key to sign build packages
|
|
111
119
|
|
|
112
|
-
* :key - the name of the
|
|
113
|
-
|
|
120
|
+
* :key - the name of the build keys subdirectory to prepare
|
|
121
|
+
(defaults to 'dev')
|
|
122
|
+
|
|
123
|
+
- The default build keys directory is
|
|
124
|
+
`#{@build_keys_dir}`
|
|
125
|
+
|
|
114
126
|
|
|
115
127
|
When :key is `dev`, a temporary signing key is created, if needed:
|
|
116
128
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
-
|
|
129
|
+
* A 14-day `dev` key will be created if none exists or the existing
|
|
130
|
+
key has expired. This includes creating
|
|
131
|
+
- A `dev` directory in the build keys directory
|
|
132
|
+
- gpg-agent assets to create/update the key within that `dev`
|
|
133
|
+
directory
|
|
120
134
|
|
|
121
135
|
When :key is *not* `dev`, the logic is much stricter:
|
|
122
136
|
|
|
123
|
-
- You must already have
|
|
124
|
-
|
|
137
|
+
- You must already have created the `<:key>` subdirectory within
|
|
138
|
+
the build keys directory and placed a valid GPG signing key and
|
|
139
|
+
requisite gpg-agent assets to access the key within the directory.
|
|
125
140
|
- If the directory or key are missing, the task will fail.
|
|
126
141
|
|
|
127
142
|
ENV vars:
|
|
128
143
|
- Set `SIMP_PKG_verbose=yes` to report file operations as they happen.
|
|
144
|
+
- Set `SIMP_PKG_build_keys_dir` to override the default build keys path.
|
|
129
145
|
EOM
|
|
130
146
|
task :key_prep,[:key] => [:prep] do |t,args|
|
|
131
147
|
args.with_defaults(:key => 'dev')
|
|
132
148
|
key = args.key
|
|
133
|
-
|
|
134
|
-
key_dir = File.join(build_keys_dir,key)
|
|
149
|
+
key_dir = File.join(@build_keys_dir,key)
|
|
135
150
|
dvd_dir = @dvd_src
|
|
136
151
|
|
|
137
|
-
FileUtils.mkdir_p build_keys_dir
|
|
152
|
+
FileUtils.mkdir_p @build_keys_dir
|
|
138
153
|
|
|
139
|
-
Dir.chdir(build_keys_dir) do
|
|
154
|
+
Dir.chdir(@build_keys_dir) do
|
|
140
155
|
if key == 'dev'
|
|
141
|
-
|
|
156
|
+
require 'simp/local_gpg_signing_key'
|
|
157
|
+
|
|
158
|
+
begin
|
|
159
|
+
Simp::LocalGpgSigningKey.new(key_dir,{verbose: @verbose}).ensure_key
|
|
160
|
+
rescue Exception => e
|
|
161
|
+
raise("#{e.message}\n\n#{@long_gpg_socket_err_msg}")
|
|
162
|
+
end
|
|
142
163
|
else
|
|
143
164
|
unless File.directory?(key_dir)
|
|
144
165
|
fail("Could not find GPG keydir '#{key_dir}' in '#{Dir.pwd}'")
|
|
@@ -356,41 +377,79 @@ module Simp::Rake::Build
|
|
|
356
377
|
Sign a set of RPMs.
|
|
357
378
|
|
|
358
379
|
Signs any unsigned RPMs in the specified directory
|
|
359
|
-
* :key - The key directory to use under
|
|
360
|
-
*
|
|
380
|
+
* :key - The key directory to use under the build keys directory
|
|
381
|
+
* key defaults to 'dev'
|
|
382
|
+
* build keys directory defaults to
|
|
383
|
+
`#{@build_keys_dir}`
|
|
361
384
|
* :rpm_dir - A directory containing RPM files to sign. Will recurse!
|
|
362
|
-
* Defaults to '
|
|
385
|
+
* Defaults to #{File.join(File.dirname(@rpm_dir), '*RPMS')}
|
|
363
386
|
* :force - Force rpms that are already signed to be resigned
|
|
364
387
|
* Defaults to 'false', can be enabled with 'true'
|
|
388
|
+
* :digest_algo - Digest algorithm to be used when signing the RPMs
|
|
389
|
+
* Defaults to 'sha256'
|
|
390
|
+
|
|
391
|
+
ENV vars:
|
|
392
|
+
* Set `SIMP_RPM_verbose=yes` to report RPM operations as they happen.
|
|
393
|
+
* Set `SIMP_PKG_build_keys_dir` to override the default build keys path.
|
|
394
|
+
* Set `SIMP_PKG_rpmsign_timeout` to override the maximum time in seconds
|
|
395
|
+
to wait for an individual RPM signing operation to complete.
|
|
396
|
+
- Defaults to 60 seconds.
|
|
365
397
|
EOM
|
|
366
|
-
task :signrpms,[:key,:rpm_dir,:force] => [:prep,:key_prep] do |t,args|
|
|
367
|
-
|
|
398
|
+
task :signrpms,[:key,:rpm_dir,:force,:digest_algo] => [:prep,:key_prep] do |t,args|
|
|
399
|
+
require 'simp/rpm_signer'
|
|
368
400
|
|
|
369
401
|
args.with_defaults(:key => 'dev')
|
|
370
402
|
args.with_defaults(:rpm_dir => File.join(File.dirname(@rpm_dir), '*RPMS'))
|
|
371
403
|
args.with_defaults(:force => 'false')
|
|
404
|
+
args.with_defaults(:digest_algo => 'sha256')
|
|
372
405
|
|
|
373
406
|
force = (args[:force].to_s == 'false' ? false : true)
|
|
407
|
+
timeout = ENV['SIMP_PKG_rpmsign_timeout'] ? ENV['SIMP_PKG_rpmsign_timeout'].to_i : 60
|
|
408
|
+
|
|
409
|
+
opts = {
|
|
410
|
+
:digest_algo => args[:digest_algo],
|
|
411
|
+
:force => force,
|
|
412
|
+
:max_concurrent => @cpu_limit,
|
|
413
|
+
:progress_bar_title => t.name,
|
|
414
|
+
:timeout_seconds => timeout,
|
|
415
|
+
:verbose => @verbose
|
|
416
|
+
}
|
|
374
417
|
|
|
375
|
-
|
|
376
|
-
|
|
418
|
+
results = nil
|
|
419
|
+
begin
|
|
420
|
+
results = Simp::RpmSigner.sign_rpms(
|
|
421
|
+
args[:rpm_dir],
|
|
422
|
+
File.join(@build_keys_dir, args[:key]),
|
|
423
|
+
opts
|
|
424
|
+
)
|
|
425
|
+
rescue Exception => e
|
|
426
|
+
raise("#{e.message}\n\n#{@long_gpg_socket_err_msg}")
|
|
427
|
+
end
|
|
377
428
|
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
429
|
+
if results
|
|
430
|
+
successes = results.select { |rpm,status| status == :signed }
|
|
431
|
+
failures = results.select { |rpm,status| status == :unsigned }
|
|
432
|
+
already_signed = results.select { |rpm,status| status == :skipped_already_signed }
|
|
433
|
+
|
|
434
|
+
if opts[:verbose]
|
|
435
|
+
puts
|
|
436
|
+
puts 'Summary'
|
|
437
|
+
puts '======='
|
|
438
|
+
puts "# RPMs already signed: #{already_signed.size}"
|
|
439
|
+
puts "# RPMs successfully signed: #{successes.size}"
|
|
440
|
+
puts "# RPM signing failures: #{failures.size}"
|
|
441
|
+
puts
|
|
382
442
|
end
|
|
383
|
-
end
|
|
384
443
|
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
444
|
+
if !failures.empty?
|
|
445
|
+
if ((results.size - already_signed.size) == (failures.size))
|
|
446
|
+
detail = already_signed.empty? ? '' : 'unsigned '
|
|
447
|
+
raise("ERROR: Failed to sign all #{detail}RPMs in #{args[:rpm_dir]}")
|
|
448
|
+
else
|
|
449
|
+
err_msg = "ERROR: Failed to sign some RPMs in #{args[:rpm_dir]}:\n"
|
|
450
|
+
err_msg += " #{failures.keys.join("\n ")}"
|
|
451
|
+
raise(err_msg)
|
|
452
|
+
end
|
|
394
453
|
end
|
|
395
454
|
end
|
|
396
455
|
end
|
|
@@ -446,7 +505,9 @@ module Simp::Rake::Build
|
|
|
446
505
|
$stderr.puts "pkg:checksig: Warning no GPG keys found in #{key_dirs_tried}"
|
|
447
506
|
end
|
|
448
507
|
end
|
|
449
|
-
|
|
508
|
+
|
|
509
|
+
# be sure to include any development keys packaged with the DVD
|
|
510
|
+
public_keys += Dir.glob(File.join(@dvd_src, 'RPM-GPG-KEY*'))
|
|
450
511
|
|
|
451
512
|
# Only import thngs that look like GPG keys...
|
|
452
513
|
public_keys.each do |key|
|
|
@@ -464,8 +525,9 @@ module Simp::Rake::Build
|
|
|
464
525
|
rpm_dirs.each do |rpm_dir|
|
|
465
526
|
Find.find(rpm_dir) do |path|
|
|
466
527
|
if (path =~ /.*\.rpm$/)
|
|
467
|
-
|
|
468
|
-
|
|
528
|
+
%x{#{rpm_cmd} --checksig #{path}}.strip
|
|
529
|
+
result = $?
|
|
530
|
+
unless result && (result.exitstatus == 0)
|
|
469
531
|
bad_rpms << path.split(/\s/).first
|
|
470
532
|
end
|
|
471
533
|
end
|
|
@@ -862,7 +924,7 @@ protect=1
|
|
|
862
924
|
Parallel.map(
|
|
863
925
|
# Allow for shell globs
|
|
864
926
|
Array(dirs),
|
|
865
|
-
:in_processes =>
|
|
927
|
+
:in_processes => @cpu_limit,
|
|
866
928
|
:progress => task.name
|
|
867
929
|
) do |dir|
|
|
868
930
|
fail("Could not find directory #{dir}") unless Dir.exist?(dir)
|