puppet 2.7.23 → 2.7.24

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of puppet might be problematic. Click here for more details.

Files changed (43) hide show
  1. data/Gemfile +23 -7
  2. data/ext/packaging/LICENSE +17 -0
  3. data/ext/packaging/README.md +92 -18
  4. data/ext/packaging/spec/tasks/00_utils_spec.rb +28 -21
  5. data/ext/packaging/spec/tasks/build_object_spec.rb +6 -4
  6. data/ext/packaging/static_artifacts/PackageInfo.plist +3 -0
  7. data/ext/packaging/tasks/00_utils.rake +91 -15
  8. data/ext/packaging/tasks/10_setupvars.rake +39 -24
  9. data/ext/packaging/tasks/20_setupextravars.rake +1 -5
  10. data/ext/packaging/tasks/30_metrics.rake +29 -37
  11. data/ext/packaging/tasks/apple.rake +8 -6
  12. data/ext/packaging/tasks/build.rake +6 -0
  13. data/ext/packaging/tasks/deb.rake +1 -4
  14. data/ext/packaging/tasks/fetch.rake +22 -12
  15. data/ext/packaging/tasks/gem.rake +88 -35
  16. data/ext/packaging/tasks/jenkins.rake +25 -1
  17. data/ext/packaging/tasks/jenkins_dynamic.rake +10 -1
  18. data/ext/packaging/tasks/mock.rake +37 -19
  19. data/ext/packaging/tasks/pe_ship.rake +108 -10
  20. data/ext/packaging/tasks/pe_sign.rake +3 -3
  21. data/ext/packaging/tasks/retrieve.rake +12 -0
  22. data/ext/packaging/tasks/rpm_repos.rake +2 -2
  23. data/ext/packaging/tasks/ship.rake +51 -12
  24. data/ext/packaging/tasks/sign.rake +42 -12
  25. data/ext/packaging/tasks/tar.rake +1 -1
  26. data/ext/packaging/tasks/template.rake +17 -3
  27. data/ext/packaging/tasks/vendor_gems.rake +1 -1
  28. data/ext/packaging/templates/downstream.xml.erb +15 -2
  29. data/ext/packaging/templates/packaging.xml.erb +143 -1
  30. data/ext/packaging/templates/repo.xml.erb +35 -24
  31. data/lib/puppet/transaction.rb +1 -1
  32. data/lib/puppet/type/file.rb +12 -23
  33. data/lib/puppet/type/file/source.rb +2 -2
  34. data/lib/puppet/type/service.rb +3 -2
  35. data/lib/puppet/util.rb +22 -41
  36. data/lib/puppet/version.rb +1 -1
  37. data/spec/integration/type/file_spec.rb +22 -35
  38. data/spec/spec_helper.rb +12 -0
  39. data/spec/unit/application/kick_spec.rb +9 -4
  40. data/spec/unit/indirector/catalog/static_compiler_spec.rb +1 -1
  41. data/spec/unit/type/file/source_spec.rb +8 -7
  42. data/spec/unit/type/file_spec.rb +0 -29
  43. metadata +64 -39
data/Gemfile CHANGED
@@ -1,17 +1,33 @@
1
- source :rubygems
1
+ source "https://rubygems.org"
2
2
 
