packaging 0.88.77 → 0.99.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.
Files changed (72) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +128 -74
  3. data/lib/packaging/artifactory.rb +60 -433
  4. data/lib/packaging/config/params.rb +7 -28
  5. data/lib/packaging/config.rb +50 -150
  6. data/lib/packaging/deb/repo.rb +19 -20
  7. data/lib/packaging/gem.rb +83 -41
  8. data/lib/packaging/ips.rb +57 -0
  9. data/lib/packaging/msi.rb +89 -0
  10. data/lib/packaging/nuget.rb +1 -1
  11. data/lib/packaging/osx.rb +36 -0
  12. data/lib/packaging/paths.rb +87 -225
  13. data/lib/packaging/platforms.rb +416 -443
  14. data/lib/packaging/repo.rb +22 -122
  15. data/lib/packaging/retrieve.rb +7 -36
  16. data/lib/packaging/rpm/repo.rb +8 -5
  17. data/lib/packaging/tar.rb +0 -9
  18. data/lib/packaging/util/date.rb +0 -5
  19. data/lib/packaging/util/execution.rb +2 -2
  20. data/lib/packaging/util/git.rb +1 -1
  21. data/lib/packaging/util/gpg.rb +1 -5
  22. data/lib/packaging/util/net.rb +37 -79
  23. data/lib/packaging/util/rake_utils.rb +0 -1
  24. data/lib/packaging/util/ship.rb +13 -142
  25. data/lib/packaging/util/tool.rb +1 -1
  26. data/lib/packaging/util/version.rb +0 -8
  27. data/lib/packaging/util.rb +2 -2
  28. data/lib/packaging.rb +3 -3
  29. data/spec/fixtures/config/params.yaml +2 -0
  30. data/spec/lib/packaging/artifactory_spec.rb +16 -66
  31. data/spec/lib/packaging/config_spec.rb +29 -49
  32. data/spec/lib/packaging/deb/repo_spec.rb +7 -16
  33. data/spec/lib/packaging/paths_spec.rb +56 -321
  34. data/spec/lib/packaging/platforms_spec.rb +21 -46
  35. data/spec/lib/packaging/repo_spec.rb +40 -78
  36. data/spec/lib/packaging/retrieve_spec.rb +8 -47
  37. data/spec/lib/packaging/rpm/repo_spec.rb +4 -4
  38. data/spec/lib/packaging/tar_spec.rb +40 -34
  39. data/spec/lib/packaging/util/git_tag_spec.rb +1 -1
  40. data/spec/lib/packaging/util/gpg_spec.rb +1 -1
  41. data/spec/lib/packaging/util/net_spec.rb +15 -35
  42. data/spec/lib/packaging/util/ship_spec.rb +63 -145
  43. data/spec/spec_helper.rb +14 -0
  44. data/tasks/00_utils.rake +6 -4
  45. data/tasks/apple.rake +0 -2
  46. data/tasks/config.rake +0 -5
  47. data/tasks/education.rake +5 -5
  48. data/tasks/fetch.rake +14 -17
  49. data/tasks/gem.rake +121 -134
  50. data/tasks/jenkins.rake +7 -51
  51. data/tasks/nightly_repos.rake +69 -20
  52. data/tasks/pe_ship.rake +11 -16
  53. data/tasks/retrieve.rake +6 -13
  54. data/tasks/ship.rake +256 -196
  55. data/tasks/sign.rake +135 -63
  56. data/tasks/tar.rake +6 -0
  57. data/templates/packaging.xml.erb +7 -9
  58. data/templates/repo.xml.erb +3 -6
  59. metadata +27 -80
  60. data/lib/packaging/archive.rb +0 -126
  61. data/lib/packaging/artifactory/extensions.rb +0 -94
  62. data/lib/packaging/config/validations.rb +0 -13
  63. data/lib/packaging/metrics.rb +0 -15
  64. data/lib/packaging/sign/deb.rb +0 -9
  65. data/lib/packaging/sign/dmg.rb +0 -41
  66. data/lib/packaging/sign/ips.rb +0 -57
  67. data/lib/packaging/sign/msi.rb +0 -124
  68. data/lib/packaging/sign/rpm.rb +0 -115
  69. data/lib/packaging/sign.rb +0 -8
  70. data/spec/lib/packaging/gem_spec.rb +0 -86
  71. data/spec/lib/packaging/sign_spec.rb +0 -133
  72. data/tasks/archive.rake +0 -69
