simp-rake-helpers 5.3.0 → 5.4.1
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/.gitignore +8 -2
- data/.travis.yml +54 -37
- data/CHANGELOG.md +40 -2
- data/Gemfile +1 -0
- data/README.md +70 -82
- data/lib/simp/rake/build/auto.rb +6 -0
- data/lib/simp/rake/build/pkg.rb +2 -2
- data/lib/simp/rake/build/rpmdeps.rb +6 -3
- data/lib/simp/rake/helpers/assets/rpm_spec/simpdefault.spec +284 -71
- data/lib/simp/rake/helpers/version.rb +1 -1
- data/lib/simp/rake/pkg.rb +38 -18
- data/lib/simp/rake/rubygem.rb +1 -1
- data/lib/simp/rpm.rb +49 -6
- data/spec/acceptance/00_pkg_rpm_custom_scriptlets_spec.rb +117 -0
- data/spec/acceptance/10_pkg_rpm_spec.rb +153 -0
- data/spec/acceptance/20_pkg_rpm_safely_upgrading_obsolete_modules_spec.rb +175 -0
- data/spec/acceptance/development/docker_env.sh +29 -0
- data/spec/acceptance/development/rerun_acceptance_tests.sh +15 -0
- data/spec/acceptance/development/vagrant_rsync.sh +23 -0
- data/spec/acceptance/files/custom_scriptlet_triggers/pupmod-new-package-2.1/CHANGELOG +2 -0
- data/spec/acceptance/files/custom_scriptlet_triggers/pupmod-new-package-2.1/Rakefile +3 -0
- data/spec/acceptance/files/custom_scriptlet_triggers/pupmod-new-package-2.1/build/rpm_metadata/custom/overrides +14 -0
- data/spec/acceptance/files/custom_scriptlet_triggers/pupmod-new-package-2.1/build/rpm_metadata/requires +1 -0
- data/spec/acceptance/files/custom_scriptlet_triggers/pupmod-new-package-2.1/metadata.json +33 -0
- data/spec/acceptance/files/custom_scriptlet_triggers/pupmod-new-package-3.0/CHANGELOG +2 -0
- data/spec/acceptance/files/custom_scriptlet_triggers/pupmod-new-package-3.0/Rakefile +3 -0
- data/spec/acceptance/files/custom_scriptlet_triggers/pupmod-new-package-3.0/build/rpm_metadata/custom/overrides +14 -0
- data/spec/acceptance/files/custom_scriptlet_triggers/pupmod-new-package-3.0/build/rpm_metadata/requires +1 -0
- data/spec/acceptance/files/custom_scriptlet_triggers/pupmod-new-package-3.0/metadata.json +33 -0
- data/spec/acceptance/files/custom_scriptlet_triggers/pupmod-old-package-1.0/CHANGELOG +2 -0
- data/spec/acceptance/files/custom_scriptlet_triggers/pupmod-old-package-1.0/Rakefile +3 -0
- data/spec/acceptance/files/custom_scriptlet_triggers/pupmod-old-package-1.0/build/rpm_metadata/requires +1 -0
- data/spec/acceptance/files/custom_scriptlet_triggers/pupmod-old-package-1.0/metadata.json +33 -0
- data/spec/acceptance/files/custom_scriptlet_triggers/pupmod-old-package-2.0/CHANGELOG +2 -0
- data/spec/acceptance/files/custom_scriptlet_triggers/pupmod-old-package-2.0/Rakefile +3 -0
- data/spec/acceptance/files/custom_scriptlet_triggers/pupmod-old-package-2.0/build/rpm_metadata/requires +1 -0
- data/spec/acceptance/files/custom_scriptlet_triggers/pupmod-old-package-2.0/metadata.json +33 -0
- data/spec/acceptance/files/custom_scriptlet_triggers/pupmod-old-package-2.2/CHANGELOG +2 -0
- data/spec/acceptance/files/custom_scriptlet_triggers/pupmod-old-package-2.2/Rakefile +3 -0
- data/spec/acceptance/files/custom_scriptlet_triggers/pupmod-old-package-2.2/build/rpm_metadata/custom/overrides +14 -0
- data/spec/acceptance/files/custom_scriptlet_triggers/pupmod-old-package-2.2/build/rpm_metadata/requires +1 -0
- data/spec/acceptance/files/custom_scriptlet_triggers/pupmod-old-package-2.2/metadata.json +33 -0
- data/spec/acceptance/files/mock_packages/pupmod-puppetlabs-stdlib.spec +32 -0
- data/spec/acceptance/files/mock_packages/pupmod-simp-foo.spec +32 -0
- data/spec/acceptance/files/mock_packages/pupmod-simp-simplib.spec +32 -0
- data/spec/acceptance/files/mock_packages/rpmbuild.sh +25 -0
- data/spec/acceptance/files/mock_packages/simp-adapter/etc/simp/adapter_config.yaml +3 -0
- data/spec/acceptance/files/mock_packages/simp-adapter/usr/local/sbin/simp_rpm_helper +406 -0
- data/spec/acceptance/files/mock_packages/simp-adapter.spec +43 -0
- data/spec/acceptance/files/testpackage_custom_scriptlet/CHANGELOG +2 -0
- data/spec/acceptance/files/testpackage_custom_scriptlet/Rakefile +3 -0
- data/spec/acceptance/files/testpackage_custom_scriptlet/build/rpm_metadata/custom/overrides +18 -0
- data/spec/acceptance/files/testpackage_custom_scriptlet/build/rpm_metadata/requires +1 -0
- data/spec/acceptance/files/testpackage_custom_scriptlet/metadata.json +33 -0
- data/spec/acceptance/nodesets/default.yml +2 -4
- data/spec/acceptance/support/pkg_rpm_helpers.rb +81 -0
- data/spec/lib/simp/rake/build/files/unmanaged_mod/build/rpm_metadata/requires +2 -1
- data/spec/lib/simp/rake/build/rpmdeps_spec.rb +2 -1
- data/spec/spec_helper_acceptance.rb +20 -1
- metadata +44 -17
- data/spec/acceptance/pkg_rpm_spec.rb +0 -164
@@ -0,0 +1,406 @@
|
|
1
|
+
#!/opt/puppetlabs/puppet/bin/ruby
|
2
|
+
#
|
3
|
+
# Purpose
|
4
|
+
# -------
|
5
|
+
#
|
6
|
+
# This script is meant to be called by the %preun and %post sections of the
|
7
|
+
# various SIMP Puppet module RPMs.
|
8
|
+
#
|
9
|
+
# The purpose of the script is to provide helper methods that correctly
|
10
|
+
# scaffold the system in such a way that all SIMP Puppet Modules can be
|
11
|
+
# installed via RPM to a single location and subsequently can be copied into
|
12
|
+
# the standard SIMP installation location based on the version of Puppet that
|
13
|
+
# is installed.
|
14
|
+
#
|
15
|
+
# Care is taken that, should the target directory be managed via 'git', this
|
16
|
+
# script will do nothing to harm the managed installation in any way. This
|
17
|
+
# ensures that the SIMP modules have maximum compatibility with the widest
|
18
|
+
# possible range of Puppet module best practices for management while ensuring
|
19
|
+
# that the RPM installations and upgrades can proceed in a seamless fashion
|
20
|
+
# over time.
|
21
|
+
#
|
22
|
+
# Should the 'simp' environment not be found, the script will simply exit
|
23
|
+
# without copying any files.
|
24
|
+
#
|
25
|
+
# Configuration
|
26
|
+
# -------------
|
27
|
+
#
|
28
|
+
# A configuration file may be placed at /etc/simp/adapter_config.yaml. The
|
29
|
+
# file must consist of proper YAML as demonstrated in the example below which
|
30
|
+
# lists the default options.
|
31
|
+
#
|
32
|
+
# Any configuration options that are not understood will be ignored.
|
33
|
+
#
|
34
|
+
# ```yaml
|
35
|
+
# ---
|
36
|
+
# # Target directory
|
37
|
+
# # May be set to a fully qualified path or 'auto'
|
38
|
+
# # If set to 'auto', the directory will be determined from puppet itself
|
39
|
+
#
|
40
|
+
# target_directory : 'auto'
|
41
|
+
#
|
42
|
+
# # Copy the RPM data to the target directory
|
43
|
+
#
|
44
|
+
# copy_rpm_data : false
|
45
|
+
#
|
46
|
+
# ```
|
47
|
+
#
|
48
|
+
|
49
|
+
require 'facter'
|
50
|
+
require 'fileutils'
|
51
|
+
require 'yaml'
|
52
|
+
require 'optparse'
|
53
|
+
require 'ostruct'
|
54
|
+
require 'find'
|
55
|
+
|
56
|
+
# Make sure we can find the Puppet executables
|
57
|
+
ENV['PATH'] += ':/opt/puppetlabs/bin'
|
58
|
+
|
59
|
+
# Get the Puppet configuration parameters currently in use
|
60
|
+
def get_puppet_config
|
61
|
+
system_config = %x{puppet config --section master print}
|
62
|
+
|
63
|
+
config_hash = Hash.new
|
64
|
+
|
65
|
+
system_config.each_line do |line|
|
66
|
+
k,v = line.split('=')
|
67
|
+
config_hash[k.strip] = v.strip
|
68
|
+
end
|
69
|
+
|
70
|
+
return config_hash
|
71
|
+
end
|
72
|
+
|
73
|
+
# A more friendly failure message
|
74
|
+
def fail(msg)
|
75
|
+
$stderr.puts(msg)
|
76
|
+
exit(1)
|
77
|
+
end
|
78
|
+
|
79
|
+
# Determine whether the passed path is under management by git or svn
|
80
|
+
def is_managed?(path)
|
81
|
+
# Short circuit if the directory is not present
|
82
|
+
return false unless File.directory?(path)
|
83
|
+
|
84
|
+
git = Facter::Core::Execution.which('git')
|
85
|
+
svn = Facter::Core::Execution.which('svn')
|
86
|
+
|
87
|
+
Dir.chdir(path) do
|
88
|
+
if git
|
89
|
+
%x{#{git} ls-files . --error-unmatch &> /dev/null}
|
90
|
+
|
91
|
+
return true if $?.success?
|
92
|
+
end
|
93
|
+
|
94
|
+
if svn
|
95
|
+
%x{#{svn} info &> /dev/null}
|
96
|
+
|
97
|
+
return true if $?.success?
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
return false
|
102
|
+
end
|
103
|
+
|
104
|
+
def parse_options
|
105
|
+
options = OpenStruct.new
|
106
|
+
options.config_file = '/etc/simp/adapter_config.yaml'
|
107
|
+
options.preserve = false
|
108
|
+
# These are not settable, but it's nice to have all this material in one place
|
109
|
+
options.puppet_user = @puppet_config['user']
|
110
|
+
options.puppet_group = @puppet_config['group']
|
111
|
+
|
112
|
+
all_opts = OptionParser.new do |opts|
|
113
|
+
opts.banner = "Usage: #{$0} [options]"
|
114
|
+
|
115
|
+
opts.separator ""
|
116
|
+
|
117
|
+
opts.on(
|
118
|
+
"--rpm_dir PATH",
|
119
|
+
"The directory into which the RPM source material is installed"
|
120
|
+
) do |arg|
|
121
|
+
options.rpm_dir = arg.strip
|
122
|
+
options.module_name = File.basename(options.rpm_dir)
|
123
|
+
end
|
124
|
+
|
125
|
+
opts.on(
|
126
|
+
"--rpm_section SECTION",
|
127
|
+
"The section of the RPM from which the script is being called.",
|
128
|
+
" Must be one of 'pre', 'post', 'preun', 'postun'"
|
129
|
+
) do |arg|
|
130
|
+
options.rpm_section = arg.strip
|
131
|
+
end
|
132
|
+
|
133
|
+
opts.on(
|
134
|
+
"--rpm_status STATUS",
|
135
|
+
"The status code passed to the RPM section"
|
136
|
+
) do |arg|
|
137
|
+
options.rpm_status = arg.strip
|
138
|
+
end
|
139
|
+
|
140
|
+
opts.on(
|
141
|
+
"-f CONFIG_FILE",
|
142
|
+
"--config CONFIG_FILE",
|
143
|
+
"The configuration file to use",
|
144
|
+
" Default: #{options.config_file}"
|
145
|
+
) do |arg|
|
146
|
+
options.config_file = arg.strip
|
147
|
+
end
|
148
|
+
|
149
|
+
opts.on(
|
150
|
+
"-p",
|
151
|
+
"--preserve",
|
152
|
+
"Preserve material in 'target_dir' that is not in 'rpm_dir'"
|
153
|
+
) do |arg|
|
154
|
+
options.preserve = true
|
155
|
+
end
|
156
|
+
|
157
|
+
opts.on(
|
158
|
+
"-e",
|
159
|
+
"--enforce",
|
160
|
+
"If set, enforce the copy, regardless of the setting in the config file",
|
161
|
+
" Default: false"
|
162
|
+
) do |arg|
|
163
|
+
options.copy_rpm_data = true
|
164
|
+
end
|
165
|
+
|
166
|
+
opts.on(
|
167
|
+
"-t DIR",
|
168
|
+
"--target_dir DIR",
|
169
|
+
"The subdirectory of #{simp_target_dir('')}",
|
170
|
+
"into which to copy the materials.",
|
171
|
+
" Default: #{simp_target_dir.gsub(/#{simp_target_dir('')}/,'')}"
|
172
|
+
) do |arg|
|
173
|
+
options.target_dir = simp_target_dir(arg.strip)
|
174
|
+
end
|
175
|
+
|
176
|
+
opts.on(
|
177
|
+
"-h",
|
178
|
+
"--help",
|
179
|
+
"Help Message"
|
180
|
+
) do
|
181
|
+
puts opts
|
182
|
+
exit(0)
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
begin
|
187
|
+
all_opts.parse!(ARGV)
|
188
|
+
rescue OptionParser::ParseError => e
|
189
|
+
puts e
|
190
|
+
puts all_opts
|
191
|
+
exit 1
|
192
|
+
end
|
193
|
+
|
194
|
+
validate_options(options, all_opts.to_s)
|
195
|
+
|
196
|
+
return options
|
197
|
+
end
|
198
|
+
|
199
|
+
# Process the config, validate the entries and do some munging
|
200
|
+
# Return an options hash
|
201
|
+
def process_config(config_file, options=OpenStruct.new)
|
202
|
+
# Defaults
|
203
|
+
config = {
|
204
|
+
'target_directory' => 'auto',
|
205
|
+
'copy_rpm_data' => false
|
206
|
+
}
|
207
|
+
|
208
|
+
if File.exist?(config_file)
|
209
|
+
begin
|
210
|
+
system_config = YAML.load_file(config_file)
|
211
|
+
if system_config
|
212
|
+
config.merge!(system_config)
|
213
|
+
end
|
214
|
+
rescue
|
215
|
+
fail("Error: Config file '#{config_file}' could not be processed")
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
if options.copy_rpm_data.nil?
|
220
|
+
options.copy_rpm_data = (config['copy_rpm_data'].to_s == 'true')
|
221
|
+
end
|
222
|
+
|
223
|
+
if options.target_dir.nil? && config['target_directory']
|
224
|
+
if config['target_directory'] == 'auto'
|
225
|
+
options.target_dir = simp_target_dir
|
226
|
+
else
|
227
|
+
unless config['target_directory'][0].chr == '/'
|
228
|
+
fail("Error: 'target_directory' in '#{config_file}' must be an absolute path")
|
229
|
+
end
|
230
|
+
|
231
|
+
options.target_dir = config['target_directory'].strip
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
return options
|
236
|
+
end
|
237
|
+
|
238
|
+
def puppet_codedir
|
239
|
+
# Figure out where the Puppet code should go
|
240
|
+
# Puppet 4+
|
241
|
+
code_dir = @puppet_config['codedir']
|
242
|
+
if !code_dir || code_dir.empty?
|
243
|
+
code_dir = @puppet_config['confdir']
|
244
|
+
end
|
245
|
+
|
246
|
+
return code_dir
|
247
|
+
end
|
248
|
+
|
249
|
+
# Return the target installation directory
|
250
|
+
def simp_target_dir(subdir=File.join('simp','modules'))
|
251
|
+
install_target = puppet_codedir
|
252
|
+
|
253
|
+
if install_target.empty?
|
254
|
+
fail('Error: Could not find a Puppet code directory for installation')
|
255
|
+
end
|
256
|
+
|
257
|
+
install_target = File.join(install_target,'environments', subdir)
|
258
|
+
|
259
|
+
return install_target
|
260
|
+
end
|
261
|
+
|
262
|
+
# Input Validation
|
263
|
+
def validate_options(options, usage)
|
264
|
+
|
265
|
+
unless options.rpm_dir
|
266
|
+
fail("Error: 'rpm_dir' is required\n#{usage}")
|
267
|
+
end
|
268
|
+
|
269
|
+
unless options.rpm_status
|
270
|
+
fail("Error: 'rpm_status' is required\n#{usage}")
|
271
|
+
end
|
272
|
+
|
273
|
+
unless options.rpm_section
|
274
|
+
fail("Error: 'rpm_section' is required\n#{usage}")
|
275
|
+
end
|
276
|
+
|
277
|
+
valid_rpm_sections = ['pre','post','preun','postun']
|
278
|
+
|
279
|
+
unless valid_rpm_sections.include?(options.rpm_section)
|
280
|
+
fail("Error: 'rpm_section' must be one of '#{valid_rpm_sections.join("', '")}'\n#{usage}")
|
281
|
+
end
|
282
|
+
|
283
|
+
if (options.rpm_section == 'post') || (options.rpm_section == 'preun')
|
284
|
+
unless File.directory?(options.rpm_dir)
|
285
|
+
fail("Error: Could not find 'rpm_dir': '#{options.rpm_dir}'")
|
286
|
+
end
|
287
|
+
end
|
288
|
+
|
289
|
+
unless options.rpm_status =~ /^\d+$/
|
290
|
+
fail("Error: 'rpm_status' must be an integer\n#{usage}")
|
291
|
+
end
|
292
|
+
|
293
|
+
fail('Error: Could not determine puppet user') if options.puppet_user.empty?
|
294
|
+
fail('Error: Could not determine puppet group') if options.puppet_group.empty?
|
295
|
+
end
|
296
|
+
|
297
|
+
### Main Code
|
298
|
+
|
299
|
+
@puppet_config = get_puppet_config
|
300
|
+
options = parse_options
|
301
|
+
options = process_config(options.config_file, options)
|
302
|
+
|
303
|
+
# A list of modules that should never be touched once installed
|
304
|
+
safe_modules = ['site']
|
305
|
+
|
306
|
+
# If the target directory is managed, we're done
|
307
|
+
unless is_managed?(File.join(options.target_dir, options.module_name)) || !options.copy_rpm_data
|
308
|
+
|
309
|
+
rsync = Facter::Core::Execution.which('rsync')
|
310
|
+
fail("Error: Could not find 'rsync' command!") unless rsync
|
311
|
+
|
312
|
+
# A regular installation or upgrade
|
313
|
+
if options.rpm_section == 'post'
|
314
|
+
if safe_modules.include?(options.module_name)
|
315
|
+
# Make sure that we preserve anything in the safe modules on installation
|
316
|
+
options.preserve = true
|
317
|
+
|
318
|
+
if options.rpm_status == '2'
|
319
|
+
# Short circuit on upgrading safe modules, just don't touch them!
|
320
|
+
if File.directory?(File.join(options.target_dir, options.module_name))
|
321
|
+
exit(0)
|
322
|
+
end
|
323
|
+
end
|
324
|
+
end
|
325
|
+
|
326
|
+
# Create the directories, with the proper mode, all the way down
|
327
|
+
dir_paths = options.target_dir.split(File::SEPARATOR).reject(&:empty?)
|
328
|
+
top_dir = File::SEPARATOR + dir_paths.shift
|
329
|
+
unless File.directory?(top_dir)
|
330
|
+
FileUtils.mkdir(top_dir, :mode => 0750)
|
331
|
+
FileUtils.chown('root', options.puppet_group, top_dir)
|
332
|
+
end
|
333
|
+
|
334
|
+
orig_dir = Dir.pwd
|
335
|
+
Dir.chdir(top_dir)
|
336
|
+
dir_paths.each do |dir|
|
337
|
+
unless File.directory?(dir)
|
338
|
+
FileUtils.mkdir(dir, :mode => 0750)
|
339
|
+
FileUtils.chown('root', options.puppet_group, dir)
|
340
|
+
end
|
341
|
+
|
342
|
+
Dir.chdir(dir)
|
343
|
+
end
|
344
|
+
Dir.chdir(orig_dir)
|
345
|
+
|
346
|
+
cmd = %(#{rsync} -a --force)
|
347
|
+
|
348
|
+
if options.preserve
|
349
|
+
cmd += %( --ignore-existing)
|
350
|
+
else
|
351
|
+
cmd += %( --delete)
|
352
|
+
end
|
353
|
+
|
354
|
+
cmd += %( #{options.rpm_dir} #{options.target_dir})
|
355
|
+
cmd += %( 2>&1)
|
356
|
+
|
357
|
+
output = %x{#{cmd}}
|
358
|
+
unless $?.success?
|
359
|
+
fail(%(Error: Copy of '#{options.module_name}' into '#{options.target_dir}' using '#{cmd}' failed with the following error:\n #{output.gsub("\n","\n ")}))
|
360
|
+
end
|
361
|
+
|
362
|
+
FileUtils.chown_R(nil, "#{options.puppet_group}", options.target_dir)
|
363
|
+
end
|
364
|
+
|
365
|
+
# A regular uninstall or downgrade
|
366
|
+
# This needs to happen *before* we uninstall since we need to compare with what's on disk
|
367
|
+
if options.rpm_section == 'preun' && options.rpm_status == '0'
|
368
|
+
# Play it safe, this needs to have at least 'environments/simp' in it!
|
369
|
+
if options.target_dir.split(File::SEPARATOR).reject(&:empty?).size < 3
|
370
|
+
fail("Error: Not removing directory '#{options.target_dir}' for safety")
|
371
|
+
else
|
372
|
+
unless safe_modules.include?(options.module_name)
|
373
|
+
# Find out what we have
|
374
|
+
ref_list = []
|
375
|
+
Dir.chdir(options.rpm_dir) do
|
376
|
+
Find.find('.').each do |file|
|
377
|
+
if File.symlink?(file)
|
378
|
+
ref_list << file
|
379
|
+
Find.prune
|
380
|
+
end
|
381
|
+
|
382
|
+
ref_list << file
|
383
|
+
end
|
384
|
+
end
|
385
|
+
|
386
|
+
# Delete from the bottom up to clear out the directories first
|
387
|
+
ref_list.reverse!
|
388
|
+
ref_list.map{|x| x.sub!(/^./, options.module_name)}
|
389
|
+
|
390
|
+
# Only delete items that are in the reference repo
|
391
|
+
Dir.chdir(options.target_dir) do
|
392
|
+
ref_list.each do |to_rm|
|
393
|
+
if File.symlink?(to_rm)
|
394
|
+
FileUtils.rm_f(to_rm)
|
395
|
+
elsif File.directory?(to_rm) && (Dir.entries(to_rm).delete_if {|dir|
|
396
|
+
dir == '.' || dir == '..'}.size == 0)
|
397
|
+
FileUtils.rmdir(to_rm)
|
398
|
+
elsif File.exist?(to_rm)
|
399
|
+
FileUtils.rm_f(to_rm)
|
400
|
+
end
|
401
|
+
end
|
402
|
+
end
|
403
|
+
end
|
404
|
+
end
|
405
|
+
end
|
406
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
Name: simp-adapter
|
2
|
+
Version: 0.9.9
|
3
|
+
Release: 9
|
4
|
+
Summary: mock simplib test package
|
5
|
+
BuildArch: noarch
|
6
|
+
|
7
|
+
License: Apache-2.0
|
8
|
+
URL: http://foo.bar
|
9
|
+
|
10
|
+
Source0: files.tar.gz
|
11
|
+
|
12
|
+
%description
|
13
|
+
A mock RPM package used for acceptance tests
|
14
|
+
|
15
|
+
%prep
|
16
|
+
echo ================ PWD: $PWD
|
17
|
+
%setup -c
|
18
|
+
|
19
|
+
%build
|
20
|
+
|
21
|
+
|
22
|
+
%install
|
23
|
+
[ "%{buildroot}" != "/" ] && rm -rf %{buildroot}
|
24
|
+
mkdir -p %{buildroot}/opt/test/puppet/code
|
25
|
+
cp -r $PWD/* %{buildroot}/
|
26
|
+
rm -rf %{buildroot}/**/.*.swp
|
27
|
+
rm -rf %{buildroot}/opt/puppetlabs
|
28
|
+
|
29
|
+
%clean
|
30
|
+
|
31
|
+
%files
|
32
|
+
%defattr(0640,root,root,0755)
|
33
|
+
|
34
|
+
%attr(0750,root,root)/usr/local/sbin/simp_rpm_helper
|
35
|
+
#%attr(0755,root,root)/opt/puppetlabs/puppet/bin/ruby
|
36
|
+
#%attr(0755,root,root)/opt/puppetlabs/bin/puppet
|
37
|
+
%attr(0644,root,root)/etc/simp/adapter_config.yaml
|
38
|
+
%dir /opt/test/puppet/code
|
39
|
+
|
40
|
+
|
41
|
+
%changelog
|
42
|
+
* Fri Feb 23 2018 nobody
|
43
|
+
- some comment
|
@@ -0,0 +1,18 @@
|
|
1
|
+
%pretrans -p <lua>
|
2
|
+
-- Custom scriptlet
|
3
|
+
|
4
|
+
%triggerun -- bar
|
5
|
+
# Custom trigger
|
6
|
+
echo "This trigger runs just before the 'bar' package's %%preun"
|
7
|
+
|
8
|
+
%triggerun -- foo
|
9
|
+
# Custom trigger
|
10
|
+
echo "The 'foo' package is great; why would you uninstall it?"
|
11
|
+
|
12
|
+
%pre
|
13
|
+
# Custom scriptlet override
|
14
|
+
echo 'I override the default %%pre section provided by the spec file.'
|
15
|
+
|
16
|
+
%triggerun -- foo
|
17
|
+
# Custom trigger
|
18
|
+
echo "This is a duplicate definition and won't be included"
|
@@ -0,0 +1 @@
|
|
1
|
+
Requires: pupmod-simp-foo >= 1.2.3
|
@@ -0,0 +1,33 @@
|
|
1
|
+
{
|
2
|
+
"name": "simp-testpackage",
|
3
|
+
"version": "0.0.1",
|
4
|
+
"author": "simp",
|
5
|
+
"summary": "A SIMP Test Package for Testing Test Things",
|
6
|
+
"license": "Apache-2.0",
|
7
|
+
"source": "https://github.com/simp/pupmod-imatest",
|
8
|
+
"project_page": "https://github.com/simp/pupmod-imatest",
|
9
|
+
"issues_url": "https://simp/project.atlassian.net",
|
10
|
+
"tags": [ "simp", "test"],
|
11
|
+
"dependencies": [
|
12
|
+
{
|
13
|
+
"name": "simp/simplib",
|
14
|
+
"version_requirement": ">= 1.1.0"
|
15
|
+
}
|
16
|
+
],
|
17
|
+
"operatingsystem_support": [
|
18
|
+
{
|
19
|
+
"operatingsystem": "CentOS",
|
20
|
+
"operatingsystemrelease": [
|
21
|
+
"6",
|
22
|
+
"7"
|
23
|
+
]
|
24
|
+
},
|
25
|
+
{
|
26
|
+
"operatingsystem": "RedHat",
|
27
|
+
"operatingsystemrelease": [
|
28
|
+
"6",
|
29
|
+
"7"
|
30
|
+
]
|
31
|
+
}
|
32
|
+
]
|
33
|
+
}
|
@@ -15,8 +15,7 @@ HOSTS:
|
|
15
15
|
- 'useradd -b /home -m -c "Build User" -s /bin/bash -U build_user'
|
16
16
|
- 'yum install -y facter'
|
17
17
|
# simp build-deps
|
18
|
-
- 'yum install -y rpm-build augeas-devel createrepo genisoimage git gnupg2 libicu-devel libxml2 libxml2-devel libxslt libxslt-devel
|
19
|
-
- 'usermod -a -G mock build_user'
|
18
|
+
- 'yum install -y rpm-build augeas-devel createrepo genisoimage git gnupg2 libicu-devel libxml2 libxml2-devel libxslt libxslt-devel rpmdevtools which'
|
20
19
|
# rvm build-deps
|
21
20
|
- 'yum install -y libyaml-devel glibc-headers autoconf gcc-c++ glibc-devel readline-devel libffi-devel openssl-devel automake libtool bison sqlite-devel'
|
22
21
|
- 'runuser build_user -l -c "gpg2 --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3"'
|
@@ -51,8 +50,7 @@ HOSTS:
|
|
51
50
|
- 'useradd -b /home -m -c "Build User" -s /bin/bash -U build_user'
|
52
51
|
- 'yum install -y facter'
|
53
52
|
# simp build-deps
|
54
|
-
- 'yum install -y rpm-build augeas-devel createrepo genisoimage git gnupg2 libicu-devel libxml2 libxml2-devel libxslt libxslt-devel
|
55
|
-
- 'usermod -a -G mock build_user'
|
53
|
+
- 'yum install -y rpm-build augeas-devel createrepo genisoimage git gnupg2 libicu-devel libxml2 libxml2-devel libxslt libxslt-devel rpmdevtools clamav-update which'
|
56
54
|
# rvm build-deps
|
57
55
|
- 'yum install -y libyaml-devel glibc-headers autoconf gcc-c++ glibc-devel readline-devel libffi-devel openssl-devel automake libtool bison sqlite-devel'
|
58
56
|
- 'runuser build_user -l -c "gpg2 --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3"'
|
@@ -0,0 +1,81 @@
|
|
1
|
+
module Simp::BeakerHelpers::SimpRakeHelpers::PkgRpmHelpers
|
2
|
+
|
3
|
+
# rake command string to run on hosts
|
4
|
+
# passes on useful troubleshooting env vars
|
5
|
+
def rake_cmd
|
6
|
+
cmd = 'bundle exec rake'
|
7
|
+
%w(
|
8
|
+
SIMP_RPM_LUA_debug
|
9
|
+
SIMP_RAKE_PKG_verbose
|
10
|
+
SIMP_RPM_verbose
|
11
|
+
).each do |env_var|
|
12
|
+
if value = ENV[env_var]
|
13
|
+
cmd = "#{env_var}=#{value} #{cmd}"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
cmd
|
17
|
+
end
|
18
|
+
|
19
|
+
|
20
|
+
def copy_host_files_into_build_user_homedir(
|
21
|
+
hosts,
|
22
|
+
root_dir=File.expand_path('../../../',__FILE__)
|
23
|
+
)
|
24
|
+
# I've added the `ch* -R` on the SUT-side, which seems to work on a fresh checkout
|
25
|
+
on hosts, 'cp -a /host_files /home/build_user/; ' +
|
26
|
+
'chmod -R go=u-w /home/build_user/host_files/{dist,**/dist,junit,log}; ' +
|
27
|
+
'chown -R build_user:build_user /home/build_user/host_files; '
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
# key = what `rpm -q --scripts` calls each scriptlet
|
32
|
+
# value = the label passed to `simp_rpm_helper`
|
33
|
+
def scriptlet_label_map
|
34
|
+
{
|
35
|
+
'pretrans' => nil,
|
36
|
+
'preinstall' => 'pre',
|
37
|
+
'postinstall' => 'post',
|
38
|
+
'preuninstall' => 'preun',
|
39
|
+
'postuninstall' => 'postun',
|
40
|
+
'posttrans' => nil,
|
41
|
+
}
|
42
|
+
end
|
43
|
+
|
44
|
+
|
45
|
+
# returns a Hash of information about an RPM file's scriptlets
|
46
|
+
def rpm_scriptlets_for( host, rpm_file )
|
47
|
+
_labels = scriptlet_label_map.keys.join('|')
|
48
|
+
rx_scriptlet_blocks = /^(?<block>(?<scriptlet>#{_labels}) scriptlet.*?(\r|\n)(?<content>.*?))(?=\n#{_labels}|\Z)/m
|
49
|
+
|
50
|
+
result = on host, %Q(rpm -qp --scripts #{rpm_file})
|
51
|
+
|
52
|
+
scriptlets = {}
|
53
|
+
result.stdout.to_s.scan(rx_scriptlet_blocks) do
|
54
|
+
scriptlet = scriptlets[$~[:scriptlet]] ||= { :count => 0 }
|
55
|
+
scriptlet[:count] += 1
|
56
|
+
scriptlet[:content] = $~[:content].strip
|
57
|
+
scriptlet[:full_block] = $~[:block]
|
58
|
+
scriptlet[:bare_content] = scriptlet[:content].gsub(/^((--|#).*?[\r\n]+)/,'')
|
59
|
+
end
|
60
|
+
scriptlets
|
61
|
+
end
|
62
|
+
|
63
|
+
|
64
|
+
# returns a Hash of information about an RPM file's triggers
|
65
|
+
def rpm_triggers_for( host, rpm_file )
|
66
|
+
_trigger = 'trigger\\w+ scriptlet \\(using [\\/a-z0-9]+\\) --(!?\\p{Graph}|\\s)*?'
|
67
|
+
rx_trigger_blocks = /^(?<block>(?<trigger>#{_trigger})[\r\n](?<content>.*?)(?=\n#{_trigger}|\Z))/m
|
68
|
+
|
69
|
+
result = on host, %Q(rpm -qp --triggers #{rpm_file})
|
70
|
+
|
71
|
+
triggers = {}
|
72
|
+
result.stdout.to_s.scan(rx_trigger_blocks) do
|
73
|
+
trigger= triggers[$~[:trigger]] ||= { :count => 0 }
|
74
|
+
trigger[:count] += 1
|
75
|
+
trigger[:content] = $~[:content].strip
|
76
|
+
trigger[:full_block] = $~[:block]
|
77
|
+
trigger[:bare_content] = trigger[:content].gsub(/^((--|#).*?[\r\n]+)/,'')
|
78
|
+
end
|
79
|
+
triggers
|
80
|
+
end
|
81
|
+
end
|
@@ -1,4 +1,5 @@
|
|
1
|
-
Obsoletes: pupmod-unmanaged_mod-test
|
1
|
+
Obsoletes: pupmod-unmanaged_mod-test < 0.0.1
|
2
|
+
Provides: pupmod-unmanaged_mod-test = 0.0.1
|
2
3
|
Requires: pupmod-puppetlabs-inifile < 2.0.0-0
|
3
4
|
Requires: pupmod-puppetlabs-inifile >= 1.6.0-0
|
4
5
|
Requires: pupmod-puppetlabs-postgresql < 5.0.0-0
|
@@ -63,7 +63,8 @@ describe 'Simp::Rake::Build::RpmDeps#generate_rpm_meta_files' do
|
|
63
63
|
requires_file = File.join(mod_dir, 'build', 'rpm_metadata', 'requires')
|
64
64
|
expect(File.exist?(requires_file)).to be true
|
65
65
|
expected = <<EOM
|
66
|
-
Obsoletes: pupmod-oldowner-changed_name_mod
|
66
|
+
Obsoletes: pupmod-oldowner-changed_name_mod < 2.5.0-2016.obsolete
|
67
|
+
Provides: pupmod-oldowner-changed_name_mod = 2.5.0-2016.obsolete
|
67
68
|
Requires: pupmod-foo1-bar1 = 1.0.0
|
68
69
|
Requires: pupmod-foo2-bar2 > 2.0.0
|
69
70
|
Requires: pupmod-foo3-bar3 < 3.0.0
|
@@ -1,9 +1,28 @@
|
|
1
1
|
require 'beaker-rspec'
|
2
|
-
require 'tmpdir'
|
3
2
|
require 'simp/beaker_helpers'
|
4
3
|
include Simp::BeakerHelpers
|
4
|
+
require 'tmpdir'
|
5
|
+
require 'pry' if ENV['PRY'] == 'yes'
|
6
|
+
|
7
|
+
$LOAD_PATH.unshift(File.expand_path('../acceptance/support',__FILE__))
|
8
|
+
|
9
|
+
module Simp::BeakerHelpers::SimpRakeHelpers
|
10
|
+
# Add RSpec log comments within examples ("it blocks")
|
11
|
+
def comment(msg, indent=10)
|
12
|
+
logger.optionally_color(Beaker::Logger::MAGENTA, " "*indent + msg)
|
13
|
+
end
|
14
|
+
|
15
|
+
# basic command + arguments for executing `runuser` within an SUT
|
16
|
+
def run_cmd
|
17
|
+
@run_cmd ||= 'runuser build_user -l -c '
|
18
|
+
end
|
19
|
+
end
|
5
20
|
|
6
21
|
RSpec.configure do |c|
|
22
|
+
# provide helper methods to individual examples AND example groups
|
23
|
+
c.include Simp::BeakerHelpers::SimpRakeHelpers
|
24
|
+
c.extend Simp::BeakerHelpers::SimpRakeHelpers
|
25
|
+
|
7
26
|
# Readable test descriptions
|
8
27
|
c.formatter = :documentation
|
9
28
|
|