packaging 0.88.77
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE +17 -0
- data/README-Solaris.md +117 -0
- data/README.md +977 -0
- data/lib/packaging.rb +32 -0
- data/lib/packaging/archive.rb +126 -0
- data/lib/packaging/artifactory.rb +651 -0
- data/lib/packaging/artifactory/extensions.rb +94 -0
- data/lib/packaging/config.rb +492 -0
- data/lib/packaging/config/params.rb +387 -0
- data/lib/packaging/config/validations.rb +13 -0
- data/lib/packaging/deb.rb +28 -0
- data/lib/packaging/deb/repo.rb +264 -0
- data/lib/packaging/gem.rb +70 -0
- data/lib/packaging/metrics.rb +15 -0
- data/lib/packaging/nuget.rb +39 -0
- data/lib/packaging/paths.rb +376 -0
- data/lib/packaging/platforms.rb +507 -0
- data/lib/packaging/repo.rb +155 -0
- data/lib/packaging/retrieve.rb +75 -0
- data/lib/packaging/rpm.rb +5 -0
- data/lib/packaging/rpm/repo.rb +254 -0
- data/lib/packaging/sign.rb +8 -0
- data/lib/packaging/sign/deb.rb +9 -0
- data/lib/packaging/sign/dmg.rb +41 -0
- data/lib/packaging/sign/ips.rb +57 -0
- data/lib/packaging/sign/msi.rb +124 -0
- data/lib/packaging/sign/rpm.rb +115 -0
- data/lib/packaging/tar.rb +163 -0
- data/lib/packaging/util.rb +146 -0
- data/lib/packaging/util/date.rb +20 -0
- data/lib/packaging/util/execution.rb +85 -0
- data/lib/packaging/util/file.rb +125 -0
- data/lib/packaging/util/git.rb +174 -0
- data/lib/packaging/util/git_tags.rb +73 -0
- data/lib/packaging/util/gpg.rb +66 -0
- data/lib/packaging/util/jenkins.rb +95 -0
- data/lib/packaging/util/misc.rb +69 -0
- data/lib/packaging/util/net.rb +410 -0
- data/lib/packaging/util/os.rb +17 -0
- data/lib/packaging/util/platform.rb +40 -0
- data/lib/packaging/util/rake_utils.rb +112 -0
- data/lib/packaging/util/serialization.rb +19 -0
- data/lib/packaging/util/ship.rb +300 -0
- data/lib/packaging/util/tool.rb +41 -0
- data/lib/packaging/util/version.rb +334 -0
- data/spec/fixtures/config/ext/build_defaults.yaml +2 -0
- data/spec/fixtures/config/ext/project_data.yaml +2 -0
- data/spec/fixtures/configs/components/test_file.json +1 -0
- data/spec/fixtures/configs/components/test_file_2.json +0 -0
- data/spec/fixtures/configs/components/test_file_not_tagged.json +1 -0
- data/spec/fixtures/configs/components/test_file_wrong_ext.txt +0 -0
- data/spec/fixtures/configs/components/test_file_wrong_ext.wrong +0 -0
- data/spec/fixtures/util/pre_tasks.yaml +4 -0
- data/spec/lib/packaging/artifactory_spec.rb +221 -0
- data/spec/lib/packaging/config_spec.rb +576 -0
- data/spec/lib/packaging/deb/repo_spec.rb +157 -0
- data/spec/lib/packaging/deb_spec.rb +52 -0
- data/spec/lib/packaging/gem_spec.rb +86 -0
- data/spec/lib/packaging/paths_spec.rb +418 -0
- data/spec/lib/packaging/platforms_spec.rb +178 -0
- data/spec/lib/packaging/repo_spec.rb +135 -0
- data/spec/lib/packaging/retrieve_spec.rb +100 -0
- data/spec/lib/packaging/rpm/repo_spec.rb +133 -0
- data/spec/lib/packaging/sign_spec.rb +133 -0
- data/spec/lib/packaging/tar_spec.rb +116 -0
- data/spec/lib/packaging/util/execution_spec.rb +56 -0
- data/spec/lib/packaging/util/file_spec.rb +139 -0
- data/spec/lib/packaging/util/git_spec.rb +160 -0
- data/spec/lib/packaging/util/git_tag_spec.rb +36 -0
- data/spec/lib/packaging/util/gpg_spec.rb +64 -0
- data/spec/lib/packaging/util/jenkins_spec.rb +112 -0
- data/spec/lib/packaging/util/misc_spec.rb +31 -0
- data/spec/lib/packaging/util/net_spec.rb +259 -0
- data/spec/lib/packaging/util/os_spec.rb +31 -0
- data/spec/lib/packaging/util/rake_utils_spec.rb +70 -0
- data/spec/lib/packaging/util/ship_spec.rb +199 -0
- data/spec/lib/packaging/util/version_spec.rb +123 -0
- data/spec/lib/packaging_spec.rb +19 -0
- data/spec/spec_helper.rb +22 -0
- data/static_artifacts/PackageInfo.plist +3 -0
- data/tasks/00_utils.rake +214 -0
- data/tasks/30_metrics.rake +33 -0
- data/tasks/apple.rake +268 -0
- data/tasks/archive.rake +69 -0
- data/tasks/build.rake +12 -0
- data/tasks/clean.rake +5 -0
- data/tasks/config.rake +35 -0
- data/tasks/deb.rake +129 -0
- data/tasks/deb_repos.rake +28 -0
- data/tasks/deprecated.rake +130 -0
- data/tasks/doc.rake +20 -0
- data/tasks/education.rake +57 -0
- data/tasks/fetch.rake +60 -0
- data/tasks/gem.rake +159 -0
- data/tasks/jenkins.rake +538 -0
- data/tasks/jenkins_dynamic.rake +202 -0
- data/tasks/load_extras.rake +21 -0
- data/tasks/mock.rake +348 -0
- data/tasks/nightly_repos.rake +286 -0
- data/tasks/pe_deb.rake +12 -0
- data/tasks/pe_rpm.rake +13 -0
- data/tasks/pe_ship.rake +226 -0
- data/tasks/pe_sign.rake +13 -0
- data/tasks/pe_tar.rake +5 -0
- data/tasks/retrieve.rake +52 -0
- data/tasks/rpm.rake +66 -0
- data/tasks/rpm_repos.rake +29 -0
- data/tasks/ship.rake +692 -0
- data/tasks/sign.rake +154 -0
- data/tasks/tag.rake +8 -0
- data/tasks/tar.rake +28 -0
- data/tasks/update.rake +16 -0
- data/tasks/vanagon.rake +35 -0
- data/tasks/vendor_gems.rake +117 -0
- data/tasks/version.rake +33 -0
- data/tasks/z_data_dump.rake +65 -0
- data/templates/README +1 -0
- data/templates/downstream.xml.erb +47 -0
- data/templates/msi.xml.erb +197 -0
- data/templates/packaging.xml.erb +346 -0
- data/templates/repo.xml.erb +117 -0
- 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,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
|