packaging 0.88.77

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 (123) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +17 -0
  3. data/README-Solaris.md +117 -0
  4. data/README.md +977 -0
  5. data/lib/packaging.rb +32 -0
  6. data/lib/packaging/archive.rb +126 -0
  7. data/lib/packaging/artifactory.rb +651 -0
  8. data/lib/packaging/artifactory/extensions.rb +94 -0
  9. data/lib/packaging/config.rb +492 -0
  10. data/lib/packaging/config/params.rb +387 -0
  11. data/lib/packaging/config/validations.rb +13 -0
  12. data/lib/packaging/deb.rb +28 -0
  13. data/lib/packaging/deb/repo.rb +264 -0
  14. data/lib/packaging/gem.rb +70 -0
  15. data/lib/packaging/metrics.rb +15 -0
  16. data/lib/packaging/nuget.rb +39 -0
  17. data/lib/packaging/paths.rb +376 -0
  18. data/lib/packaging/platforms.rb +507 -0
  19. data/lib/packaging/repo.rb +155 -0
  20. data/lib/packaging/retrieve.rb +75 -0
  21. data/lib/packaging/rpm.rb +5 -0
  22. data/lib/packaging/rpm/repo.rb +254 -0
  23. data/lib/packaging/sign.rb +8 -0
  24. data/lib/packaging/sign/deb.rb +9 -0
  25. data/lib/packaging/sign/dmg.rb +41 -0
  26. data/lib/packaging/sign/ips.rb +57 -0
  27. data/lib/packaging/sign/msi.rb +124 -0
  28. data/lib/packaging/sign/rpm.rb +115 -0
  29. data/lib/packaging/tar.rb +163 -0
  30. data/lib/packaging/util.rb +146 -0
  31. data/lib/packaging/util/date.rb +20 -0
  32. data/lib/packaging/util/execution.rb +85 -0
  33. data/lib/packaging/util/file.rb +125 -0
  34. data/lib/packaging/util/git.rb +174 -0
  35. data/lib/packaging/util/git_tags.rb +73 -0
  36. data/lib/packaging/util/gpg.rb +66 -0
  37. data/lib/packaging/util/jenkins.rb +95 -0
  38. data/lib/packaging/util/misc.rb +69 -0
  39. data/lib/packaging/util/net.rb +410 -0
  40. data/lib/packaging/util/os.rb +17 -0
  41. data/lib/packaging/util/platform.rb +40 -0
  42. data/lib/packaging/util/rake_utils.rb +112 -0
  43. data/lib/packaging/util/serialization.rb +19 -0
  44. data/lib/packaging/util/ship.rb +300 -0
  45. data/lib/packaging/util/tool.rb +41 -0
  46. data/lib/packaging/util/version.rb +334 -0
  47. data/spec/fixtures/config/ext/build_defaults.yaml +2 -0
  48. data/spec/fixtures/config/ext/project_data.yaml +2 -0
  49. data/spec/fixtures/configs/components/test_file.json +1 -0
  50. data/spec/fixtures/configs/components/test_file_2.json +0 -0
  51. data/spec/fixtures/configs/components/test_file_not_tagged.json +1 -0
  52. data/spec/fixtures/configs/components/test_file_wrong_ext.txt +0 -0
  53. data/spec/fixtures/configs/components/test_file_wrong_ext.wrong +0 -0
  54. data/spec/fixtures/util/pre_tasks.yaml +4 -0
  55. data/spec/lib/packaging/artifactory_spec.rb +221 -0
  56. data/spec/lib/packaging/config_spec.rb +576 -0
  57. data/spec/lib/packaging/deb/repo_spec.rb +157 -0
  58. data/spec/lib/packaging/deb_spec.rb +52 -0
  59. data/spec/lib/packaging/gem_spec.rb +86 -0
  60. data/spec/lib/packaging/paths_spec.rb +418 -0
  61. data/spec/lib/packaging/platforms_spec.rb +178 -0
  62. data/spec/lib/packaging/repo_spec.rb +135 -0
  63. data/spec/lib/packaging/retrieve_spec.rb +100 -0
  64. data/spec/lib/packaging/rpm/repo_spec.rb +133 -0
  65. data/spec/lib/packaging/sign_spec.rb +133 -0
  66. data/spec/lib/packaging/tar_spec.rb +116 -0
  67. data/spec/lib/packaging/util/execution_spec.rb +56 -0
  68. data/spec/lib/packaging/util/file_spec.rb +139 -0
  69. data/spec/lib/packaging/util/git_spec.rb +160 -0
  70. data/spec/lib/packaging/util/git_tag_spec.rb +36 -0
  71. data/spec/lib/packaging/util/gpg_spec.rb +64 -0
  72. data/spec/lib/packaging/util/jenkins_spec.rb +112 -0
  73. data/spec/lib/packaging/util/misc_spec.rb +31 -0
  74. data/spec/lib/packaging/util/net_spec.rb +259 -0
  75. data/spec/lib/packaging/util/os_spec.rb +31 -0
  76. data/spec/lib/packaging/util/rake_utils_spec.rb +70 -0
  77. data/spec/lib/packaging/util/ship_spec.rb +199 -0
  78. data/spec/lib/packaging/util/version_spec.rb +123 -0
  79. data/spec/lib/packaging_spec.rb +19 -0
  80. data/spec/spec_helper.rb +22 -0
  81. data/static_artifacts/PackageInfo.plist +3 -0
  82. data/tasks/00_utils.rake +214 -0
  83. data/tasks/30_metrics.rake +33 -0
  84. data/tasks/apple.rake +268 -0
  85. data/tasks/archive.rake +69 -0
  86. data/tasks/build.rake +12 -0
  87. data/tasks/clean.rake +5 -0
  88. data/tasks/config.rake +35 -0
  89. data/tasks/deb.rake +129 -0
  90. data/tasks/deb_repos.rake +28 -0
  91. data/tasks/deprecated.rake +130 -0
  92. data/tasks/doc.rake +20 -0
  93. data/tasks/education.rake +57 -0
  94. data/tasks/fetch.rake +60 -0
  95. data/tasks/gem.rake +159 -0
  96. data/tasks/jenkins.rake +538 -0
  97. data/tasks/jenkins_dynamic.rake +202 -0
  98. data/tasks/load_extras.rake +21 -0
  99. data/tasks/mock.rake +348 -0
  100. data/tasks/nightly_repos.rake +286 -0
  101. data/tasks/pe_deb.rake +12 -0
  102. data/tasks/pe_rpm.rake +13 -0
  103. data/tasks/pe_ship.rake +226 -0
  104. data/tasks/pe_sign.rake +13 -0
  105. data/tasks/pe_tar.rake +5 -0
  106. data/tasks/retrieve.rake +52 -0
  107. data/tasks/rpm.rake +66 -0
  108. data/tasks/rpm_repos.rake +29 -0
  109. data/tasks/ship.rake +692 -0
  110. data/tasks/sign.rake +154 -0
  111. data/tasks/tag.rake +8 -0
  112. data/tasks/tar.rake +28 -0
  113. data/tasks/update.rake +16 -0
  114. data/tasks/vanagon.rake +35 -0
  115. data/tasks/vendor_gems.rake +117 -0
  116. data/tasks/version.rake +33 -0
  117. data/tasks/z_data_dump.rake +65 -0
  118. data/templates/README +1 -0
  119. data/templates/downstream.xml.erb +47 -0
  120. data/templates/msi.xml.erb +197 -0
  121. data/templates/packaging.xml.erb +346 -0
  122. data/templates/repo.xml.erb +117 -0
  123. metadata +287 -0
