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,155 @@
1
+ module Pkg::Repo
2
+
3
+ class << self
4
+
5
+ ##
6
+ ## Construct a local_target based upon the versioning style
7
+ ##
8
+ def construct_local_target_path(project, versioning)
9
+ case versioning
10
+ when 'ref'
11
+ return File.join(project, Pkg::Config.ref)
12
+ when 'version'
13
+ return File.join(project, Pkg::Util::Version.dot_version)
14
+ else
15
+ fail "Error: Unknown versioning argument: #{versioning}"
16
+ end
17
+ end
18
+
19
+ ##
20
+ ## Put a single signed repo into a tarball stored in
21
+ ## 'pkg/<local_target>/<archive_name>.tar.gz'
22
+ ##
23
+ def create_signed_repo_archive(repo_location, archive_name, versioning)
24
+ tar = Pkg::Util::Tool.check_tool('tar')
25
+
26
+ local_target = construct_local_target_path(Pkg::Config.project, versioning)
27
+
28
+ if Pkg::Util::File.empty_dir?(File.join('pkg', local_target, repo_location))
29
+ if ENV['FAIL_ON_MISSING_TARGET'] == "true"
30
+ raise "Error: missing packages under #{repo_location}"
31
+ end
32
+ warn "Warn: Skipping #{archive_name} because #{repo_location} has no files"
33
+ return
34
+ end
35
+
36
+ Dir.chdir(File.join('pkg', local_target)) do
37
+ puts "Info: Archiving #{repo_location} as #{archive_name}"
38
+ target_tarball = File.join('repos', "#{archive_name}.tar.gz")
39
+ tar_command = "#{tar} --owner=0 --group=0 --create --gzip --file #{target_tarball} #{repo_location}"
40
+ stdout, _, _ = Pkg::Util::Execution.capture3(tar_command)
41
+ return stdout
42
+ end
43
+ end
44
+
45
+ ##
46
+ ## Add a single repo tarball into the 'all' tarball located in
47
+ ## 'pkg/<local_target>/<project>-all.tar'
48
+ ## Create the 'all' tarball if needed.
49
+ ##
50
+ def update_tarball_of_all_repos(project, platform, versioning)
51
+ tar = Pkg::Util::Tool.check_tool('tar')
52
+
53
+ all_repos_tarball_name = "#{project}-all.tar"
54
+ archive_name = "#{project}-#{platform['name']}"
55
+ local_target = construct_local_target_path(project, versioning)
56
+ repo_tarball_name = "#{archive_name}.tar.gz"
57
+ repo_tarball_path = File.join('repos', repo_tarball_name)
58
+
59
+ Dir.chdir(File.join('pkg', local_target)) do
60
+ unless Pkg::Util::File.exist?(repo_tarball_path)
61
+ warn "Skipping #{archive_name} because it (#{repo_tarball_path}) contains no files"
62
+ next
63
+ end
64
+
65
+ tar_action = "--create"
66
+ if File.exist?(all_repos_tarball_name)
67
+ tar_action = "--update"
68
+ end
69
+
70
+ tar_command = "#{tar} --owner=0 --group=0 #{tar_action} --file #{all_repos_tarball_name} #{repo_tarball_path}"
71
+ stdout, _, _ = Pkg::Util::Execution.capture3(tar_command)
72
+ puts stdout
73
+ end
74
+ end
75
+
76
+ ##
77
+ ## Invoke gzip to compress the 'all' tarball located in
78
+ ## 'pkg/<local_target>/<project>-all.tar'
79
+ ##
80
+ def compress_tarball_of_all_repos(all_repos_tarball_name)
81
+ gzip = Pkg::Util::Tool.check_tool('gzip')
82
+
83
+ gzip_command = "#{gzip} --fast #{all_repos_tarball_name}"
84
+ stdout, _, _ = Pkg::Util::Execution.capture3(gzip_command)
85
+ puts stdout
86
+ end
87
+
88
+ ##
89
+ ## Generate each of the repos listed in <Config.platform_repos>.
90
+ ## Update the 'all repos' tarball as we do each one.
91
+ ## Compress the 'all repos' tarball when all the repos have been generated
92
+ ##
93
+ def create_all_repo_archives(project, versioning)
94
+ platforms = Pkg::Config.platform_repos
95
+ local_target = construct_local_target_path(project, versioning)
96
+ all_repos_tarball_name = "#{project}-all.tar"
97
+
98
+ platforms.each do |platform|
99
+ archive_name = "#{project}-#{platform['name']}"
100
+ create_signed_repo_archive(platform['repo_location'], archive_name, versioning)
101
+ update_tarball_of_all_repos(project, platform, versioning)
102
+ end
103
+
104
+ Dir.chdir(File.join('pkg', local_target)) do
105
+ compress_tarball_of_all_repos(all_repos_tarball_name)
106
+ end
107
+ end
108
+
109
+ def directories_that_contain_packages(artifact_directory, pkg_ext)
110
+ cmd = "[ -d #{artifact_directory} ] || exit 1 ; "
111
+ cmd << "pushd #{artifact_directory} > /dev/null && "
112
+ cmd << "find . -name '*.#{pkg_ext}' -print0 | xargs --no-run-if-empty -0 -I {} dirname {} "
113
+ stdout, _ = Pkg::Util::Net.remote_execute(
114
+ Pkg::Config.distribution_server,
115
+ cmd,
116
+ { capture_output: true }
117
+ )
118
+ return stdout.split
119
+ rescue => e
120
+ fail "Error: Could not retrieve directories that contain #{pkg_ext} packages in #{Pkg::Config.distribution_server}:#{artifact_directory}"
121
+ end
122
+
123
+ def populate_repo_directory(artifact_parent_directory)
124
+ cmd = "[ -d #{artifact_parent_directory}/artifacts ] || exit 1 ; "
125
+ cmd << "pushd #{artifact_parent_directory} > /dev/null && "
126
+ cmd << 'rsync --archive --verbose --one-file-system --ignore-existing artifacts/ repos/ '
127
+ Pkg::Util::Net.remote_execute(Pkg::Config.distribution_server, cmd)
128
+ rescue => e
129
+ fail "Error: Could not populate repos directory in #{Pkg::Config.distribution_server}:#{artifact_parent_directory}"
130
+ end
131
+
132
+ def argument_required?(argument_name, repo_command)
133
+ repo_command.include?("__#{argument_name.upcase}__")
134
+ end
135
+
136
+ def update_repo(remote_host, command, options = {})
137
+ fail_message = "Error: Missing required argument '%s', update your build_defaults?"
138
+ [:repo_name, :repo_path, :repo_host, :repo_url].each do |option|
139
+ fail fail_message % option.to_s if argument_required?(option.to_s, command) && !options[option]
140
+ end
141
+
142
+ whitelist = {
143
+ __REPO_NAME__: options[:repo_name],
144
+ __REPO_PATH__: options[:repo_path],
145
+ __REPO_HOST__: options[:repo_host],
146
+ __REPO_URL__: options[:repo_url],
147
+ __APT_PLATFORMS__: Pkg::Config.apt_releases.join(' '),
148
+ __GPG_KEY__: Pkg::Util::Gpg.key
149
+ }
150
+ Pkg::Util::Net.remote_execute(
151
+ remote_host,
152
+ Pkg::Util::Misc.search_and_replace(command, whitelist))
153
+ end
154
+ end
155
+ end
@@ -0,0 +1,75 @@
1
+ module Pkg::Retrieve
2
+ module_function
3
+
4
+ # --no-parent = Only descend when recursing, never ascend
5
+ # --no-host-directories = Discard http://#{Pkg::Config.builds_server} when saving to disk
6
+ # --level=0 = infinitely recurse, no limit
7
+ # --cut-dirs 3 = will cut off #{Pkg::Config.project}, #{Pkg::Config.ref}, and the first directory in #{remote_target} from the url when saving to disk
8
+ # --directory-prefix = where to save to disk (defaults to ./)
9
+ # --reject = Reject all hits that match the supplied regex
10
+
11
+ def default_wget_command(local_target, url, additional_options = {})
12
+ default_options = {
13
+ 'quiet' => true,
14
+ 'recursive' => true,
15
+ 'no-parent' => true,
16
+ 'no-host-directories' => true,
17
+ 'level' => 0,
18
+ 'cut-dirs' => 3,
19
+ 'directory-prefix' => local_target,
20
+ 'reject' => "'index*'",
21
+ }
22
+ options = default_options.merge(additional_options)
23
+ wget = Pkg::Util::Tool.check_tool('wget')
24
+ wget_command = wget
25
+ options.each do |option, value|
26
+ next unless value
27
+ if value.is_a?(TrueClass)
28
+ wget_command << " --#{option}"
29
+ else
30
+ wget_command << " --#{option}=#{value}"
31
+ end
32
+ end
33
+ wget_command << " #{url}"
34
+ return wget_command
35
+ end
36
+
37
+ # NOTE: When supplying additional options, if you want your value to be
38
+ # quoted (e.g. --reject='index*'), you must include the quotes as part of
39
+ # your string (e.g. {'reject' => "'index*'"}).
40
+ def default_wget(local_target, url, additional_options = {})
41
+ wget_command = default_wget_command(local_target, url, additional_options)
42
+ puts "Executing #{wget_command} . . ."
43
+ %x(#{wget_command})
44
+ end
45
+
46
+ # This will always retrieve from under the 'artifacts' directory
47
+ def foss_only_retrieve(build_url, local_target)
48
+ unless Pkg::Config.foss_platforms
49
+ fail "FOSS_ONLY specified, but I don't know anything about FOSS_PLATFORMS. Retrieve cancelled."
50
+ end
51
+ default_wget(local_target, "#{build_url}/", { 'level' => 1 })
52
+ yaml_path = File.join(local_target, "#{Pkg::Config.ref}.yaml")
53
+ unless File.readable?(yaml_path)
54
+ fail "Couldn't read #{Pkg::Config.ref}.yaml, which is necessary for FOSS_ONLY. Retrieve cancelled."
55
+ end
56
+ platform_data = Pkg::Util::Serialization.load_yaml(yaml_path)[:platform_data]
57
+ platform_data.each do |platform, paths|
58
+ path_to_retrieve = File.dirname(paths[:artifact])
59
+ default_wget(local_target, "#{build_url}/#{path_to_retrieve}/") if Pkg::Config.foss_platforms.include?(platform)
60
+ end
61
+ end
62
+
63
+ def retrieve_all(build_url, rsync_path, local_target)
64
+ if Pkg::Util::Tool.find_tool("wget")
65
+ default_wget(local_target, "#{build_url}/")
66
+ else
67
+ warn "Could not find `wget` tool. Falling back to rsyncing from #{Pkg::Config.distribution_server}."
68
+ begin
69
+ Pkg::Util::Net.rsync_from("#{rsync_path}/", Pkg::Config.distribution_server, "#{local_target}/")
70
+ rescue => e
71
+ fail "Couldn't rsync packages from distribution server.\n#{e}"
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,5 @@
1
+ # RPM methods used by various libraries and rake tasks
2
+
3
+ module Pkg::Rpm
4
+ require 'packaging/rpm/repo'
5
+ end
@@ -0,0 +1,254 @@
1
+ # Utilities for working with rpm repos
2
+ require 'fileutils'
3
+ require 'find'
4
+
5
+ module Pkg::Rpm::Repo
6
+ class << self
7
+ def base_url
8
+ "http://#{Pkg::Config.builds_server}/#{Pkg::Config.project}/#{Pkg::Config.ref}"
9
+ end
10
+
11
+ def ship_repo_configs(target = "repo_configs")
12
+ if Pkg::Util::File.empty_dir?("pkg/#{target}/rpm")
13
+ warn "No repo configs have been generated! Try pl:rpm_repo_configs."
14
+ return
15
+ end
16
+
17
+ Pkg::Util::RakeUtils.invoke_task("pl:fetch")
18
+ repo_dir = "#{Pkg::Config.jenkins_repo_path}/#{Pkg::Config.project}/#{Pkg::Config.ref}/#{target}/rpm"
19
+ Pkg::Util::Net.remote_execute(Pkg::Config.distribution_server, "mkdir -p #{repo_dir}")
20
+ Pkg::Util::Execution.retry_on_fail(:times => 3) do
21
+ Pkg::Util::Net.rsync_to("pkg/#{target}/rpm/", Pkg::Config.distribution_server, repo_dir)
22
+ end
23
+ end
24
+
25
+ def repo_creation_command(repo_directory, artifact_paths = nil)
26
+ cmd = "[ -d #{repo_directory} ] || exit 1 ; "
27
+ cmd << "pushd #{repo_directory} > /dev/null && "
28
+ cmd << 'echo "Checking for running repo creation. Will wait if detected." && '
29
+ cmd << 'while [ -f .lock ] ; do sleep 1 ; echo -n "." ; done && '
30
+ cmd << 'echo "Setting lock" && '
31
+ cmd << 'touch .lock && '
32
+ cmd << 'createrepo=$(which createrepo) ; '
33
+
34
+ # Added for compatibility.
35
+ # The nightly repo ships operate differently and do not want to be calculating
36
+ # the correct paths based on which packages are available on the distribution
37
+ # host, we just want to be `createrepo`ing for what we've staged locally
38
+ #
39
+ # We should only assume repo_directory exists locally if we didn't pass
40
+ # artifact paths
41
+ if artifact_paths.nil?
42
+ # Since the command already has a `pushd #{repo_directory}` let's make sure
43
+ # we're calculating artifact paths relative to that.
44
+ Dir.chdir repo_directory do
45
+ artifact_paths = Dir.glob('**/*.rpm').map { |package| File.dirname(package) }
46
+ end
47
+ end
48
+
49
+ artifact_paths.each do |path|
50
+ next if path.include? 'aix'
51
+ cmd << "if [ -d #{path} ]; then "
52
+ cmd << "pushd #{path} && "
53
+ cmd << '$createrepo --checksum=sha --checkts --update --delta-workers=0 --database . && '
54
+ cmd << 'popd ; '
55
+ cmd << 'fi ;'
56
+ end
57
+ cmd
58
+ end
59
+
60
+ # @deprecated this command will die a painful death when we are
61
+ # able to sit down with Operations and refactor our distribution infra.
62
+ # At a minimum, it should be refactored alongside its Debian counterpart
63
+ # into something modestly more generic.
64
+ # - Ryan McKern 11/2015
65
+ #
66
+ # @param origin_path [String] path for RPM repos on local filesystem
67
+ # @param destination_path [String] path for RPM repos on remote filesystem
68
+ # @param destination [String] remote host to send rsynced content to. If
69
+ # nil will copy locally
70
+ # @param dryrun [Boolean] whether or not to use '--dry-run'
71
+ #
72
+ # @return [String] an rsync command that can be executed on a remote host
73
+ # to copy local content from that host to a remote node.
74
+ def repo_deployment_command(origin_path, destination_path, destination, dryrun = false)
75
+ path = Pathname.new(origin_path)
76
+ dest_path = Pathname.new(destination_path)
77
+
78
+ options = %w(
79
+ rsync
80
+ --recursive
81
+ --links
82
+ --hard-links
83
+ --update
84
+ --human-readable
85
+ --itemize-changes
86
+ --progress
87
+ --verbose
88
+ --super
89
+ --delay-updates
90
+ --omit-dir-times
91
+ --no-perms
92
+ --no-owner
93
+ --no-group
94
+ )
95
+
96
+ options << '--dry-run' if dryrun
97
+ options << path
98
+
99
+ if destination
100
+ options << "#{destination}:#{dest_path.parent}"
101
+ else
102
+ options << "#{dest_path.parent}"
103
+ end
104
+
105
+ options.join("\s")
106
+ end
107
+
108
+ def sign_repos(directory)
109
+ files_to_sign = Find.find(directory).select { |file| file.match(/repomd.xml$/) }
110
+ files_to_sign.each do |file|
111
+ Pkg::Util::Gpg.sign_file(file)
112
+ end
113
+ end
114
+
115
+ def retrieve_repo_configs(target = "repo_configs")
116
+ wget = Pkg::Util::Tool.check_tool("wget")
117
+ FileUtils.mkdir_p("pkg/#{target}")
118
+ config_url = "#{base_url}/#{target}/rpm/"
119
+ begin
120
+ stdout, _, _ = Pkg::Util::Execution.capture3("#{wget} -r -np -nH --cut-dirs 3 -P pkg/#{target} --reject 'index*' #{config_url}")
121
+ stdout
122
+ rescue => e
123
+ fail "Couldn't retrieve rpm yum repo configs.\n#{e}"
124
+ end
125
+ end
126
+
127
+ # Generate yum configuration files that point to the repositories created
128
+ # on the distribution server with packages created from the current source
129
+ # repo commit. There is one for each dist/version that is packaged (e.g.
130
+ # el5, el6, etc). Files are created in pkg/repo_configs/rpm and are named
131
+ # pl-$project-$sha.conf, and can be placed in /etc/yum.repos.d to enable
132
+ # clients to install these packages.
133
+ #
134
+ def generate_repo_configs(source = "repos", target = "repo_configs", signed = false)
135
+ # We have a hard requirement on wget because of all the download magicks
136
+ # we have to do
137
+ #
138
+ wget = Pkg::Util::Tool.check_tool("wget")
139
+
140
+ # This is the standard path to all build artifacts on the distribution
141
+ # server for this commit
142
+ #
143
+ repo_base = "#{base_url}/#{source}/"
144
+
145
+ # First check if the artifacts directory exists
146
+ #
147
+
148
+ # We have to do two checks here - first that there are directories with
149
+ # repodata folders in them, and second that those same directories also
150
+ # contain rpms
151
+ #
152
+ stdout, _, _ = Pkg::Util::Execution.capture3("#{wget} --spider -r -l 5 --no-parent #{repo_base} 2>&1")
153
+ stdout = stdout.split.uniq.reject { |x| x =~ /\?|index/ }.select { |x| x =~ /http:.*repodata\/$/ }
154
+
155
+ # RPMs will always exist at the same directory level as the repodata
156
+ # folder, which means if we go up a level we should find rpms
157
+ #
158
+ yum_repos = []
159
+ stdout.map { |x| x.chomp('repodata/') }.each do |url|
160
+ output, _, _ = Pkg::Util::Execution.capture3("#{wget} --spider -r -l 1 --no-parent #{url} 2>&1")
161
+ unless output.split.uniq.reject { |x| x =~ /\?|index/ }.select { |x| x =~ /http:.*\.rpm$/ }.empty?
162
+ yum_repos << url
163
+ end
164
+ end
165
+
166
+ if yum_repos.empty?
167
+ warn "No rpm repos were found to generate configs from!"
168
+ return
169
+ end
170
+
171
+ FileUtils.mkdir_p(File.join("pkg", target, "rpm"))
172
+
173
+ # Parse the rpm configs file to generate repository configs. Each line in
174
+ # the rpm_configs file corresponds with a repo directory on the
175
+ # distribution server.
176
+ #
177
+ yum_repos.each do |url|
178
+ # We ship a base 'srpm' that gets turned into a repo, but we want to
179
+ # ignore this one because its an extra
180
+ next if url == "#{repo_base}srpm/"
181
+
182
+ platform_tag = Pkg::Paths.tag_from_artifact_path(url)
183
+ platform, version, arch = Pkg::Platforms.parse_platform_tag(platform_tag)
184
+
185
+ # Create an array of lines that will become our yum config
186
+ #
187
+ config = ["[pl-#{Pkg::Config.project}-#{Pkg::Config.ref}]"]
188
+ config << ["name=PL Repo for #{Pkg::Config.project} at commit #{Pkg::Config.ref}"]
189
+ config << ["baseurl=#{url}"]
190
+ config << ["enabled=1"]
191
+ if signed
192
+ config << ["gpgcheck=1"]
193
+ config << ["gpgkey=http://#{Pkg::Config.builds_server}/#{Pkg::Util::Gpg.key}"]
194
+ else
195
+ config << ["gpgcheck=0"]
196
+ end
197
+
198
+ # Write the new config to a file under our repo configs dir
199
+ #
200
+ config_file = File.join("pkg", target, "rpm", "pl-#{Pkg::Config.project}-#{Pkg::Config.ref}-#{platform}-#{version}-#{arch}.repo")
201
+ File.open(config_file, 'w') { |f| f.puts config }
202
+ end
203
+ puts "Wrote yum configuration files for #{Pkg::Config.project} at #{Pkg::Config.ref} to pkg/#{target}/rpm"
204
+ end
205
+
206
+ def create_local_repos(directory = "repos")
207
+ stdout, _, _ = Pkg::Util::Execution.capture3("bash -c '#{repo_creation_command(directory)}'")
208
+ stdout
209
+ end
210
+
211
+ def create_remote_repos(directory = 'repos')
212
+ artifact_directory = File.join(Pkg::Config.jenkins_repo_path, Pkg::Config.project, Pkg::Config.ref)
213
+ artifact_paths = Pkg::Repo.directories_that_contain_packages(File.join(artifact_directory, 'artifacts'), 'rpm')
214
+ Pkg::Repo.populate_repo_directory(artifact_directory)
215
+ command = Pkg::Rpm::Repo.repo_creation_command(File.join(artifact_directory, directory), artifact_paths)
216
+
217
+ begin
218
+ Pkg::Util::Net.remote_execute(Pkg::Config.distribution_server, command)
219
+ # Now that we've created our package repositories, we can generate repo
220
+ # configurations for use with downstream jobs, acceptance clients, etc.
221
+ Pkg::Rpm::Repo.generate_repo_configs
222
+
223
+ # Now that we've created the repo configs, we can ship them
224
+ Pkg::Rpm::Repo.ship_repo_configs
225
+ ensure
226
+ # Always remove the lock file, even if we've failed
227
+ Pkg::Util::Net.remote_execute(Pkg::Config.distribution_server, "rm -f #{artifact_directory}/repos/.lock")
228
+ end
229
+ end
230
+
231
+ def create_repos_from_artifacts(directory = "repos")
232
+ Pkg::Util.deprecate('Pkg::Rpm::Repo.create_repos_from_artifacts', 'Pkg::Rpm::Repo.create_remote_repos')
233
+ create_remote_repos(directory)
234
+ end
235
+
236
+ def create_repos(directory = "repos")
237
+ Pkg::Util.deprecate('Pkg::Rpm::Repo.create_repos', 'Pkg::Rpm::Repo.create_local_repos')
238
+ create_local_repos(directory)
239
+ end
240
+
241
+ # @deprecated this command is exactly as awful as you think it is.
242
+ # -- Ryan McKern 12/2015
243
+ #
244
+ # @param yum_path [String] path for rpm repos on local and remote filesystem
245
+ # @param origin_server [String] remote host to start the rsync from
246
+ # @param destination_server [String] remote host to send rsynced content to
247
+ # @param dryrun [Boolean] whether or not to use '--dry-run'
248
+ def deploy_repos(yum_path, origin_server, destination_server, dryrun = false)
249
+ rsync_command = repo_deployment_command(yum_path, yum_path, destination_server, dryrun)
250
+
251
+ Pkg::Util::Net.remote_execute(origin_server, rsync_command)
252
+ end
253
+ end
254
+ end