3
- gemspec
3
+ def location_for(place)
4
+ if place =~ /^(git:[^#]*)#(.*)/
5
+ [{ :git => $1, :branch => $2, :require => false }]
6
+ elsif place =~ /^file:\/\/(.*)/
7
+ ['>= 0', { :path => File.expand_path($1), :require => false }]
8
+ else
9
+ [place, { :require => false }]
10
+ end
11
+ end
4
12
 
5
13
  group(:development, :test) do
6
- gem "facter", "~> 1.6.4", :require => false
7
- gem "rack", "~> 1.4.1", :require => false
8
- gem "rspec", "~> 2.10.0", :require => false
14
+ gem "puppet", :path => File.dirname(__FILE__), :require => false
15
+ gem "facter", *location_for(ENV['FACTER_LOCATION'] || '~> 1.6')
16
+ gem "hiera", *location_for(ENV['HIERA_LOCATION'] || '~> 1.0')
17
+ gem "rack", "~> 1.4", :require => false
18
+ gem "rake", :require => false
19
+ gem "rspec", "~> 2.11.0", :require => false
9
20
  gem "mocha", "~> 0.10.5", :require => false
21
+ gem "activerecord", *location_for('~> 3.0.7')
22
+ gem "couchrest", *location_for('~> 1.0')
23
+ gem "net-ssh", *location_for('~> 2.1')
24
+ gem "puppetlabs_spec_helper"
25
+ gem "sqlite3"
26
+ gem "stomp"
27
+ gem "tzinfo"
10
28
  end
11
29
 
12
30
  platforms :mswin, :mingw do
13
- # See http://jenkins.puppetlabs.com/ for current Gem listings for the Windows
14
- # CI Jobs.
15
31
  gem "sys-admin", "~> 1.5.6", :require => false
16
32
  gem "win32-api", "~> 1.4.8", :require => false
17
33
  gem "win32-dir", "~> 0.3.7", :require => false
@@ -0,0 +1,17 @@
1
+ packaging - Puppet Labs packaging framework
2
+
3
+ Copyright (C) 2011-2013 Puppet Labs Inc
4
+
5
+ Puppet Labs can be contacted at: info@puppetlabs.com
6
+
7
+ Licensed under the Apache License, Version 2.0 (the "License");
8
+ you may not use this file except in compliance with the License.
9
+ You may obtain a copy of the License at
10
+
11
+ http://www.apache.org/licenses/LICENSE-2.0
12
+
13
+ Unless required by applicable law or agreed to in writing, software
14
+ distributed under the License is distributed on an "AS IS" BASIS,
15
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ See the License for the specific language governing permissions and
17
+ limitations under the License.
@@ -123,7 +123,8 @@ specified in the build-data file, and appropriate membership in the build
123
123
  groups, e.g. to use mock on the builder, membership in the mock group. This is
124
124
  a major hurdle, and is resolved with the `jenkins` tasks below.
125
125
 
126
- ## `:jenkins:` tasks
126
+ ## legacy `:jenkins:` workflow tasks
127
+ (Deprecated - see "dyamic jenkins task workflow" below)
127
128
  Jenkins tasks are similar to the `:remote:` tasks, but they do not require ssh
128
129
  access to the builders. They do require being on the local network - the
129
130
  jenkins instance that performs package builds is an internal server only,
@@ -150,6 +151,10 @@ repository](https://github.com/puppetlabs/build-data)
150
151
  later in determining the target for the build artifacts on the distribution
151
152
  server
152
153
 
154
+ 4) $METRICS - a string of data points related to the build which are used for
155
+ data analysis. Contents of this string are items which cannot be obtained from
156
+ within the Jenkins job itself.
157
+
153
158
  5) $DOWNSTREAM\_JOB - The URL of a downstream job that jenkins should post to
154
159
  upon success. This is obtained via the DOWNSTREAM\_JOB environment variable.
155
160
 
@@ -206,14 +211,25 @@ the task are:
206
211
 
207
212
  #################