@@ -1,9 +1,3 @@
1
- require 'artifactory'
2
- require 'uri'
3
- require 'open-uri'
4
- require 'digest'
5
- require 'packaging/artifactory/extensions'
6
-
7
1
  module Pkg
8
2
 
9
3
  # The Artifactory class
@@ -12,11 +6,6 @@ module Pkg
12
6
  # artifacts to the repos, and to retrieve them back from the repos.
13
7
  class ManageArtifactory
14
8
 
15
- # The Artifactory property that the artifactCleanup user plugin
16
- # {https://github.com/jfrog/artifactory-user-plugins/tree/master/cleanup/artifactCleanup}
17
- # uses to tell it to not clean a particular artifact
18
- ARTIFACTORY_CLEANUP_SKIP_PROPERTY = 'cleanup.skip'
19
-
20
9
  DEFAULT_REPO_TYPE = 'generic'
21
10
  DEFAULT_REPO_BASE = 'development'
22
11
 
@@ -31,6 +20,8 @@ module Pkg
31
20
  # @option :repo_base [String] The base of all repos, set for consistency.
32
21
  # This currently defaults to 'development'
33
22
  def initialize(project, project_version, opts = {})
23
+ require 'artifactory'
24
+
34
25
  @artifactory_uri = opts[:artifactory_uri] || 'https://artifactory.delivery.puppetlabs.net/artifactory'
35
26
  @repo_base = opts[:repo_base] || DEFAULT_REPO_BASE
36
27
 
@@ -51,6 +42,7 @@ module Pkg
51
42
  def location_for(platform_tag)
52
43
  toplevel_repo = DEFAULT_REPO_TYPE
53
44
  repo_subdirectories = File.join(@repo_base, @project, @project_version)
45
+ alternate_subdirectories = repo_subdirectories
54
46
 
55
47
  unless platform_tag == DEFAULT_REPO_TYPE
56
48
  format = Pkg::Platforms.package_format_for_tag(platform_tag)
@@ -61,16 +53,20 @@ module Pkg
61
53
  when 'rpm'
62
54
  toplevel_repo = 'rpm'
63
55
  repo_subdirectories = File.join(repo_subdirectories, "#{platform}-#{version}-#{architecture}")
56
+ alternate_subdirectories = repo_subdirectories
64
57
  when 'deb'
65
58
  toplevel_repo = 'debian__local'
66
59
  repo_subdirectories = File.join(repo_subdirectories, "#{platform}-#{version}")
60
+ alternate_subdirectories = File.join('pool', repo_subdirectories)
67
61
  when 'swix', 'dmg', 'svr4', 'ips'
68
62
  repo_subdirectories = File.join(repo_subdirectories, "#{platform}-#{version}-#{architecture}")
63
+ alternate_subdirectories = repo_subdirectories
69
64
  when 'msi'
70
65
  repo_subdirectories = File.join(repo_subdirectories, "#{platform}-#{architecture}")
66
+ alternate_subdirectories = repo_subdirectories
71
67
  end
72
68
 
73
- [toplevel_repo, repo_subdirectories]
69
+ [toplevel_repo, repo_subdirectories, alternate_subdirectories]
74
70
  end
75
71
 
76
72
  # @param platform_tag [String] The platform tag specific to the information
@@ -85,8 +81,8 @@ module Pkg
85
81
  end
86
82
  end
87
83
 
88
- repo_name, repo_subdirectories = location_for(platform_tag)
89
- full_artifactory_path = File.join(repo_name, repo_subdirectories)
84
+ repo_name, repo_subdirectories, alternate_subdirectories = location_for(platform_tag)
85
+ full_artifactory_path = File.join(repo_name, alternate_subdirectories)
90
86
 
91
87
  {
92
88
  platform: platform,
@@ -96,6 +92,7 @@ module Pkg
96
92
  package_format: package_format,
97
93
  repo_name: repo_name,
98
94
  repo_subdirectories: repo_subdirectories,
95
+ alternate_subdirectories: alternate_subdirectories,
99
96
  full_artifactory_path: full_artifactory_path
100
97
  }
101
98
  end
@@ -169,7 +166,7 @@ module Pkg
169
166
  #
170
167
  # Currently we are including everything that would be included in the yaml
171
168
  # file that is generated at package build time.
172
- def deploy_properties(platform_tag, file_name)
169
+ def deploy_properties(platform_tag)
173
170
  data = platform_specific_data(platform_tag)
174
171
 
175
172
  # TODO This method should be returning the entire contents of the yaml
@@ -180,34 +177,15 @@ module Pkg
180
177
  #properties_hash = Pkg::Config.config_to_hash