@@ -0,0 +1,70 @@
1
+ require 'json'
2
+ module Pkg::Gem
3
+ class << self
4
+ def ship(file)
5
+ rsync_to_downloads(file)
6
+ ship_to_rubygems(file)
7
+ end
8
+
9
+ # Use rsync to deploy a file and any associated detached signatures,
10
+ # checksums, or other glob-able artifacts to an external download server.
11
+ def rsync_to_downloads(file)
12
+ Pkg::Util.deprecate('Pkg::Gem.rsync_to_downloads', 'Pkg::Util::Ship.ship_pkgs')
13
+ Pkg::Util::Ship.ship_pkgs(["#{file}*"], Pkg::Config.gem_host,
14
+ Pkg::Config.gem_path, platform_independent: true)
15
+ end
16
+
17
+ def shipped_to_rubygems?(gem_name, gem_version, gem_platform)
18
+ rubygems_url = "https://rubygems.org/api/v1/versions/#{gem_name}.json"
19
+ gem_data = JSON.parse(%x(curl --silent #{rubygems_url}))
20
+ gem = gem_data.select do |data|
21
+ data['number'] == gem_version && data['platform'] == gem_platform
22
+ end
23
+ return !gem.empty?
24
+ rescue => e
25
+ puts "Something went wrong searching for gem '#{gem_name}':"
26
+ puts e
27
+ puts "Perhaps you're shipping '#{gem_name}' for the first time?"
28
+ return false
29
+ end
30
+
31
+ # Ship a Ruby gem file to rubygems.org. Requires the existence
32
+ # of a ~/.gem/credentials file or else rubygems.org won't have
33
+ # any idea who you are.
34
+ def ship_to_rubygems(file, options = {})
35
+ # rubygems uses 'ruby' as the platform when it's not a platform-specific
36
+ # gem
37
+ platform = file.match(/\w+-(?:\d+(?:\.)?)+-(.*)\.gem$/)
38
+ unless platform.nil?
39
+ gem_platform = platform[1]
40
+ end
41
+ gem_platform ||= 'ruby'
42
+
43
+ if shipped_to_rubygems?(Pkg::Config.gem_name, Pkg::Config.gemversion, gem_platform)
44
+ puts "#{file} has already been shipped to rubygems, skipping."
45
+ return
46
+ end
47
+ Pkg::Util::File.file_exists?("#{ENV['HOME']}/.gem/credentials", :required => true)
48
+ gem_push_command = "gem push #{file}"
49
+ gem_push_command << " --host #{options[:host]}" if options[:host]
50
+ gem_push_command << " --key #{options[:key]}" if options[:key]
51
+ Pkg::Util::Execution.capture3(gem_push_command)
52
+ rescue => e
53
+ puts "###########################################"
54
+ puts "# Publishing to rubygems failed. Make sure your .gem/credentials"
55
+ puts "# file is set up and you are an owner of #{Pkg::Config.gem_name}"
56
+ puts "###########################################"
57
+ puts
58
+ puts e
59
+ raise e
60
+ end
61
+
62
+ def ship_to_internal_mirror(file)
63
+ internal_mirror_api_key_name = 'artifactory_api_key'
64
+ ship_to_rubygems(file, {
65
+ host: Pkg::Config.internal_gem_host,
66
+ key: internal_mirror_api_key_name
67
+ })
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,15 @@
1
+ module Pkg::Metrics
2
+ module_function
3
+
4
+ def update_release_metrics
5
+ metrics_repo = 'release-metrics'
6
+ command = <<CMD
7
+ git clone git@github.com:puppetlabs/#{metrics_repo}.git
8
+ cd #{metrics_repo}
9
+ bundle exec add-release --date #{Pkg::Util::Date.today} --project #{Pkg::Config.project} --version #{Pkg::Config.ref}
10
+ cd ..
11
+ rm -r #{metrics_repo}
12
+ CMD
13
+ Pkg::Util::Execution.capture3(command, true)
14
+ end
15
+ end
@@ -0,0 +1,39 @@
1
+ module Pkg::Nuget
2
+ class << self
3
+ def ship(packages)
4
+ #
5
+ # Support shipping of Nuget style packages to an Artifactory based nuget feed
6
+ # Using curl to submit the packages rather than windows based choco/mono.
7
+ # This approach gives more flexibility and fits in with the current Puppet
8
+ # release automation practices using linux/mac systems.
9
+
10
+ # Sanity checks
11
+ fail "NUGET_HOST is not defined" if Pkg::Config.nuget_host.empty?
12
+ fail "NUGET_REPO is not defined" if Pkg::Config.nuget_repo_path.to_s.empty?
13
+
14
+ # Retrieve password without revealing it
15
+ puts "Obtaining credentials to ship to nuget feed #{Pkg::Config.nuget_repo_path} on #{Pkg::Config.nuget_host}"
16
+ print "Username please: "
17
+ username = Pkg::Util.get_input(true)
18
+ print "Password please: "
19
+ password = Pkg::Util.get_input(false)
20
+ authentication = Pkg::Util.base64_encode("#{username}:#{password}")
21
+
22
+ uri = "#{Pkg::Config.nuget_host}#{Pkg::Config.nuget_repo_path}"
23
+ form_data = ["-H 'Authorization: Basic #{authentication}'", "-f"]
24
+ packages.each do |pkg|
25
+ puts "Working on package #{pkg}"
26
+ projname, version = File.basename(pkg).match(/^(.*)-([\d+\.]+)\.nupkg$/).captures
27
+ package_form_data = ["--upload-file #{pkg}"]
28
+ package_path = "#{projname}/#{version}/#{File.basename(pkg)}"
29
+ stdout = ''
30
+ retval = ''
31
+ Pkg::Util::Execution.retry_on_fail(:times => 3) do
32
+ stdout, retval = Pkg::Util::Net.curl_form_data("#{uri}/#{package_path}", form_data + package_form_data)
33
+ end
34
+ fail "The Package upload (curl) failed with error #{retval}" unless Pkg::Util::Execution.success?(retval)
35
+ stdout
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,376 @@
1
+ # Utilities surrounding the appropriate paths associated with a platform
2
+ # This includes both reporting the correct path and divining the platform
3
+ # tag associated with a variety of paths
4
+ #
5
+ # rubocop:disable Metrics/ModuleLength
6
+ module Pkg::Paths
7
+ include Pkg::Platforms
8
+
9
+ module_function
10
+
11
+ def arch_from_artifact_path(platform, version, path)
12
+ arches = Pkg::Platforms.arches_for_platform_version(platform, version)
13
+
14
+ # First check if it's a source package
15
+ source_formats = Pkg::Platforms.get_attribute_for_platform_version(platform, version, :source_package_formats)
16
+ if source_formats.find { |fmt| path =~ /#{fmt}$/ }
17
+ return Pkg::Platforms.get_attribute_for_platform_version(platform, version, :source_architecture)
18
+ end
19
+ arches.find { |a| path.include?(package_arch(platform, a)) } || arches[0]
20
+ rescue
21
+ arches.find { |a| path.include?(package_arch(platform, a)) } || arches[0]
22
+ end
23
+
24
+ # Given a path to an artifact, divine the appropriate platform tag associated
25
+ # with the artifact and path
26
+ def tag_from_artifact_path(path)
27
+ platform = Pkg::Platforms.supported_platforms.find { |p| path =~ /(\/|\.)#{p}[^\.]/ }
28
+ platform = 'windowsfips' if path =~ /windowsfips/
29
+
30
+ codename = Pkg::Platforms.codenames.find { |c| path =~ /\/#{c}/ }
31
+
32
+ if codename
33
+ platform, version = Pkg::Platforms.codename_to_platform_version(codename)
34
+ end
35
+
36
+ version = '2012' if platform =~ /^windows.*$/
37
+
38
+ version ||= Pkg::Platforms.versions_for_platform(platform).find { |v| path =~ /#{platform}(\/|-)?#{v}/ }
39
+
40
+ arch = arch_from_artifact_path(platform, version, path)
41
+
42
+ return "#{platform}-#{version}-#{arch}"
43
+ rescue
44
+ fmt = Pkg::Platforms.all_supported_package_formats.find { |ext| path =~ /#{ext}$/ }
45
+
46
+ # We need to make sure this is actually a file, and not simply a path
47
+ file_ext = File.extname(path)
48
+
49
+ # Fail if we do not have a file extension or if that file extension is one
50
+ # that is platform specific
51
+ raise "Cannot determine tag from #{path}" if fmt || file_ext.empty?
52
+
53
+ # Return nil otherwise, assuming that is a file type that is not tied to a
54
+ # specific platform
55
+ return nil
56
+ end
57
+
58
+ # Assign repo name
59
+ # If we are shipping development/beta/non-final packages, they should be
60
+ # shipped to the development/beta/non-final repo, if there is one defined.
61
+ # Otherwise, default to the final repo name. We use this for more than just
62
+ # shipping to the final repos, so we need this to not fail.
63
+ def repo_name(nonfinal = false)
64
+ if nonfinal && Pkg::Config.nonfinal_repo_name
65
+ Pkg::Config.nonfinal_repo_name
66
+ elsif nonfinal
67
+ fail "Nonfinal is set to true but Pkg::Config.nonfinal_repo_name is unset!"
68
+ else
69
+ Pkg::Config.repo_name || ""
70
+ end
71
+ end
72
+
73
+ # Method to determine the yum repo name. Maintains compatibility with legacy
74
+ # projects, where `Pkg::Config.yum_repo_name` is set instead of
75
+ # `Pkg::Config.repo_name`. Defaults to 'products' if nothing is set.
76
+ def yum_repo_name(nonfinal = false)
77
+ if nonfinal && Pkg::Config.nonfinal_repo_name
78
+ return Pkg::Config.nonfinal_repo_name
79
+ elsif nonfinal
80
+ fail "Nonfinal is set to true but Pkg::Config.nonfinal_repo_name is unset!"
81
+ end
82
+
83
+ return Pkg::Config.repo_name || Pkg::Config.yum_repo_name || 'products'
84
+ end
85
+
86
+ # Method to determine the apt repo name. Maintains compatibility with legacy
87
+ # projects, where `Pkg::Config.apt_repo_name` is set instead of
88
+ # `Pkg::Config.repo_name`. Defaults to 'main' if nothing is set.
89
+ def apt_repo_name(nonfinal = false)
90
+ if nonfinal && Pkg::Config.nonfinal_repo_name
91
+ return Pkg::Config.nonfinal_repo_name
92
+ elsif nonfinal
93
+ fail "Nonfinal is set to true but Pkg::Config.nonfinal_repo_name is unset!"
94
+ end
95
+
96
+ return Pkg::Config.repo_name || Pkg::Config.apt_repo_name || 'main'
97
+ end
98
+
99
+ def link_name(nonfinal = false)
100
+ return Pkg::Config.nonfinal_repo_link_target if nonfinal
101
+ return Pkg::Config.repo_link_target
102
+ end
103
+
104
+ # Construct a platform-dependent symlink target path.
105
+ def construct_base_path(path_data)
106
+ package_format = path_data[:package_format]
107
+ prefix = path_data[:prefix]
108
+ is_nonfinal = path_data[:is_nonfinal]
109
+ platform_name = path_data[:platform_name]
110
+ platform_tag = path_data[:platform_tag]
111
+
112
+ repo_name = Pkg::Config.repo_name
113
+
114
+ case package_format
115
+ when 'deb'
116
+ debian_code_name = Pkg::Platforms.get_attribute(platform_tag, :codename)
117
+
118
+ # In puppet7 and beyond, we moved the repo_name to the top to allow each
119
+ # puppet major release to have its own apt repo.
120
+ if %w(FUTURE-puppet7 FUTURE-puppet7-nightly).include? repo_name
121
+ return File.join(prefix, apt_repo_name(is_nonfinal), debian_code_name)
122
+ end
123
+
124
+ # For puppet6 and prior
125
+ return File.join(prefix, debian_code_name, apt_repo_name(is_nonfinal))
126
+ when 'dmg'
127
+ return File.join(prefix, 'mac', repo_name(is_nonfinal))
128
+ when 'msi'
129
+ return File.join(prefix, platform_name, repo_name(is_nonfinal))
130
+ when 'rpm'
131
+ return File.join(prefix, yum_repo_name(is_nonfinal))
132
+ when 'swix'
133
+ return File.join(prefix, platform_name, repo_name(is_nonfinal))
134
+ when 'svr4', 'ips'
135
+ return File.join(prefix, 'solaris', repo_name(is_nonfinal))
136
+ else
137
+ raise "Error: Unknown package format '#{package_format}'"
138
+ end
139
+ end
140
+
141
+ # Construct a platform-dependent link path
142
+ def construct_link_path(path_data)
143
+ package_format = path_data[:package_format]
144
+ prefix = path_data[:prefix]
145
+ platform_name = path_data[:platform_name]
146
+ platform_tag = path_data[:platform_tag]
147
+ link = path_data[:link]
148
+
149
+ return nil if link.nil?
150
+
151
+ case package_format
152
+ when 'rpm'
153
+ return File.join(prefix, link)
154
+ when 'swix'
155
+ return File.join(prefix, platform_name, link)
156
+ when 'deb'
157
+ debian_code_name = Pkg::Platforms.get_attribute(platform_tag, :codename)
158
+ return File.join(prefix, debian_code_name, link)
159
+ when 'svr4', 'ips'
160
+ return File.join(prefix, 'solaris', link)
161
+ when 'dmg'
162
+ return File.join(prefix, 'mac', link)
163
+ when 'msi'
164
+ return File.join(prefix, platform_name, link)
165
+ else
166
+ raise "Error: Unknown package format '#{package_format}'"
167
+ end
168
+ end
169
+
170
+ # Given platform information, create symlink target (base_path) and link path in the
171
+ # form of a 2-element array
172
+ def artifacts_base_path_and_link_path(platform_tag, prefix = 'artifacts', is_nonfinal = false)
173
+ platform_name, _ = Pkg::Platforms.parse_platform_tag(platform_tag)
174
+ package_format = Pkg::Platforms.package_format_for_tag(platform_tag)
175
+
176
+ path_data = {
177
+ is_nonfinal: is_nonfinal,
178
+ link: link_name(is_nonfinal),
179
+ package_format: package_format,
180
+ platform_name: platform_name,
181
+ platform_tag: platform_tag,
182
+ prefix: prefix
183
+ }
184
+
185
+ return [
186
+ construct_base_path(path_data),
187
+ construct_link_path(path_data)
188
+ ]
189
+ end
190
+
191
+ def artifacts_path(platform_tag, path_prefix = 'artifacts', nonfinal = false)
192
+ base_path, _ = artifacts_base_path_and_link_path(platform_tag, path_prefix, nonfinal)
193
+ platform, version, architecture = Pkg::Platforms.parse_platform_tag(platform_tag)
194
+ package_format = Pkg::Platforms.package_format_for_tag(platform_tag)
195
+
196
+ case package_format
197
+ when 'rpm'
198
+ File.join(base_path, platform, version, architecture)
199
+ when 'swix'
200
+ File.join(base_path, version, architecture)
201
+ when 'deb'
202
+ base_path
203
+ when 'svr4', 'ips'
204
+ File.join(base_path, version)
205
+ when 'dmg'
206
+ File.join(base_path, version, architecture)
207
+ when 'msi'
208
+ base_path
209
+ else
210
+ raise "Not sure where to find packages with a package format of '#{package_format}'"
211
+ end
212
+ end
213
+
214
+ def repo_path(platform_tag, options = { :legacy => false, :nonfinal => false })
215
+ repo_target = repo_name(options[:nonfinal])
216
+ # in legacy packaging methods, there was no consistent way to determine the
217
+ # repo name. There were separate variables for apt_repo_name and
218
+ # yum_repo_name. At times, either or both of these were unset, and they had
219
+ # different defaults. So, for legacy automation we need to just use a splat
220
+ # and globbing to find our packages.
221
+ repo_target = '**' if options[:legacy]
222
+ platform, version, arch = Pkg::Platforms.parse_platform_tag(platform_tag)
223
+ package_format = Pkg::Platforms.package_format_for_tag(platform_tag)
224
+
225
+ case package_format
226
+ when 'rpm', 'swix'
227
+ if options[:legacy]
228
+ File.join('repos', platform, version, repo_target, arch)
229
+ else
230
+ File.join('repos', repo_target, platform, version, arch)
231
+ end
232
+ when 'deb'
233
+ File.join('repos', 'apt', Pkg::Platforms.get_attribute(platform_tag, :codename), 'pool', repo_target)
234
+ when 'svr4', 'ips'
235
+ if options[:legacy]
236
+ File.join('repos', 'solaris', version, repo_target)
237
+ else
238
+ File.join('repos', 'solaris', repo_target, version)
239
+ end
240
+ when 'dmg'
241
+ if options[:legacy]
242
+ File.join('repos', 'apple', version, repo_target, arch)
243
+ else
244
+ File.join('repos', 'mac', repo_target, version, arch)
245
+ end
246
+ when 'msi'
247
+ if options[:legacy]
248
+ File.join('repos', 'windows')
249
+ else
250
+ File.join('repos', platform, repo_target)
251
+ end
252
+ else
253
+ raise "Not sure what to do with a package format of '#{package_format}'"
254
+ end
255
+ end
256
+
257
+ def repo_config_path(platform_tag)
258
+ package_format = Pkg::Platforms.package_format_for_tag(platform_tag)
259
+
260
+ case package_format
261
+ when 'rpm'
262
+ # rpm/pl-puppet-agent-1.2.5-el-5-i386.repo for example
263
+ File.join('repo_configs', 'rpm', "*#{platform_tag}*.repo")
264
+ when 'deb'
265
+ # deb/pl-puppet-agent-1.2.5-jessie.list
266
+ File.join('repo_configs', 'deb', "*#{Pkg::Platforms.get_attribute(platform_tag, :codename)}*.list")
267
+ when 'msi', 'swix', 'dmg', 'svr4', 'ips'
268
+ nil
269
+ else
270
+ raise "Not sure what to do with a package format of '#{package_format}'"
271
+ end
272
+ end
273
+
274
+ def remote_repo_base(platform_tag = nil, nonfinal: false, package_format: nil)
275
+ if platform_tag.nil? && package_format.nil?
276
+ raise "Pkg::Paths.remote_repo_base must have `platform_tag` or `package_format` specified."
277
+ end
278
+
279
+ package_format ||= Pkg::Platforms.package_format_for_tag(platform_tag)
280
+
281
+ repo_base = case package_format
282
+ when 'rpm'
283
+ nonfinal ? Pkg::Config.nonfinal_yum_repo_path : Pkg::Config.yum_repo_path
284
+ when 'deb'
285
+ nonfinal ? Pkg::Config.nonfinal_apt_repo_path : Pkg::Config.apt_repo_path
286
+ when 'dmg'
287
+ nonfinal ? Pkg::Config.nonfinal_dmg_path : Pkg::Config.dmg_path
288
+ when 'swix'
289
+ nonfinal ? Pkg::Config.nonfinal_swix_path : Pkg::Config.swix_path
290
+ when 'msi'
291
+ nonfinal ? Pkg::Config.nonfinal_msi_path : Pkg::Config.msi_path
292
+ else
293
+ raise "Can't determine remote repo base path for package format '#{package_format}'."
294
+ end
295
+
296
+ # normalize the path for things shipping to the downloads server
297
+ if repo_base.match(/^\/opt\/downloads\/\w+$/)
298
+ repo_base = '/opt/downloads'
299
+ end
300
+ repo_base
301
+ end
302
+
303
+ # This is where deb packages end up after freight repo updates
304
+ def apt_package_base_path(platform_tag, repo_name, project, nonfinal = false)
305
+ unless Pkg::Platforms.package_format_for_tag(platform_tag) == 'deb'
306
+ fail "Can't determine path for non-debian platform #{platform_tag}."
307
+ end
308
+
309
+ platform, version, _ = Pkg::Platforms.parse_platform_tag(platform_tag)
310
+ code_name = Pkg::Platforms.codename_for_platform_version(platform, version)
311
+ remote_repo_path = remote_repo_base(platform_tag, nonfinal: nonfinal)
312
+
313
+ # In puppet7 and beyond, we moved the puppet major version to near the top to allow each
314
+ # puppet major release to have its own apt repo, for example:
315
+ # /opt/repository/apt/puppet7/pool/bionic/p/puppet-agent
316
+ if %w(FUTURE-puppet7 FUTURE-puppet7-nightly).include? repo_name
317
+ return File.join(remote_repo_path, repo_name, 'pool', code_name, project[0], project)
318
+ end
319
+
320
+ # For repos prior to puppet7, the puppet version was part of the repository
321
+ # For example: /opt/repository/apt/pool/bionic/puppet6/p/puppet-agent
322
+ if %w(puppet7 puppet7-nightly
323
+ puppet6 puppet6-nightly
324
+ puppet5 puppet5-nightly
325
+ puppet puppet-nightly
326
+ puppet-tools).include? repo_name
327
+ return File.join(remote_repo_path, 'pool', code_name, repo_name, project[0], project)
328
+ end
329
+
330
+ raise "Error: Cannot determine apt_package_base_path for repo: \"#{repo_name}\"."
331
+ end
332
+
333
+ def release_package_link_path(platform_tag, nonfinal = false)
334
+ platform, version, _ = Pkg::Platforms.parse_platform_tag(platform_tag)
335
+ package_format = Pkg::Platforms.package_format_for_tag(platform_tag)
336
+ case package_format
337
+ when 'rpm'
338
+ return File.join(remote_repo_base(platform_tag, nonfinal: nonfinal),
339
+ "#{repo_name(nonfinal)}-release-#{platform}-#{version}.noarch.rpm")
340
+ when 'deb'
341
+ codename = Pkg::Platforms.codename_for_platform_version(platform, version)
342
+ return File.join(remote_repo_base(platform_tag, nonfinal: nonfinal),
343
+ "#{repo_name(nonfinal)}-release-#{codename}.deb")
344
+ else
345
+ warn "No release packages for package format '#{package_format}', skipping."
346
+ return nil
347
+ end
348
+ end
349
+
350
+ def debian_component_from_path(path)
351
+ # substitute '.' and '/' since those aren't valid characters for debian components
352
+ matches = path.match(/(\d+\.\d+|master|main)\/(\w+)/)
353
+ regex_for_substitution = /[\.\/]/
354
+ fail "Error: Could not determine Debian Component from path #{path}" if matches.nil?
355
+ base_component = matches[1]
356
+ component_qualifier = matches[2]
357
+ full_component = "#{base_component}/#{component_qualifier}"
358
+ unless regex_for_substitution.nil?
359
+ base_component.gsub!(regex_for_substitution, '_')
360
+ full_component.gsub!(regex_for_substitution, '_')
361
+ end
362
+ return base_component if component_qualifier == 'repos'
363
+ return full_component
364
+ end
365
+
366
+ #for ubuntu-20.04-aarch64, debian package architecture is arm64
367
+ def package_arch(platform, arch)
368
+ if platform == 'ubuntu' && arch == 'aarch64'
369
+ return 'arm64'
370
+ end
371
+ arch
372
+ end
373
+
374
+ private :package_arch
375
+
376
+ end