208
213
  ```
209
- The second, more recent, jenkins-based workflow is for initiating the
210
- "uber_build", or a package build for all of our target platforms. This workflow
211
- doesn't actually use a static job on the jenkins-server. Instead it _creates_
212
- the jenkins jobs for you, on-demand. Specifically, it creates two jenkins-jobs,
213
- and can create an optional third.
214
+
215
+ To gather metrics related to a Jenkins build, the Groovy Postbuild plugin is used.
216
+ For tasks carried out on the static Jenkins job, the script must be manually added to the job's
217
+ configuration. The script in its entirety can be seen [here.](https://github.com/Whopper92/buildboard#groovyScript)
218
+
219
+ ## dynamic `:jenkins:` task workflow
220
+
221
+ The recommended and far simpler jenkins-based workflow is for initiating the
222
+ "uber_build", or a package build for all of our target platforms.
223
+
224
+ The uber_build is invoked as "pl:jenkins:uber_build" or "pe:jenkins:uber_build"
225
+ depending on if this is a FOSS or PE package.
226
+
227
+ This workflow doesn't actually use a static job on the jenkins-server. Instead
228
+ it _creates_ the jenkins jobs for you, on-demand. Specifically, it creates two
229
+ jenkins-jobs, and can create an optional third.
214
230
 
215
231
  The first job is a matrix job, the cells of which are individual package tasks
216
- for all of the build targets. This job takes three parameters:
232
+ for all of the build targets. This job takes four parameters:
217
233
 
218
234
  1) $PROJECT\_BUNDLE - a tar.gz of a git-bundle from HEAD of the current
219
235
  project, which is cloned on the builder to set up a duplicate of this
@@ -226,11 +242,16 @@ about the build
226
242
  later in determining the target for the build artifacts on the distribution
227
243
  server
228
244
 
245
+ 4) $METRICS - a string of data points related to the build which are used for data
246
+ analysis. Contents of this string are items which cannot be obtained from within
247
+ the Jenkins job itself. Note that the Groovy postbuild script needed for metrics
248
+ gathering is dynamically passed to each job.
249
+
229
250
  This first job clones the git bundle passed in as a parameter, then clones the
230
251
  packaging repo (rake package:bootstrap) and for every cell in its matrix
231
252
  performs a package build for a specific target (e.g. rake pl:deb
232
- COW=base-lucid-i386.cow). If all cells in the matrix complete successfully (if
233
- all packages build), this job automatically triggers the second of the new jobs
253
+ COW=base-lucid-i386.cow). Once all cells in the matrix complete (either succeed
254
+ or fail), this job automatically triggers the second of the new jobs
234
255
  as a downstream job.
235
256
 
236
257
  To receive an email notification from jenkins about the status of the packaging
@@ -243,15 +264,34 @@ The second job is an automatic repository creation task for this git repo.
243
264
  Specifically, the job copies the git bundle from the packaging job and clones
244
265
  it, and uses the git information in the git bundle to clone the packaging repo
245
266
  and invoke the repository creation jobs `pl:jenkins:rpm_repos` and
246
- `pl:jenkins:deb_repos`.
267
+ `pl:jenkins:deb_repos`. The job will always be invoked, but will only actually
268
+ create repos if the upstream packaging job actually succeeded.
247
269
 
248
270
  The third job is only created _if_ the environment variable
249
271
  `DOWNSTREAM_JOB=<job_url>` was passed to the initial "pl:jenkins:uber_build"
250
272
  invocation. This third job takes the value assigned to `DOWNSTREAM_JOB` and
251
273
  creates a proxy jenkins job with a single build step, a curl call to this
252
274
  value, presumably a url to a jenkins job to trigger programmatically.
253
- Once the repos have successfully been created by the second job, the third job
254
- will automatically trigger as a downstream job.
275
+
276
+ An important note about `DOWNSTREAM_JOB`: `DOWNSTREAM_JOB` in the dynamic jenkins
277
+ workflow is _always_ invoked if it is passed in as an environment variable.
278
+ However, it is also appended with an additional parameter, `PACKAGE_BUILD_STATUS`,
279
+ which will be the string "success" if package and repo builds succeeded, or
280
+ "failure" if package or repo builds failed. By modifying the actual downstream
281
+ jenkins job to accept a string parameter of `PACKAGE_BUILD_STATUS`, one can
282
+ switch on the success or failure of the packaging job, responding
283
+ appropriately.
284
+
285
+ E.g., a job url:
286
+ http://jenkins.example.net/job/downstream/buildWithParameters?FOO=bar
287
+
288
+ in the success case will be transformed into
289
+
290
+ http://jenkins.example.net/job/downstream/buildWithParameters?FOO=bar&PACKAGE_BUILD_STATUS=success
291
+
292
+ and in the failure case transformed into
293
+
294
+ http://jenkins.example.net/job/downstream/buildWithParameters?FOO=bar&PACKAGE_BUILD_STATUS=failure
255
295
 
256
296
  All 3 jobs are configured by default for removal by jenkins after 3 days, to
257
297
  avoid clutter.
@@ -260,6 +300,7 @@ The goal is to move toward migrating all of the jenkins tasks from the first
260
300
  workflow, using a static job that is called many times per package, to this
261
301
  second workflow of creating the jobs on demand.
262
302
 
303
+
263
304
  ## Task Explanations
264
305
  For a listing of all available tasks and their functions, see the [Task
265
306
  Dictionary](https://github.com/puppetlabs/packaging/tree/more_documentation#task-dictionary)
@@ -293,17 +334,20 @@ spec file, and an osx preflight and plist.
293
334
 
294
335
  The top level Rakefile or a separate task file in the project should have the following added:
295
336
 
337
+ (this assumes RAKE\_ROOT is defined in the top-level Rakefile using something like the following)
296
338
  ```ruby