181
178
  properties_hash = {}
182
179
  if data[:package_format] == 'deb'
183
- architecture = data[:architecture]
184
- # set arch correctly for noarch packages
185
- if file_name =~ /_all\.deb$/
186
- architecture = 'all'
187
- end
188
180
  properties_hash.merge!({
189
181
  'deb.distribution' => data[:codename],
190
182
  'deb.component' => data[:repo_subdirectories],
191
- 'deb.architecture' => architecture,
183
+ 'deb.architecture' => data[:architecture],
192
184
  })
193
185
  end
194
186
  properties_hash
195
187
  end
196
188
 
197
- # Basic method to check if a package exists on artifactory
198
- # @param package [String] The full relative path to the package to be
199
- # checked, relative from the current working directory
200
- # Return true if package already exists on artifactory
201
- def package_exists_on_artifactory?(package)
202
- check_authorization
203
- artifact = Artifactory::Resource::Artifact.search(name: File.basename(package), :artifactory_uri => @artifactory_uri)
204
- if artifact.empty?
205
- return false
206
- else
207
- return true
208
- end
209
- end
210
-
211
189
  # @param package [String] The full relative path to the package to be
212
190
  # shipped, relative from the current working directory
213
191
  def deploy_package(package)
@@ -216,31 +194,25 @@ module Pkg
216
194
 
217
195
  check_authorization
218
196
  artifact = Artifactory::Resource::Artifact.new(local_path: package)
219
- artifact_md5 = Digest::MD5.file(package).hexdigest
220
- headers = { "X-Checksum-Md5" => artifact_md5 }
221
197
  artifact.upload(
222
198
  data[:repo_name],
223
- File.join(data[:repo_subdirectories], File.basename(package)),
224
- deploy_properties(platform_tag, File.basename(package)),
225
- headers
199
+ File.join(data[:alternate_subdirectories], File.basename(package)),
200
+ deploy_properties(platform_tag)
226
201
  )
227
202
  rescue
228
203
  raise "Attempt to upload '#{package}' to #{File.join(@artifactory_uri, data[:full_artifactory_path])} failed"
229
204
  end
230
205
 
231
- # @param pkg [String] The package to download YAML for
232
- # i.e. 'puppet-agent' or 'puppetdb'
233
- # @param ref [String] The git ref (sha or tag) we want the YAML for
234
- #
235
- # @return [String] The contents of the YAML file
236
- def retrieve_yaml_data(pkg, ref)
237
- yaml_url = "#{@artifactory_uri}/#{DEFAULT_REPO_TYPE}/#{DEFAULT_REPO_BASE}/#{pkg}/#{ref}/#{ref}.yaml"
238
- open(yaml_url) { |f| f.read }
239
- rescue
240
- raise "Failed to load YAML data for #{pkg} at #{ref} from #{yaml_url}!"
206
+ # @param directory [String] optional, The directory where the yaml file will
207
+ # be downloaded
208
+ # @return [String] The path to the downloaded file
209
+ def retrieve_yaml_data_file(directory = nil)
210
+ directory ||= Dir.mktmpdir
211
+ retrieve_package(DEFAULT_REPO_TYPE, "#{@project_version}.yaml", directory)
212
+ File.join(directory, "#{@project_version}.yaml")
241
213
  end
242
214
 
243
- # @param platform_data [Hash] The hash of the platform data that needs to be
215
+ # @param platform_data [Hash] The has of the platform data that needs to be
244
216
  # parsed
245
217
  # @param platform_tag [String] The tag that the data we want belongs to
246
218
  # @return [String] The name of the package for the given project,
@@ -250,7 +222,7 @@ module Pkg
250
222
  rescue
251
223
  fail_message = <<-DOC
252
224
  Package name could not be found from loaded yaml data. Either this package
253
- does not exist, or '#{platform_tag}' is not present in this dataset.
225
+ does not exist, or '#{@platform_tag}' is not present in this dataset.
254
226
 
255
227
  The following are available platform tags for '#{@project}' '#{@project_version}':
256
228
  #{platform_data.keys.sort}
@@ -258,392 +230,47 @@ module Pkg
258
230
  raise fail_message
259
231
  end
260
232
 