297
- Dir['ext/packaging/tasks/**/*.rake'].sort.each { |t| load t }
339
+ RAKE_ROOT = File.expand_path(File.dirname(__FILE__))
340
+ ```
298
341
 
299
- build_defs_file = 'ext/build_defaults.yaml'
342
+ ```ruby
343
+ build_defs_file = File.join(RAKE_ROOT, 'ext', 'build_defaults.yaml')
300
344
  if File.exist?(build_defs_file)
301
345
  begin
302
346
  require 'yaml'
303
347
  @build_defaults ||= YAML.load_file(build_defs_file)
304
348
  rescue Exception => e
305
349
  STDERR.puts "Unable to load yaml from #{build_defs_file}:"
306
- STDERR.puts e
350
+ raise e
307
351
  end
308
352
  @packaging_url = @build_defaults['packaging_url']
309
353
  @packaging_repo = @build_defaults['packaging_repo']
@@ -313,20 +357,25 @@ if File.exist?(build_defs_file)
313
357
  namespace :package do
314
358
  desc "Bootstrap packaging automation, e.g. clone into packaging repo"
315
359
  task :bootstrap do
316
- if File.exist?("ext/#{@packaging_repo}")
360
+ if File.exist?(File.join(RAKE_ROOT, "ext", @packaging_repo))
317
361
  puts "It looks like you already have ext/#{@packaging_repo}. If you don't like it, blow it away with package:implode."
318
362
  else