261
- # @param platform_data [Hash] The hash of the platform data that needs to be
262
- # parsed
263
- # @param platform_tag [String] The tag that the data we want belongs to
264
- # @return [Array] An array containing all packages for the given project,
265
- # project_version, and platform_tag
266
- def all_package_names(platform_data, platform_tag)
267
- packages = [platform_data[platform_tag][:artifact]]
268
- packages << platform_data[platform_tag][:additional_artifacts]
269
- packages.flatten!
270
- packages.reject! { |package| package.nil? || package.empty? }
271
- packages.map { |package| File.basename(package) }
272
- rescue
273
- fail_message = <<-DOC
274
- Package name could not be found from loaded yaml data. Either this package
275
- does not exist, or '#{platform_tag}' is not present in this dataset.
276
-
277
- The following are available platform tags for '#{@project}' '#{@project_version}':
278
- #{platform_data.keys.sort}
279
- DOC
280
- raise fail_message
281
- end
282
-
283
- # Promotes a build based on build SHA or tag (or SNAPSHOT version, for ezbake)
284
- # Depending on if it's an RPM or Deb package promote accordingly
285
- # 'promote' by copying the package(s) to the enterprise directory on artifactory
286
- #
287
- # @param pkg [String] the package name ex. puppet-agent
288
- # @param ref [String] tag or SHA of package(s) to be promoted
289
- # @param platform_tag [String] the platform tag of the artifact
290
- # ex. el-7-x86_64, ubuntu-18.04-amd64
291
- # @param repository [String] the repository to promote
292
- # the artifact to. Will prepend 'rpm_' or 'debian_' to the repositories
293
- # depending on package type
294
- # @param debian_component [String] the debian component to promote packages
295
- # into. Optional.
296
- def promote_package(pkg, ref, platform_tag, repository, debian_component = nil)
297
- # load package metadata
298
- yaml_content = retrieve_yaml_data(pkg, ref)
299
- yaml_data = YAML::load(yaml_content)
300
-
301
- # get the artifact name
302
- artifact_names = all_package_names(yaml_data[:platform_data], platform_tag)
303
- artifact_names.each do |artifact_name|
304
- artifact_search_results = Artifactory::Resource::Artifact.search(
305
- name: artifact_name, :artifactory_uri => @artifactory_uri)
306
-
307
- if artifact_search_results.empty?
308
- raise "Error: could not find PKG=#{pkg} at REF=#{ref} for #{platform_tag}"
309
- end
310
- artifact_to_promote = artifact_search_results[0]
311
-
312
- # This makes an assumption that we're using some consistent repo names
313
- # but need to either prepend 'rpm_' or 'debian_' based on package type
314
- case File.extname(artifact_name)
315
- when '.rpm'
316
- promotion_path = "rpm_#{repository}/#{platform_tag}/#{artifact_name}"
317
- when '.deb'
318
- promotion_path = "debian_#{repository}/#{platform_tag}/#{artifact_name}"
319
- properties = { 'deb.component' => debian_component } unless debian_component.nil?
320
- else
321
- raise "Error: Unknown promotion repository for #{artifact_name}! Only .rpm and .deb files are supported!"
322
- end
323
-
324
- begin
325
- source_path = artifact_to_promote.download_uri.sub(@artifactory_uri, '')
326
- puts "promoting #{artifact_name} from #{source_path} to #{promotion_path}"
327
- artifact_to_promote.copy(promotion_path)
328
- unless properties.nil?
329
- artifacts = Artifactory::Resource::Artifact.search(name: artifact_name, :artifactory_uri => @artifactory_uri)
330
- promoted_artifact = artifacts.select { |artifact| artifact.download_uri =~ %r{#{promotion_path}} }.first
331
- promoted_artifact.properties(properties)
332
- end
333
- rescue Artifactory::Error::HTTPError => e
334
- if e.message =~ /(destination and source are the same|user doesn't have permissions to override)/i
335
- puts "Skipping promotion of #{artifact_name}; it has already been promoted"
336
- else
337
- puts "#{e.message}"
338
- raise e
339
- end
340
- rescue => e
341
- puts "Something went wrong promoting #{artifact_name}!"
342
- raise e
343
- end
344
- end
345
- end
346
-
347
- # Using the manifest provided by enterprise-dist, grab the appropropriate packages from artifactory based on md5sum
348
- # @param staging_directory [String] location to download packages to
349
- # @param manifest [File] JSON file containing information about what packages to download and the corresponding md5sums
350
- # @param remote_path [String] Optional partial path on the remote host containing packages
351
- # Used to specify which subdirectories packages will be downloaded from.
352
- def download_packages(staging_directory, manifest, remote_path = '')
353
- check_authorization
354
- manifest.each do |dist, packages|
355
- puts "Grabbing the #{dist} packages from artifactory"
356
- packages.each do |name, info|
357
- filename = info['filename']
358
- artifacts = Artifactory::Resource::Artifact.checksum_search(md5: "#{info["md5"]}", repos: ["rpm_enterprise__local", "debian_enterprise__local"], name: filename)
359
- artifact_to_download = artifacts.select { |artifact| artifact.download_uri.include? remote_path }.first
360
- # If we found matching artifacts, but not in the correct path, copy the artifact to the correct path
361
- # This should help us keep repos up to date with the packages we are expecting to be there
362
- # while helping us avoid 'what the hell, could not find package' errors
363
- if artifact_to_download.nil? && !artifacts.empty?
364
- artifact_to_copy = artifacts.first
365
- copy_artifact(artifact_to_copy, artifact_to_copy.repo, "#{remote_path}/#{dist}/#{filename}")
366
- artifacts = Artifactory::Resource::Artifact.checksum_search(md5: "#{info["md5"]}", repos: ["rpm_enterprise__local", "debian_enterprise__local"], name: filename)
367
- artifact_to_download = artifacts.select { |artifact| artifact.download_uri.include? remote_path }.first
368
- end
369
-
370
- if artifact_to_download.nil?
371
- message = "Error: what the hell, could not find package #{filename} with md5sum #{info["md5"]}"
372
- unless remote_path.empty?
373
- message += " in #{remote_path}"
374
- end
375
- raise message
376
- else
377
- full_staging_path = "#{staging_directory}/#{dist}"
378
- puts "downloading #{artifact_to_download.download_uri} to #{File.join(full_staging_path, filename)}"
379
- artifact_to_download.download(full_staging_path, filename: filename)
380
- end
381
- end
382
- end
383
- end
384
-
385
- # Ship PE tarballs to specified artifactory repo and paths
386
- # @param local_tarball_directory [String] the local directory containing the tarballs
387
- # @param target_repo [String] the artifactory repo to ship the tarballs to
388
- # @param ship_paths [Array] the artifactory path(s) to ship the tarballs to within
389
- # the target_repo
390
- def ship_pe_tarballs(local_tarball_directory, target_repo, ship_paths)
391
- check_authorization
392
- ship_paths.each do |path|
393
- Dir.foreach(local_tarball_directory) do |pe_tarball|
394
- next if pe_tarball == '.' || pe_tarball == ".."
395
- begin
396
- puts "Uploading #{pe_tarball} to #{target_repo}/#{path}#{pe_tarball}"
397
- artifact = Artifactory::Resource::Artifact.new(
398
- local_path: "#{local_tarball_directory}/#{pe_tarball}")
399
- artifact.upload(target_repo, "#{path}#{pe_tarball}")
400
- rescue Errno::EPIPE
401
- STDERR.puts "Warning: Could not upload #{pe_tarball} to #{target_repo}/#{path}. Skipping."
402
- next
403
- end
404
- end
405
- end
406
- end
407
-
408
- # Upload file to Artifactory
409
- # @param local_path [String] local path to file to upload
410
- # @param target_repo [String] repo on artifactory to upload to
411
- # @param target_path [String] path within target_repo to upload to
412
- # @param properties [Hash] Optional property names and values to assign the uploaded file
413
- # For example, this would set both the 'cleanup.skip' and 'deb.component' properties:
414
- # \{ "cleanup.skip" => true, "deb.component" => 'bionic' \}
415
- # @param headers [Hash] Optional upload headers, most likely checksums, for the upload request
416
- # "X-Checksum-Md5" and "X-Checksum-Sha1" are typical
417
- def upload_file(local_path, target_repo, target_path, properties = {}, headers = {})
418
- fail "Error: Couldn't find file at #{local_path}." unless File.exist? local_path
419
- check_authorization
420
- artifact = Artifactory::Resource::Artifact.new(local_path: local_path)
421
- full_upload_path = File.join(target_path, File.basename(local_path))
422
- begin
423
- puts "Uploading #{local_path} to #{target_repo}/#{full_upload_path} . . ."
424
- artifact.upload(target_repo, full_upload_path, properties, headers)
425
- rescue Artifactory::Error::HTTPError => e
426
- fail "Error: Upload failed. Ensure path #{target_path} exists in the #{target_repo} repository."
427
- end
428
- end
429
-
430
- # Start by clearing the ARTIFACTORY_CLEANUP_SKIP_PROPERTY on all artifacts in a
431
- # single repo/directory location. This allows all artifacts in the directory to be cleaned.
432
- # Once cleared, set ARTIFACTORY_CLEANUP_SKIP_PROPERTY on those matching pe_build_version,
433
- # presumably the latest. This prevents those artifacts from being deleted.
434
- #
435
- # @param repo [String] Artifactory repository that contains the specified directory
436
- # @param directory [String] Artifactory directory in repo containing the artifacts from which to
437
- # set the 'cleanup.skip' property setting to false
438
- # @param pe_build_version [String] Set 'cleanup.skip' property on artifacts that
439
- # contain this string in their file inside the directory.
440
- def prevent_artifact_cleanup(repo, directory, pe_build_version)
441
- # Clean up any trailing slashes on directory, just in case
442
- directory.sub!(/(\/)+$/, '')
443
-
444
- all_artifacts_pattern = "#{directory}/*"
445
- latest_artifacts_pattern = "#{directory}/*#{pe_build_version}*"
446
-
447
- all_artifacts = Artifactory::Resource::Artifact.pattern_search(
448
- repo: repo,
449
- pattern: all_artifacts_pattern
450
- )
451
- latest_artifacts = Artifactory::Resource::Artifact.pattern_search(
452
- repo: repo,
453
- pattern: latest_artifacts_pattern
454
- )
455
-
456
- # Clear cleanup.skip on all artifacts in directory
457
- puts "Clearing #{ARTIFACTORY_CLEANUP_SKIP_PROPERTY} in #{repo}/#{all_artifacts_pattern}"
458
- all_artifacts.each do |artifact|
459
- artifact.properties(ARTIFACTORY_CLEANUP_SKIP_PROPERTY => false)
460
- end
461
-
462
- # Set cleanup.skip on all artifacts in directory matching *pe_build_version*
463
- puts "Setting #{ARTIFACTORY_CLEANUP_SKIP_PROPERTY} in #{repo}/#{latest_artifacts_pattern}"
464
- latest_artifacts.each do |artifact|
465
- artifact.properties(ARTIFACTORY_CLEANUP_SKIP_PROPERTY => true)
466
- end
467
- end
468
-
469
- # Search for artifacts matching `artifact_name` in `repo` with path matching
470
- # `path`
471
- # @param artifact_name [String] name of artifact to download
472
- # @param repo [String] repo the artifact lives
473
- # @param path [String] path to artifact in the repo
474
- #
475
- # @return [Array<Artifactory::Resource::Artifact>] A list of artifacts that
476
- # match the query
477
- def search_with_path(artifact_id, repo, path)
478
- check_authorization
479
- artifacts = Artifactory::Resource::Artifact.search(name: artifact_id, repos: repo)
480
- artifacts.select { |artifact| artifact.download_uri.include? path }
481
- end
482
-
483
- # Download an artifact based on name, repo, and path to artifact
484
- # @param artifact_name [String] name of artifact to download
485
- # @param repo [String] repo the artifact lives
486
- # @param path [String] path to artifact in the repo
487
- # @param target [String] directory to download artifact to. Defaults to '.'
488
- # @param filename [String] Filename to save artifact as. Defaults to artifact_name
489
- def download_artifact(artifact_name, repo, path, target: '.', filename: nil)
490
- filename ||= artifact_name
491
- artifacts = search_with_path(artifact_name, repo, path)
492
- return nil if artifacts.empty?
493
- # Only download the first of the artifacts since we're saving them to
494
- # the same location anyways
495
- artifacts.first.download(target, filename: filename)
496
- end
497
-
498
- # Download final pe tarballs to local path based on name, repo, and path on artifactory
499
- # @param pe_version [String] pe final tag
500
- # @param repo [String] repo the tarballs live
501
- # @param remote_path [String] path to tarballs in the repo
502
- # @param local_path [String] local path to download tarballs to
503
- def download_final_pe_tarballs(pe_version, repo, remote_path, local_path)
504
- check_authorization
505
- artifacts = Artifactory::Resource::Artifact.search(name: pe_version, repos: repo, exact_match: false)
506
- artifacts.each do |artifact|
507
- next unless artifact.download_uri.include? remote_path
508
- next if artifact.download_uri.include? "-rc"
509
- artifact.download(local_path)
510
- end
511
- end
512
-
513
- # Download beta pe tarballs to local path based on tag, repo, and path on artifactory
514
- # @param beta_tag [String] rc tag of beta release ex. 2019.2.0-rc10
515
- # @param repo [String] repo the tarballs live
516
- # @param remote_path [String] path to tarballs in the repo
517
- # @param local_path [String] local path to download tarballs to
518
- def download_beta_pe_tarballs(beta_tag, repo, remote_path, local_path)
519
- check_authorization
520
- pattern = "#{remote_path}/*-#{beta_tag}-*"
521
- artifacts = Artifactory::Resource::Artifact.pattern_search(repo: repo, pattern: pattern)
522
- artifacts.each do |artifact|
523
- artifact.download(local_path)
524
- end
525
- end
526
-
527
- # When we ship a new PE release we copy final tarballs to archives/releases
528
- # @param pe_version [String] pe final tag
529
- # @param repo [String] repo the tarballs live
530
- # @param remote_path [String] path to tarballs in the repo
531
- # @param target_path [String] path copy tarballs to, assumes same repo
532
- def copy_final_pe_tarballs(pe_version, repo, remote_path, target_path)
533
- check_authorization
534
- final_tarballs = Artifactory::Resource::Artifact.search(name: pe_version, repos: repo, exact_match: false)
535
- final_tarballs.each do |artifact|
536
- next unless artifact.download_uri.include? remote_path
537
- next if artifact.download_uri.include? "-rc"
538
- filename = File.basename(artifact.download_uri)
539
- # Artifactory does NOT like when you use `File.join`, so let's concatenate!
540
- full_target_path = "#{repo}/#{target_path}/#{filename}"
541
- puts "INFO: Copying #{filename} to #{full_target_path} . . ."
542
- artifact.copy(full_target_path)
233
+ # @param platform_tags [Array[String], String] optional, either a string, or
234
+ # an array of strings. These are the platform or platforms that we will
235
+ # download packages for.
236
+ # @param package [String] optional, the name of the package to be
237
+ # retrieved. If the user does not know this information, we can derive it
238
+ # from the yaml data. This ignores everything but the package name. Any
239
+ # customization for where the user wants to fetch the package is via the
240
+ # download_path parameter.
241
+ # @param download_path [String] Optional, an optional path set to where
242
+ # the user wants the retrieved package to end up. If no path is specified
243
+ # this defaults to the pkg directory.
244
+ def retrieve_package(platform_tags = nil, package = nil, download_path = nil)
245
+
246
+ if platform_tags.nil? && !package.nil?
247
+ platform_tags = Pkg::Paths.tag_from_artifact_path(package) || DEFAULT_REPO_TYPE
248
+ elsif platform_tags.nil? && package.nil?
249
+ yaml_file = retrieve_yaml_data_file(download_path)
250
+ yaml_data = Pkg::Config.config_from_yaml(yaml_file)
251
+ platform_data = yaml_data[:platform_data]
252
+ platform_tags = platform_data.keys
543
253
  end
544
- end
545
-
546
- # Copy an artifact to a target repo/path
547
- #
548
- # @param artifact [Artifactory::Resource::Artifact] The artifact to be copied
549
- # @param target_repo [String] The repository to copy the artifact to
550
- # @param target_path [String] The path in the target repository to copy the artifact to
551
- # @param target_debian_component [String] `deb.component` property to set on the copied artifact
552
- # defaults to `Pkg::Paths.debian_component_from_path(target_path)`
553
- def copy_artifact(artifact, target_repo, target_path, target_debian_component = nil)
554
- filename = File.basename(artifact.download_uri)
555
- artifactory_target_path = "#{target_repo}/#{target_path}"
556
- puts "Copying #{artifact.download_uri} to #{artifactory_target_path}"
557
- begin
558
- artifact.copy(artifactory_target_path)
559
- rescue Artifactory::Error::HTTPError
560
- STDERR.puts "Could not copy #{artifactory_target_path}. Source and destination are the same. Skipping..."
561
- end
562
-
563
- if File.extname(filename) == '.deb'
564
- target_debian_component ||= Pkg::Paths.debian_component_from_path(target_path)
565
- copied_artifact_search = search_with_path(filename, target_repo, target_path)
566
- fail "Error: what the hell, could not find just-copied package #{filename} under #{target_repo}/#{target_path}" if copied_artifact_search.empty?
567
- copied_artifact = copied_artifact_search.first
568
- properties = { 'deb.component' => target_debian_component }
569
- copied_artifact.properties(properties)
570
- end
571
- end
572
-
573
- # When we cut a new PE branch, we need to copy the pe components into <pe_version>/{repos,feature,release}/<platform>
574
- # @param manifest [File] JSON file containing information about what packages to download and the corresponding md5sums
575
- # @param target_path [String] path on artifactory to copy components to, e.g. <pe_version>/release
576
- def populate_pe_repos(manifest, target_path)
577
- check_authorization
578
- manifest.each do |dist, packages|
579
- puts "Copying #{dist} packages..."
580
- packages.each do |name, info|
581
- filename = info["filename"]
582
- artifact = Artifactory::Resource::Artifact.checksum_search(md5: "#{info["md5"]}", repos: ["rpm_enterprise__local", "debian_enterprise__local"], name: filename).first
583
- if artifact.nil?
584
- raise "Error: what the hell, could not find package #{filename} with md5sum #{info["md5"]}"
585
- end
586
- copy_artifact(artifact, artifact.repo, "#{target_path}/#{dist}/#{filename}")
587
- end
588
- end
589
- end
590
254
 
591
- # Remove all artifacts in repo based on pattern, used when we purge all artifacts in release/ after PE release
592
- # @param repos [Array] repos that we want to search for artifacts in
593
- # @param pattern [String] pattern for artifacts that should be deleted ex. `2019.1/release/*/*`
594
- def teardown_repo(repos, pattern)
595
- check_authorization
596
- repos.each do |repo|
597
- artifacts = Artifactory::Resource::Artifact.pattern_search(repo: repo, pattern: pattern)
598
- artifacts.each do |artifact|
599
- puts "Deleting #{artifact.download_uri}"
600
- artifact.delete
601
- end
602
- end
603
- end
604
-
605
- # Remove promoted artifacts if promotion is reverted, use information provided in manifest
606
- # @param manifest [File] JSON file containing information about what packages to download and the corresponding md5sums
607
- # @param remote_path [String] path on artifactory to promoted packages ex. 2019.1/repos/
608
- # @param package [String] package name ex. puppet-agent
609
- # @param repos [Array] the repos the promoted artifacts live
610
- def remove_promoted_packages(manifest, remote_path, package, repos)
611
- check_authorization
612
- manifest.each do |dist, packages|
613
- packages.each do |package_name, info|
614
- next unless package_name == package
615
- filename = info["filename"]
616
- artifacts = Artifactory::Resource::Artifact.checksum_search(md5: "#{info["md5"]}", repos: repos, name: filename)
617
- artifacts.each do |artifact|
618
- next unless artifact.download_uri.include? remote_path
619
- puts "Removing reverted package #{artifact.download_uri}"
620
- artifact.delete
621
- end
255
+ Array(platform_tags).each do |platform_tag|
256
+ puts "fetching package for #{platform_tag}"
257
+ data = platform_specific_data(platform_tag)
258
+ if package.nil?
259
+ package_for_tag = package_name(platform_data, platform_tag)
260
+ puts "package name is #{package_for_tag}"
261
+ else
262
+ package_for_tag = package
622
263
  end
623
- end
624
- end
264
+ download_path_for_tag = download_path || data[:repo_subdirectories].sub(@repo_base, 'pkg')
625
265
 
626
- # Remove shipped PE tarballs from artifactory
627
- # Used when compose fails, we only want the tarball shipped to artifactory if all platforms succeed
628
- # Identify which packages were created and shipped based on md5sum and remove them
629
- # @param tarball_path [String] the local path to the tarballs that were shipped
630
- # @param pe_repo [String] the artifactory repo the tarballs were shipped to
631
- def purge_copied_pe_tarballs(tarball_path, pe_repo)
632
- check_authorization
633
- Dir.foreach("#{tarball_path}/") do |pe_tarball|
634
- next if pe_tarball == '.' || pe_tarball == ".."
635
- md5 = Digest::MD5.file("#{tarball_path}/#{pe_tarball}").hexdigest
636
- artifacts_to_delete = Artifactory::Resource::Artifact.checksum_search(md5: md5, repos: pe_repo, name: pe_tarball)
637
- next if artifacts_to_delete.nil?
638
- begin
639
- artifacts_to_delete.each do |artifact|
640
- puts "Removing #{pe_tarball} from #{pe_repo}... "
641
- artifact.delete
642
- end
643
- rescue Artifactory::Error::HTTPError
644
- STDERR.puts "Error: cannot remove #{pe_tarball}, do you have the right permissions?"
645
- end
266
+ check_authorization
267
+ artifact = Artifactory::Resource::Artifact.new(
268
+ download_uri: File.join(@artifactory_uri, data[:full_artifactory_path], File.basename(package_for_tag))
269
+ )
270
+ artifact.download(download_path_for_tag)
646
271
  end
272
+ rescue
273
+ raise "Attempt to download '#{File.basename(package)}' from #{File.join(@artifactory_uri, data[:full_artifactory_path])} failed."
647
274
  end
648
275
 
649
276
  private :check_authorization