319
- cd 'ext' do
363
+ cd File.join(RAKE_ROOT, 'ext') do
320
364
  %x{git clone #{@packaging_url}}
321
365
  end
322
366
  end
323
367
  end
324
368
  desc "Remove all cloned packaging automation"
325
369
  task :implode do
326
- rm_rf "ext/#{@packaging_repo}"
370
+ rm_rf File.join(RAKE_ROOT, "ext", @packaging_repo)
327
371
  end
328
372
  end
329
373
  end
374
+
375
+ begin
376
+ load File.join(RAKE_ROOT, 'ext', 'packaging', 'packaging.rake')
377
+ rescue LoadError
378
+ end
330
379
  ```
331
380
 
332
381
  Also in ext should be two files, build_defaults.yaml and project_data.yaml.
@@ -388,6 +437,12 @@ summary: 'Light weight hierarchical data store'
388
437
  description: 'A pluggable data store for hierarcical data'
389
438
  # file containing hard coded version information, if present
390
439
  version_file: '/lib/hiera.rb'
440
+ # A string indicating the version strategy for the project (one of 'odd_even' or 'rc_final'), defaults to rc_final
441
+ # odd_even is a final release when the minor version is even, and a development release when it is odd
442
+ # rc_final is a final release when there is no rc at the end of the version string, and a development release when there is
443
+ version_strategy: 'rc_final'
444
+ # Boolean value of whether or not to automatically update the version file before packaging (defaults to false)
445
+ update_version_file: true
391
446
  # files and gem\_files are space separated lists
392
447
  # files to be packaged into a tarball and released with deb/rpm
393
448
  files: '[A-Z]* ext lib bin spec acceptance_tests'
@@ -396,6 +451,12 @@ files: '[A-Z]* ext lib bin spec acceptance_tests'
396
451
  # 'tar\_excludes' only needs to include any undesired subdirectories/files of the 'files'
397
452
  # list to exclude
398
453
  tar_excludes: 'ext/packaging lib/some_excluded_file'
454
+ # Array of templates or globs of templates to evaluate. Note that without this key, the packaging will
455
+ # default to searching for any files in `ext` with the extension '.erb' and evaluate them. When this
456
+ # key is supplied, its values override the defaults, and all desired erb files must be specified with a path or glob.
457
+ templates:
458
+ - ext/redhat/project.spec.erb
459
+ - ext/templates/**/*.erb
399
460
  # files to be packaged into a gem
400
461
  gem_files: '{bin,lib}/**/* CHANGELOG COPYING README.md LICENSE'
401
462
  # To exclude specific files from inclusion in a gem:
@@ -417,6 +478,19 @@ gem_runtime_dependencies:
417
478
  hiera-json:
418
479
  gem_development_dependencies:
419
480
  facter: '>= 1.6.11'
481
+ # To add gem dependencies which only apply to a specific platform, add the key "gem_platform_dependencies".
482
+ # The first key under the gem_platform_dependencies has to be a value that
483
+ # corresponds to a value of RUBY_PLATFORM. The subkeys are the same as the
484
+ # top-level gem dependency keys:
485
+ gem_platform_dependencies:
486
+ x86-mingw32:
487
+ gem_runtime_dependencies:
488
+ win32process: '~> 0.6.5'
489
+ gem_development_dependencies:
490
+ rake: '~> 0.9.0'
491
+ x86_64-darwin:
492
+ gem_runtime_dependencies:
493
+ CFPropertyList: '~> 2.2.4'
420
494
  # rdoc options as an array
421
495
  gem_rdoc_options:
422
496
  - --line-numbers
@@ -14,16 +14,18 @@ describe "00_utils" do
14
14
  :get_rpmversion => '0.7.0',
15
15
  :get_rpmrelease => '1',
16
16
  :is_rc? => false,
17
+ :is_odd? => true,
17
18
  },
18
- '0.7.0rc10' => {
19
- :git_describe_version => %w{0.7.0rc10},
20
- :get_dash_version => '0.7.0rc10',
21
- :get_ips_version => '0.7.0rc10,3.14159-0',
22
- :get_dot_version => '0.7.0rc10',
23
- :get_debversion => '0.7.0-0.1rc10puppetlabs1',
24
- :get_rpmversion => '0.7.0',
19
+ '0.8.0rc10' => {
20
+ :git_describe_version => %w{0.8.0rc10},
21
+ :get_dash_version => '0.8.0rc10',
22
+ :get_ips_version => '0.8.0rc10,3.14159-0',
23
+ :get_dot_version => '0.8.0rc10',
24
+ :get_debversion => '0.8.0-0.1rc10puppetlabs1',
25
+ :get_rpmversion => '0.8.0',
25
26
  :get_rpmrelease => '0.1rc10',
26
27
  :is_rc? => true,
28
+ :is_odd? => false,
27
29
  },
28
30
  '0.7.0-rc1' => {
29
31
  :git_describe_version => %w{0.7.0 rc1},
@@ -34,26 +36,29 @@ describe "00_utils" do
34
36
  :get_rpmversion => '0.7.0',
35
37
  :get_rpmrelease => '0.1rc1',
36
38
  :is_rc? => true,
39
+ :is_odd? => true,
37
40
  },
38
- '0.7.0-rc1-63-ge391f55' => {
39
- :git_describe_version => %w{0.7.0 rc1 63},
40
- :get_dash_version => '0.7.0-rc1-63',
41
- :get_ips_version => '0.7.0,3.14159-63',
42
- :get_dot_version => '0.7.0.rc1.63',
43
- :get_debversion => '0.7.0-0.1rc1.63puppetlabs1',
44
- :get_rpmversion => '0.7.0',
41
+ '0.4.0-rc1-63-ge391f55' => {
42
+ :git_describe_version => %w{0.4.0 rc1 63},
43
+ :get_dash_version => '0.4.0-rc1-63',
44
+ :get_ips_version => '0.4.0,3.14159-63',
45
+ :get_dot_version => '0.4.0.rc1.63',
46
+ :get_debversion => '0.4.0-0.1rc1.63puppetlabs1',
47
+ :get_rpmversion => '0.4.0',
45
48
  :get_rpmrelease => '0.1rc1.63',
46
49
  :is_rc? => true,
50
+ :is_odd? => false,
47
51
  },
48
- '0.7.0-rc1-63-ge391f55-dirty' => {
49
- :git_describe_version => %w{0.7.0 rc1 63 dirty},
50
- :get_dash_version => '0.7.0-rc1-63-dirty',
51
- :get_ips_version => '0.7.0,3.14159-63-dirty',
52
- :get_dot_version => '0.7.0.rc1.63.dirty',
53
- :get_debversion => '0.7.0-0.1rc1.63dirtypuppetlabs1',
54
- :get_rpmversion => '0.7.0',
52
+ '0.6.0-rc1-63-ge391f55-dirty' => {
53
+ :git_describe_version => %w{0.6.0 rc1 63 dirty},
54
+ :get_dash_version => '0.6.0-rc1-63-dirty',
55
+ :get_ips_version => '0.6.0,3.14159-63-dirty',
56
+ :get_dot_version => '0.6.0.rc1.63.dirty',
57
+ :get_debversion => '0.6.0-0.1rc1.63dirtypuppetlabs1',
58
+ :get_rpmversion => '0.6.0',
55
59
  :get_rpmrelease => '0.1rc1.63dirty',
56
60
  :is_rc? => true,
61
+ :is_odd? => false,
57
62
 
58
63
  },
59
64
  '0.7.0-63-ge391f55' => {
@@ -65,6 +70,7 @@ describe "00_utils" do
65
70
  :get_rpmversion => '0.7.0.63',
66
71
  :get_rpmrelease => '1',
67
72
  :is_rc? => false,
73
+ :is_odd? => true,
68
74
 
69
75
  },
70
76
  '0.7.0-63-ge391f55-dirty' => {
@@ -76,6 +82,7 @@ describe "00_utils" do
76
82
  :get_rpmversion => '0.7.0.63.dirty',
77
83
  :get_rpmrelease => '1',
78
84
  :is_rc? => false,
85
+ :is_odd? => true,
79
86
  },
80
87
  }
81
88
 
@@ -36,11 +36,13 @@ describe Build::BuildInstance do
36
36
  :gem_dependencies,
37
37
  :gem_description,
38
38
  :gem_devel_dependencies,
39
+ :gem_development_dependencies,
39
40
  :gem_excludes,
40
41
  :gem_executables,
41
42
  :gem_files,
42
43
  :gem_forge_project,
43
44
  :gem_name,
45
+ :gem_platform_dependencies,
44
46
  :gem_rdoc_options,
45
47
  :gem_require_path,
46
48
  :gem_runtime_dependencies,
@@ -62,6 +64,7 @@ describe Build::BuildInstance do
62
64
  :jenkins_packaging_job,
63
65
  :jenkins_repo_path,
64
66
  :metrics,
67
+ :metrics_url,
65
68
  :name,
66
69
  :notify,
67
70
  :project,
@@ -84,17 +87,16 @@ describe Build::BuildInstance do
84
87
  :rpmversion,
85
88
  :ref,
86
89
  :sign_tar,
87
- :sles_build_host,
88
- :sles_repo_path,
89
- :sles_repo_host,
90
- :sles_arch_repos,
91
90
  :summary,
92
91
  :tar_excludes,
93
92
  :tar_host,
94
93
  :tarball_path,
95
94
  :team,
95
+ :templates,
96
+ :update_version_file,
96
97
  :version,
97
98
  :version_file,
99
+ :version_strategy,
98
100
  :yum_host,
99
101
  :yum_repo_path]
100
102
 
@@ -0,0 +1,3 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <pkg-info followSymLinks="true" minimumSystemVersion="10.6" auth="root"/>
3
+
@@ -93,7 +93,7 @@ end
93
93
 
94
94
  def rsync_to *args
95
95
  check_tool('rsync')
96
- flags = "-rHlv -O --no-perms --no-owner --no-group"
96
+ flags = "-rHlv -O --no-perms --no-owner --no-group --ignore-existing"
97
97
  source = args[0]
98
98
  target = args[1]
99
99
  dest = args[2]
@@ -228,8 +228,10 @@ end
228
228
 
229
229
  def load_keychain
230
230
  unless @keychain_loaded
231
- kill_keychain
232
- start_keychain
231
+ unless ENV['RPM_GPG_AGENT']
232
+ kill_keychain
233
+ start_keychain
234
+ end
233
235
  @keychain_loaded = TRUE
234
236
  end
235
237
  end
@@ -260,7 +262,8 @@ def gpg_sign_file(file)
260
262
  gpg ||= find_tool('gpg')
261
263
 
262
264
  if gpg
263
- sh "#{gpg} --armor --detach-sign -u #{@build.gpg_key} #{file}"
265
+ use_tty = "--no-tty --use-agent" if ENV['RPM_GPG_AGENT']
266
+ sh "#{gpg} #{use_tty} --armor --detach-sign -u #{@build.gpg_key} #{file}"
264
267
  else
265
268
  fail "No gpg available. Cannot sign #{file}."
266
269
  end
@@ -311,6 +314,7 @@ def git_commit_file(file, message=nil)
311
314
  end
312
315
 
313
316
  def ship_gem(file)
317
+ check_file("#{ENV['HOME']}/.gem/credentials")
314
318
  %x{gem push #{file}}
315
319
  end
316
320
 
@@ -360,9 +364,9 @@ def rand_string
360
364
  rand.to_s.split('.')[1]
361
365
  end
362
366
 
363
- def git_bundle(treeish)
364
- temp = get_temp
365
- appendix = rand_string
367
+ def git_bundle(treeish, appendix=nil, output_dir=nil)
368
+ temp = output_dir || get_temp
369
+ appendix ||= rand_string
366
370
  sh "git bundle create #{temp}/#{@build.project}-#{@build.version}-#{appendix} #{treeish} --tags"
367
371
  cd temp do
368
372
  sh "tar -czf #{@build.project}-#{@build.version}-#{appendix}.tar.gz #{@build.project}-#{@build.version}-#{appendix}"
@@ -371,12 +375,14 @@ def git_bundle(treeish)
371
375
  "#{temp}/#{@build.project}-#{@build.version}-#{appendix}.tar.gz"
372
376
  end
373
377
 
374
- # We take a tar argument for cases where `tar` isn't best, e.g. Solaris
375
- def remote_bootstrap(host, treeish, tar_cmd=nil)
378
+ # We take a tar argument for cases where `tar` isn't best, e.g. Solaris. We
379
+ # also take an optional argument of the tarball containing the git bundle to
380
+ # use.
381
+ def remote_bootstrap(host, treeish, tar_cmd=nil, tarball=nil)
376
382
  unless tar = tar_cmd
377
383
  tar = 'tar'
378
384
  end
379
- tarball = git_bundle(treeish)
385
+ tarball ||= git_bundle(treeish)
380
386
  tarball_name = File.basename(tarball).gsub('.tar.gz','')
381
387
  rsync_to(tarball, host, '/tmp')
382
388
  appendix = rand_string
@@ -456,28 +462,62 @@ def deprecate(old_cmd, new_cmd=nil)
456
462
  STDOUT.puts
457
463
  end
458
464
 
459
- # Determines if this package is an rc package via the version
460
- # returned by get_dash_version method.
465
+ # Determines if this package is a final package via the
466
+ # selected version_strategy.
467
+ # There are currently two supported version strategies.
468
+ #
469
+ # This method calls down to the version strategy indicated, defaulting to the
470
+ # rc_final strategy. The methods themselves will return false if it is a final
471
+ # release, so their return values are collected and then inverted before being
472
+ # returned.
473
+ def is_final?
474
+ ret = nil
475
+ case @build.version_strategy
476
+ when "rc_final"
477
+ ret = is_rc?
478
+ when "odd_even"
479
+ ret = is_odd?
480
+ when nil
481
+ ret = is_rc?
482
+ end
483
+ return (! ret)
484
+ end
485
+
486
+ # the rc_final strategy (default)
461
487
  # Assumes version strings in the formats:
462
488
  # final:
463
489
  # '0.7.0'
464
490
  # '0.7.0-63'
465
491
  # '0.7.0-63-dirty'
466
- # rc:
492
+ # development:
467
493
  # '0.7.0rc1 (we don't actually use this format anymore, but once did)
468
494
  # '0.7.0-rc1'
469
495
  # '0.7.0-rc1-63'
470
496
  # '0.7.0-rc1-63-dirty'
471
497
  def is_rc?
472
498
  return TRUE if get_dash_version =~ /^\d+\.\d+\.\d+-*rc\d+/
473
- FALSE
499
+ return FALSE
500
+ end
501
+
502
+ # the odd_even strategy (mcollective)
503
+ # final:
504
+ # '0.8.0'
505
+ # '1.8.0-63'
506
+ # '0.8.1-63-dirty'
507
+ # development:
508
+ # '0.7.0'
509
+ # '1.7.0-63'
510
+ # '0.7.1-63-dirty'
511
+ def is_odd?
512
+ return TRUE if get_dash_version.match(/^\d+\.(\d+)\.\d+/)[1].to_i.odd?
513
+ return FALSE
474
514
  end
475
515
 
476
516
  # Utility method to return the dist method if this is a redhat box. We use this
477
517
  # in rpm packaging to define a dist macro, and we use it in the pl:fetch task
478
518
  # to disable ssl checking for redhat 5 because it has a certs bundle so old by
479
519
  # default that it's useless for our purposes.
480
- def el_version()
520
+ def el_version
481
521
  if File.exists?('/etc/fedora-release')
482
522
  nil
483
523
  elsif File.exists?('/etc/redhat-release')
@@ -578,3 +618,39 @@ def escape_html(uri)
578
618
  require 'cgi'
579
619
  CGI.escapeHTML(uri)
580
620
  end
621
+
622
+ # Add a parameter to a given uri. If we were sane we'd use
623
+ # encode_www_form(params) of URI, but because we're not, because that will http
624
+ # encode it, which isn't what we want since we're require the encoding provided
625
+ # by escapeHTML of CGI, since this is being transfered in the xml of a jenkins
626
+ # job via curl and DEAR JEEBUS WHAT HAVE WE DONE.
627
+ def add_param_to_uri(uri, param)
628
+ require 'uri'
629
+ uri = URI.parse(uri)
630
+ uri.query = [uri.query, param].compact.join('&')
631
+ uri.to_s
632
+ end
633
+
634
+ # Remotely set the immutable bit on a list of files
635
+ #
636
+ def remote_set_immutable(host, files)
637
+ remote_ssh_cmd(host, "sudo chattr +i #{files.join(" ")}")
638
+ end
639
+
640
+ # ex combines the behavior of `%x{cmd}` and rake's `sh "cmd"`. `%x{cmd}` has
641
+ # the benefit of returning the standard out of an executed command, enabling us
642
+ # to query the file system, e.g. `contents = %x{ls}`. The drawback to `%x{cmd}`
643
+ # is that on failure of a command (something returned non-zero) the return of
644
+ # `%x{cmd}` is just an empty string. As such, we can't know if we succeeded.
645
+ # Rake's `sh "cmd"`, on the other hand, will raise a RuntimeError if a command
646
+ # does not return 0, but doesn't return any of the stdout from the command -
647
+ # only true or false depending on its success or failure. With `ex(cmd)` we
648
+ # purport to both return the results of the command execution (ala `%x{cmd}`)
649
+ # while also raising an exception if a command does not succeed (ala `sh "cmd"`).
650
+ def ex(command)
651
+ ret = %x[#{command}]
652
+ unless $?.success?
653
+ raise RuntimeError
654
+ end
655
+ ret
656
+ end