packaging 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.
- checksums.yaml +7 -0
- data/LICENSE +17 -0
- data/README-Solaris.md +117 -0
- data/README.md +1031 -0
- data/lib/packaging.rb +32 -0
- data/lib/packaging/artifactory.rb +278 -0
- data/lib/packaging/config.rb +392 -0
- data/lib/packaging/config/params.rb +366 -0
- data/lib/packaging/deb.rb +28 -0
- data/lib/packaging/deb/repo.rb +263 -0
- data/lib/packaging/gem.rb +112 -0
- data/lib/packaging/ips.rb +57 -0
- data/lib/packaging/msi.rb +89 -0
- data/lib/packaging/nuget.rb +39 -0
- data/lib/packaging/osx.rb +36 -0
- data/lib/packaging/paths.rb +238 -0
- data/lib/packaging/platforms.rb +480 -0
- data/lib/packaging/repo.rb +55 -0
- data/lib/packaging/retrieve.rb +46 -0
- data/lib/packaging/rpm.rb +5 -0
- data/lib/packaging/rpm/repo.rb +257 -0
- data/lib/packaging/tar.rb +154 -0
- data/lib/packaging/util.rb +146 -0
- data/lib/packaging/util/date.rb +15 -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 +62 -0
- data/lib/packaging/util/jenkins.rb +95 -0
- data/lib/packaging/util/misc.rb +69 -0
- data/lib/packaging/util/net.rb +368 -0
- data/lib/packaging/util/os.rb +17 -0
- data/lib/packaging/util/platform.rb +40 -0
- data/lib/packaging/util/rake_utils.rb +111 -0
- data/lib/packaging/util/serialization.rb +19 -0
- data/lib/packaging/util/ship.rb +171 -0
- data/lib/packaging/util/tool.rb +41 -0
- data/lib/packaging/util/version.rb +326 -0
- data/spec/fixtures/config/ext/build_defaults.yaml +2 -0
- data/spec/fixtures/config/ext/project_data.yaml +2 -0
- data/spec/fixtures/config/params.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 +171 -0
- data/spec/lib/packaging/config_spec.rb +556 -0
- data/spec/lib/packaging/deb/repo_spec.rb +148 -0
- data/spec/lib/packaging/deb_spec.rb +52 -0
- data/spec/lib/packaging/paths_spec.rb +153 -0
- data/spec/lib/packaging/platforms_spec.rb +153 -0
- data/spec/lib/packaging/repo_spec.rb +97 -0
- data/spec/lib/packaging/retrieve_spec.rb +61 -0
- data/spec/lib/packaging/rpm/repo_spec.rb +133 -0
- data/spec/lib/packaging/tar_spec.rb +122 -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 +239 -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 +117 -0
- data/spec/lib/packaging/util/version_spec.rb +123 -0
- data/spec/lib/packaging_spec.rb +19 -0
- data/spec/spec_helper.rb +36 -0
- data/static_artifacts/PackageInfo.plist +3 -0
- data/tasks/00_utils.rake +216 -0
- data/tasks/30_metrics.rake +33 -0
- data/tasks/apple.rake +266 -0
- data/tasks/build.rake +12 -0
- data/tasks/clean.rake +5 -0
- data/tasks/config.rake +30 -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 +57 -0
- data/tasks/gem.rake +146 -0
- data/tasks/jenkins.rake +494 -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 +335 -0
- data/tasks/pe_deb.rake +12 -0
- data/tasks/pe_rpm.rake +13 -0
- data/tasks/pe_ship.rake +221 -0
- data/tasks/pe_sign.rake +13 -0
- data/tasks/pe_tar.rake +5 -0
- data/tasks/retrieve.rake +45 -0
- data/tasks/rpm.rake +66 -0
- data/tasks/rpm_repos.rake +29 -0
- data/tasks/ship.rake +752 -0
- data/tasks/sign.rake +226 -0
- data/tasks/tag.rake +8 -0
- data/tasks/tar.rake +34 -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 +344 -0
- data/templates/repo.xml.erb +114 -0
- metadata +234 -0
@@ -0,0 +1,112 @@
|
|
1
|
+
module Pkg::Gem
|
2
|
+
@nexus_config = "#{ENV['HOME']}/.gem/nexus"
|
3
|
+
|
4
|
+
class << self
|
5
|
+
# This is preserved because I don't want to update the deprecated code path
|
6
|
+
# yet; I'm not entirely sure I've fixed everything that might attempt
|
7
|
+
# to call this method so this is now a wrapper for a wrapper.
|
8
|
+
def ship(file)
|
9
|
+
ship_to_stickler(file)
|
10
|
+
ship_to_nexus(file)
|
11
|
+
rsync_to_downloads(file)
|
12
|
+
ship_to_rubygems(file)
|
13
|
+
end
|
14
|
+
|
15
|
+
def load_nexus_config
|
16
|
+
if Pkg::Util::File.file_exists?(@nexus_config)
|
17
|
+
config = YAML.load_file(@nexus_config)
|
18
|
+
end
|
19
|
+
config || {}
|
20
|
+
end
|
21
|
+
|
22
|
+
def write_nexus_config
|
23
|
+
hash = load_nexus_config
|
24
|
+
if hash["GEM_INTERNAL"].nil? || hash["GEM_INTERNAL"][:authorization].nil?
|
25
|
+
puts "Please enter nexus username:"
|
26
|
+
username = Pkg::Util.get_input
|
27
|
+
puts "Please enter nexus password:"
|
28
|
+
password = Pkg::Util.get_input(false)
|
29
|
+
hash["GEM_INTERNAL"] = { :authorization => "Basic #{Pkg::Util.base64_encode("#{username}:#{password}")}" }
|
30
|
+
end
|
31
|
+
if hash["GEM_INTERNAL"][:url].nil? || hash["GEM_INTERNAL"][:url] != Pkg::Config.internal_nexus_host
|
32
|
+
hash["GEM_INTERNAL"][:url] = Pkg::Config.internal_nexus_host
|
33
|
+
end
|
34
|
+
File.open(@nexus_config, "w") do |file|
|
35
|
+
file.write(hash.to_yaml)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# Ship a Ruby gem file to a Nexus server, because
|
40
|
+
# you've lost the ability to feel joy anymore.
|
41
|
+
def ship_to_nexus(file)
|
42
|
+
write_nexus_config
|
43
|
+
cmd = "gem nexus #{file} --repo GEM_INTERNAL"
|
44
|
+
if ENV['DRYRUN']
|
45
|
+
puts "[DRY-RUN] #{cmd}"
|
46
|
+
else
|
47
|
+
stdout, _, _ = Pkg::Util::Execution.capture3(cmd, true)
|
48
|
+
# The `gem nexus` command always returns `0` regardless of what the
|
49
|
+
# command results in. In order to properly handle fail cases, this
|
50
|
+
# checks for the success case and fails otherwise. The `ex` command
|
51
|
+
# above will print any output, so the user should have enough info
|
52
|
+
# to debug the failure, and potentially update this fail case if
|
53
|
+
# needed.
|
54
|
+
fail unless stdout.include? "Created"
|
55
|
+
puts "#{file} pushed to nexus server at #{Pkg::Config.internal_nexus_host}"
|
56
|
+
end
|
57
|
+
rescue => e
|
58
|
+
puts "###########################################"
|
59
|
+
puts "# Nexus failed, ensure the nexus gem is installed,"
|
60
|
+
puts "# you have access to #{Pkg::Config.internal_nexus_host}"
|
61
|
+
puts "# and your settings in #{@nexus_config} are correct"
|
62
|
+
puts "###########################################"
|
63
|
+
puts
|
64
|
+
puts e
|
65
|
+
raise e
|
66
|
+
end
|
67
|
+
|
68
|
+
# Ship a Ruby gem file to a Stickler server, because
|
69
|
+
# you've lost the ability to feel joy anymore.
|
70
|
+
def ship_to_stickler(file)
|
71
|
+
Pkg::Util::Tool.check_tool("stickler")
|
72
|
+
cmd = "stickler push #{file} --server=#{Pkg::Config.internal_stickler_host} 2>/dev/null"
|
73
|
+
if ENV['DRYRUN']
|
74
|
+
puts "[DRY-RUN] #{cmd}"
|
75
|
+
else
|
76
|
+
Pkg::Util::Execution.capture3(cmd)
|
77
|
+
puts "#{file} pushed to stickler server at #{Pkg::Config.internal_stickler_host}"
|
78
|
+
end
|
79
|
+
rescue => e
|
80
|
+
puts "###########################################"
|
81
|
+
puts "# Stickler failed, ensure it's installed"
|
82
|
+
puts "# and you have access to #{Pkg::Config.internal_stickler_host}"
|
83
|
+
puts "###########################################"
|
84
|
+
puts
|
85
|
+
puts e
|
86
|
+
raise e
|
87
|
+
end
|
88
|
+
|
89
|
+
# Use rsync to deploy a file and any associated detached signatures,
|
90
|
+
# checksums, or other glob-able artifacts to an external download server.
|
91
|
+
def rsync_to_downloads(file)
|
92
|
+
Pkg::Util.deprecate('Pkg::Gem.rsync_to_downloads', 'Pkg::Util::Ship.ship_pkgs')
|
93
|
+
Pkg::Util::Ship.ship_pkgs(["#{file}*"], Pkg::Config.gem_host, Pkg::Config.gem_path, platform_independent: true)
|
94
|
+
end
|
95
|
+
|
96
|
+
# Ship a Ruby gem file to rubygems.org. Requires the existence
|
97
|
+
# of a ~/.gem/credentials file or else rubygems.org won't have
|
98
|
+
# any idea who you are.
|
99
|
+
def ship_to_rubygems(file)
|
100
|
+
Pkg::Util::File.file_exists?("#{ENV['HOME']}/.gem/credentials", :required => true)
|
101
|
+
Pkg::Util::Execution.capture3("gem push #{file}")
|
102
|
+
rescue => e
|
103
|
+
puts "###########################################"
|
104
|
+
puts "# Publishing to rubygems failed. Make sure your .gem/credentials"
|
105
|
+
puts "# file is set up and you are an owner of #{Pkg::Config.gem_name}"
|
106
|
+
puts "###########################################"
|
107
|
+
puts
|
108
|
+
puts e
|
109
|
+
raise e
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module Pkg::IPS
|
2
|
+
class << self
|
3
|
+
def sign(target_dir = 'pkg')
|
4
|
+
use_identity = "-i #{Pkg::Config.ips_signing_ssh_key}" unless Pkg::Config.ips_signing_ssh_key.nil?
|
5
|
+
|
6
|
+
ssh_host_string = "#{use_identity} #{ENV['USER']}@#{Pkg::Config.ips_signing_server}"
|
7
|
+
rsync_host_string = "-e 'ssh #{use_identity}' #{ENV['USER']}@#{Pkg::Config.ips_signing_server}"
|
8
|
+
|
9
|
+
p5ps = Dir.glob("#{target_dir}/solaris/11/**/*.p5p")
|
10
|
+
|
11
|
+
p5ps.each do |p5p|
|
12
|
+
work_dir = "/tmp/#{Pkg::Util.rand_string}"
|
13
|
+
unsigned_dir = "#{work_dir}/unsigned"
|
14
|
+
repo_dir = "#{work_dir}/repo"
|
15
|
+
signed_dir = "#{work_dir}/pkgs"
|
16
|
+
|
17
|
+
Pkg::Util::Net.remote_ssh_cmd(ssh_host_string, "mkdir -p #{repo_dir} #{unsigned_dir} #{signed_dir}")
|
18
|
+
Pkg::Util::Net.rsync_to(p5p, rsync_host_string, unsigned_dir)
|
19
|
+
|
20
|
+
# Before we can get started with signing packages we need to create a repo
|
21
|
+
Pkg::Util::Net.remote_ssh_cmd(ssh_host_string, "sudo -E /usr/bin/pkgrepo create #{repo_dir}")
|
22
|
+
Pkg::Util::Net.remote_ssh_cmd(ssh_host_string, "sudo -E /usr/bin/pkgrepo set -s #{repo_dir} publisher/prefix=puppetlabs.com")
|
23
|
+
# And import all the packages into the repo.
|
24
|
+
Pkg::Util::Net.remote_ssh_cmd(ssh_host_string, "sudo -E /usr/bin/pkgrecv -s #{unsigned_dir}/#{File.basename(p5p)} -d #{repo_dir} '*'")
|
25
|
+
# We are going to hard code the values for signing cert locations for now.
|
26
|
+
# This autmation will require an update to actually become reusable, but
|
27
|
+
# for now these values will stay this way so solaris signing will stop
|
28
|
+
# failing. Please update soon. 06/23/16
|
29
|
+
#
|
30
|
+
# - Sean P. McDonald
|
31
|
+
#
|
32
|
+
# We sign the entire repo
|
33
|
+
sign_cmd = "sudo -E /usr/bin/pkgsign -c /root/signing/signing_cert_interim_SHA1.pem \
|
34
|
+
-i /root/signing/Thawte_Code_Signing_Certificate_interim_SHA1.pem \
|
35
|
+
-i /root/signing/Thawte_Primary_Root_CA_interim_SHA1.pem \
|
36
|
+
-k /root/signing/signing_key_interim_SHA1.pem \
|
37
|
+
-s 'file://#{work_dir}/repo' '*'"
|
38
|
+
puts "About to sign #{p5p} with #{sign_cmd} in #{work_dir}"
|
39
|
+
Pkg::Util::Net.remote_ssh_cmd(ssh_host_string, sign_cmd.squeeze(' '))
|
40
|
+
# pkgrecv with -a will pull packages out of the repo, so we need to do that too to actually get the packages we signed
|
41
|
+
Pkg::Util::Net.remote_ssh_cmd(ssh_host_string, "sudo -E /usr/bin/pkgrecv -d #{signed_dir}/#{File.basename(p5p)} -a -s #{repo_dir} '*'")
|
42
|
+
begin
|
43
|
+
# lets make sure we actually signed something?
|
44
|
+
# **NOTE** if we're repeatedly trying to sign the same version this
|
45
|
+
# might explode because I don't know how to reset the IPS cache.
|
46
|
+
# Everything is amazing.
|
47
|
+
Pkg::Util::Net.remote_ssh_cmd(ssh_host_string, "sudo -E /usr/bin/pkg contents -m -g #{signed_dir}/#{File.basename(p5p)} '*' | grep '^signature '")
|
48
|
+
rescue RuntimeError
|
49
|
+
raise "Looks like #{File.basename(p5p)} was not signed correctly, quitting!"
|
50
|
+
end
|
51
|
+
# and pull the packages back.
|
52
|
+
Pkg::Util::Net.rsync_from("#{signed_dir}/#{File.basename(p5p)}", rsync_host_string, File.dirname(p5p))
|
53
|
+
Pkg::Util::Net.remote_ssh_cmd(ssh_host_string, "if [ -e '#{work_dir}' ] ; then sudo rm -r '#{work_dir}' ; fi")
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
module Pkg::MSI
|
2
|
+
class << self
|
3
|
+
def sign(target_dir = 'pkg')
|
4
|
+
use_identity = "-i #{Pkg::Config.msi_signing_ssh_key}" if Pkg::Config.msi_signing_ssh_key
|
5
|
+
|
6
|
+
ssh_host_string = "#{use_identity} Administrator@#{Pkg::Config.msi_signing_server}"
|
7
|
+
rsync_host_string = "-e 'ssh #{use_identity}' Administrator@#{Pkg::Config.msi_signing_server}"
|
8
|
+
|
9
|
+
work_dir = "Windows/Temp/#{Pkg::Util.rand_string}"
|
10
|
+
Pkg::Util::Net.remote_ssh_cmd(ssh_host_string, "mkdir -p C:/#{work_dir}")
|
11
|
+
msis = Dir.glob("#{target_dir}/windows/**/*.msi")
|
12
|
+
Pkg::Util::Net.rsync_to(msis.join(" "), rsync_host_string, "/cygdrive/c/#{work_dir}")
|
13
|
+
|
14
|
+
# Please Note:
|
15
|
+
# We are currently adding two signatures to the msi.
|
16
|
+
#
|
17
|
+
# Microsoft compatable Signatures are composed of three different
|
18
|
+
# elements.
|
19
|
+
# 1) The Certificate used to sign the package. This is the element that
|
20
|
+
# is attached to organization. The certificate has an associated
|
21
|
+
# algorithm. We recently (February 2016) had to switch from a sha1 to
|
22
|
+
# a sha256 certificate. Sha1 was deprecated by many Microsoft
|
23
|
+
# elements on 2016-01-01, which forced us to switch to a sha256 cert.
|
24
|
+
# This sha256 certificate is recognized by all currently supported
|
25
|
+
# windows platforms (Windows 8/Vista forward).
|
26
|
+
# 2) The signature used to attach the certificate to the package. This
|
27
|
+
# can be a done with a variety of digest algorithms. Older platforms
|
28
|
+
# (i.e., Windows 8 and Windows Vista) don't recognize later
|
29
|
+
# algorithms like sha256.
|
30
|
+
# 3) The timestamp used to validate when the package was signed. This
|
31
|
+
# comes from an external source and can be delivered with a variety
|
32
|
+
# of digest algorithms. Older platforms do not recognize newer
|
33
|
+
# algorithms like sha256.
|
34
|
+
#
|
35
|
+
# We could have only one signature with the Sha256 Cert, Sha1 Signature,
|
36
|
+
# and Sha1 Timestamp, but that would be too easy. The sha256 signature
|
37
|
+
# and timestamp add more security to our packages. We can't have only
|
38
|
+
# sha256 elements in our package signature, though, because Windows 8
|
39
|
+
# and Windows Vista just don't recognize them at all.
|
40
|
+
#
|
41
|
+
# In order to add two signatures to an MSI, we also need to change the
|
42
|
+
# tool we use to sign packages with. Previously, we were using SignTool
|
43
|
+
# which is the Microsoft blessed program used to sign packages. However,
|
44
|
+
# this tool isn't able to add two signatures to an MSI specifically. It
|
45
|
+
# can dual-sign an exe, just not an MSI. In order to get the dual-signed
|
46
|
+
# packages, we decided to switch over to using osslsigncode. The original
|
47
|
+
# project didn't have support to compile on a windows system, so we
|
48
|
+
# decided to use this fork. The binaries on the signer were pulled from
|
49
|
+
# https://sourceforge.net/u/keeely/osslsigncode/ci/master/tree/
|
50
|
+
#
|
51
|
+
# These are our signatures:
|
52
|
+
# The first signature:
|
53
|
+
# * Sha256 Certificate
|
54
|
+
# * Sha1 Signature
|
55
|
+
# * Sha1 Timestamp
|
56
|
+
#
|
57
|
+
# The second signature:
|
58
|
+
# * Sha256 Certificate
|
59
|
+
# * Sha256 Signature
|
60
|
+
# * Sha256 Timestamp
|
61
|
+
#
|
62
|
+
# Once we no longer support Windows 8/Windows Vista, we can remove the
|
63
|
+
# first Sha1 signature.
|
64
|
+
Pkg::Util::Net.remote_ssh_cmd(ssh_host_string, %Q(for msi in #{msis.map { |d| File.basename(d) }.join(" ")}; do
|
65
|
+
"/cygdrive/c/tools/osslsigncode-fork/osslsigncode.exe" sign \
|
66
|
+
-n "Puppet" -i "http://www.puppet.com" \
|
67
|
+
-h sha1 \
|
68
|
+
-pkcs12 "#{Pkg::Config.msi_signing_cert}" \
|
69
|
+
-pass "#{Pkg::Config.msi_signing_cert_pw}" \
|
70
|
+
-t "http://timestamp.verisign.com/scripts/timstamp.dll" \
|
71
|
+
-in "C:/#{work_dir}/$msi" \
|
72
|
+
-out "C:/#{work_dir}/signed-$msi"
|
73
|
+
"/cygdrive/c/tools/osslsigncode-fork/osslsigncode.exe" sign \
|
74
|
+
-n "Puppet" -i "http://www.puppet.com" \
|
75
|
+
-nest -h sha256 \
|
76
|
+
-pkcs12 "#{Pkg::Config.msi_signing_cert}" \
|
77
|
+
-pass "#{Pkg::Config.msi_signing_cert_pw}" \
|
78
|
+
-ts "http://sha256timestamp.ws.symantec.com/sha256/timestamp" \
|
79
|
+
-in "C:/#{work_dir}/signed-$msi" \
|
80
|
+
-out "C:/#{work_dir}/$msi"
|
81
|
+
rm "C:/#{work_dir}/signed-$msi"
|
82
|
+
done))
|
83
|
+
msis.each do | msi |
|
84
|
+
Pkg::Util::Net.rsync_from("/cygdrive/c/#{work_dir}/#{File.basename(msi)}", rsync_host_string, File.dirname(msi))
|
85
|
+
end
|
86
|
+
Pkg::Util::Net.remote_ssh_cmd(ssh_host_string, "if [ -d '/cygdrive/c/#{work_dir}' ]; then rm -rf '/cygdrive/c/#{work_dir}'; fi")
|
87
|
+
end
|
88
|
+
end
|
89
|
+
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 a nexus 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,36 @@
|
|
1
|
+
module Pkg::OSX
|
2
|
+
class << self
|
3
|
+
def sign(target_dir = 'pkg')
|
4
|
+
use_identity = "-i #{Pkg::Config.osx_signing_ssh_key}" unless Pkg::Config.osx_signing_ssh_key.nil?
|
5
|
+
|
6
|
+
if Pkg::Config.osx_signing_server =~ /@/
|
7
|
+
host_string = "#{Pkg::Config.osx_signing_server}"
|
8
|
+
else
|
9
|
+
host_string = "#{ENV['USER']}@#{Pkg::Config.osx_signing_server}"
|
10
|
+
end
|
11
|
+
ssh_host_string = "#{use_identity} #{host_string}"
|
12
|
+
rsync_host_string = "-e 'ssh #{use_identity}' #{host_string}"
|
13
|
+
|
14
|
+
work_dir = "/tmp/#{Pkg::Util.rand_string}"
|
15
|
+
mount = File.join(work_dir, "mount")
|
16
|
+
signed = File.join(work_dir, "signed")
|
17
|
+
Pkg::Util::Net.remote_ssh_cmd(ssh_host_string, "mkdir -p #{mount} #{signed}")
|
18
|
+
dmgs = Dir.glob("#{target_dir}/apple/**/*.dmg")
|
19
|
+
Pkg::Util::Net.rsync_to(dmgs.join(" "), rsync_host_string, work_dir)
|
20
|
+
Pkg::Util::Net.remote_ssh_cmd(ssh_host_string, %Q[for dmg in #{dmgs.map { |d| File.basename(d, ".dmg") }.join(" ")}; do
|
21
|
+
/usr/bin/hdiutil attach #{work_dir}/$dmg.dmg -mountpoint #{mount} -nobrowse -quiet ;
|
22
|
+
/usr/bin/security -q unlock-keychain -p "#{Pkg::Config.osx_signing_keychain_pw}" "#{Pkg::Config.osx_signing_keychain}" ;
|
23
|
+
for pkg in $(ls #{mount}/*.pkg | xargs -n 1 basename); do
|
24
|
+
/usr/bin/productsign --keychain "#{Pkg::Config.osx_signing_keychain}" --sign "#{Pkg::Config.osx_signing_cert}" #{mount}/$pkg #{signed}/$pkg ;
|
25
|
+
done
|
26
|
+
/usr/bin/hdiutil detach #{mount} -quiet ;
|
27
|
+
/bin/rm #{work_dir}/$dmg.dmg ;
|
28
|
+
/usr/bin/hdiutil create -volname $dmg -srcfolder #{signed}/ #{work_dir}/$dmg.dmg ;
|
29
|
+
/bin/rm #{signed}/* ; done])
|
30
|
+
dmgs.each do | dmg |
|
31
|
+
Pkg::Util::Net.rsync_from("#{work_dir}/#{File.basename(dmg)}", rsync_host_string, File.dirname(dmg))
|
32
|
+
end
|
33
|
+
Pkg::Util::Net.remote_ssh_cmd(ssh_host_string, "if [ -d '#{work_dir}' ]; then rm -rf '#{work_dir}'; fi")
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,238 @@
|
|
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?(a) } || arches[0]
|
20
|
+
rescue
|
21
|
+
arches.find { |a| path.include?(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
|
+
codename = Pkg::Platforms.codenames.find { |c| path =~ /\/#{c}/ }
|
29
|
+
|
30
|
+
if codename
|
31
|
+
platform, version = Pkg::Platforms.codename_to_platform_version(codename)
|
32
|
+
end
|
33
|
+
|
34
|
+
version = '2012' if platform == 'windows'
|
35
|
+
|
36
|
+
version ||= Pkg::Platforms.versions_for_platform(platform).find { |v| path =~ /#{platform}(\/|-)?#{v}/ }
|
37
|
+
|
38
|
+
arch = arch_from_artifact_path(platform, version, path)
|
39
|
+
|
40
|
+
return "#{platform}-#{version}-#{arch}"
|
41
|
+
rescue
|
42
|
+
fmt = Pkg::Platforms.all_supported_package_formats.find { |ext| path =~ /#{ext}$/ }
|
43
|
+
|
44
|
+
# We need to make sure this is actually a file, and not simply a path
|
45
|
+
file_ext = File.extname(path)
|
46
|
+
|
47
|
+
# Fail if we do not have a file extension or if that file extension is one
|
48
|
+
# that is platform specific
|
49
|
+
raise "Cannot determine tag from #{path}" if fmt || file_ext.empty?
|
50
|
+
|
51
|
+
# Return nil otherwise, assuming that is a file type that is not tied to a
|
52
|
+
# specific platform
|
53
|
+
return nil
|
54
|
+
end
|
55
|
+
|
56
|
+
# Assign repo name
|
57
|
+
# If we are shipping development/beta/non-final packages, they should be
|
58
|
+
# shipped to the development/beta/non-final repo, if there is one defined.
|
59
|
+
# Otherwise, default to the final repo name. We use this for more than just
|
60
|
+
# shipping to the final repos, so we need this to not fail.
|
61
|
+
def repo_name
|
62
|
+
if Pkg::Util::Version.final?
|
63
|
+
Pkg::Config.repo_name || ""
|
64
|
+
else
|
65
|
+
if Pkg::Config.nonfinal_repo_name
|
66
|
+
Pkg::Config.nonfinal_repo_name
|
67
|
+
else
|
68
|
+
Pkg::Config.repo_name || ""
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def link_name
|
74
|
+
if Pkg::Util::Version.final?
|
75
|
+
Pkg::Config.repo_link_target || nil
|
76
|
+
else
|
77
|
+
Pkg::Config.nonfinal_repo_link_target || nil
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
# TODO: please please please clean this up
|
82
|
+
# This is so terrible. I really dislike it. But in order to maintain backward
|
83
|
+
# compatibility, we need to maintain these path differences between PC1 and
|
84
|
+
# everything else. Once we stop shipping things to PC1, we can remove all the
|
85
|
+
# PC1 specific cases. That's likely to not happen until the current LTS
|
86
|
+
# (2016.4) is EOL'd. Hopefully also we do not choose to further change these
|
87
|
+
# path structures, as it is no bueno.
|
88
|
+
# --MAS 2017-08-16
|
89
|
+
def artifacts_base_path_and_link_path(platform_tag, path_prefix = 'artifacts')
|
90
|
+
platform, version, architecture = Pkg::Platforms.parse_platform_tag(platform_tag)
|
91
|
+
package_format = Pkg::Platforms.package_format_for_tag(platform_tag)
|
92
|
+
|
93
|
+
case package_format
|
94
|
+
when 'rpm'
|
95
|
+
if repo_name == 'PC1'
|
96
|
+
[File.join(path_prefix, platform, version, repo_name), nil]
|
97
|
+
else
|
98
|
+
[File.join(path_prefix, repo_name), link_name.nil? ? nil : File.join(path_prefix, link_name)]
|
99
|
+
end
|
100
|
+
when 'swix'
|
101
|
+
if repo_name == 'PC1'
|
102
|
+
[File.join(path_prefix, platform, version, repo_name), nil]
|
103
|
+
else
|
104
|
+
[File.join(path_prefix, platform, repo_name), link_name.nil? ? nil : File.join(path_prefix, platform, link_name)]
|
105
|
+
end
|
106
|
+
when 'deb'
|
107
|
+
[File.join(path_prefix, Pkg::Platforms.get_attribute(platform_tag, :codename), repo_name),
|
108
|
+
link_name.nil? ? nil : File.join(path_prefix, Pkg::Platforms.get_attribute(platform_tag, :codename), link_name)]
|
109
|
+
when 'svr4', 'ips'
|
110
|
+
if repo_name == 'PC1'
|
111
|
+
[File.join(path_prefix, 'solaris', repo_name, version), nil]
|
112
|
+
else
|
113
|
+
[File.join(path_prefix, 'solaris', repo_name), link_name.nil? ? nil : File.join(path_prefix, 'solaris', link_name)]
|
114
|
+
end
|
115
|
+
when 'dmg'
|
116
|
+
if repo_name == 'PC1'
|
117
|
+
[File.join(path_prefix, 'mac', version, repo_name), nil]
|
118
|
+
else
|
119
|
+
[File.join(path_prefix, 'mac', repo_name), link_name.nil? ? nil : File.join(path_prefix, 'mac', link_name)]
|
120
|
+
end
|
121
|
+
when 'msi'
|
122
|
+
if repo_name == 'PC1'
|
123
|
+
[File.join(path_prefix, 'windows'), nil]
|
124
|
+
else
|
125
|
+
[File.join(path_prefix, 'windows', repo_name), link_name.nil? ? nil : File.join(path_prefix, 'windows', link_name)]
|
126
|
+
end
|
127
|
+
else
|
128
|
+
raise "Not sure where to find packages with a package format of '#{package_format}'"
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
# TODO: please please please clean this up
|
133
|
+
# This is so terrible. I really dislike it. But in order to maintain backward
|
134
|
+
# compatibility, we need to maintain these path differences between PC1 and
|
135
|
+
# everything else. Once we stop shipping things to PC1, we can remove all the
|
136
|
+
# PC1 specific cases. That's likely to not happen until the current LTS
|
137
|
+
# (2016.4) is EOL'd. Hopefully also we do not choose to further change these
|
138
|
+
# path structures, as it is no bueno.
|
139
|
+
# --MAS 2017-08-16
|
140
|
+
def artifacts_path(platform_tag, path_prefix = 'artifacts')
|
141
|
+
base_path, _ = artifacts_base_path_and_link_path(platform_tag, path_prefix)
|
142
|
+
platform, version, architecture = Pkg::Platforms.parse_platform_tag(platform_tag)
|
143
|
+
package_format = Pkg::Platforms.package_format_for_tag(platform_tag)
|
144
|
+
|
145
|
+
case package_format
|
146
|
+
when 'rpm'
|
147
|
+
if repo_name == 'PC1'
|
148
|
+
File.join(base_path, architecture)
|
149
|
+
else
|
150
|
+
File.join(base_path, platform, version, architecture)
|
151
|
+
end
|
152
|
+
when 'swix'
|
153
|
+
if repo_name == 'PC1'
|
154
|
+
File.join(base_path, architecture)
|
155
|
+
else
|
156
|
+
File.join(base_path, version, architecture)
|
157
|
+
end
|
158
|
+
when 'deb'
|
159
|
+
base_path
|
160
|
+
when 'svr4', 'ips'
|
161
|
+
if repo_name == 'PC1'
|
162
|
+
base_path
|
163
|
+
else
|
164
|
+
File.join(base_path, version)
|
165
|
+
end
|
166
|
+
when 'dmg'
|
167
|
+
if repo_name == 'PC1'
|
168
|
+
File.join(base_path, architecture)
|
169
|
+
else
|
170
|
+
File.join(base_path, version, architecture)
|
171
|
+
end
|
172
|
+
when 'msi'
|
173
|
+
base_path
|
174
|
+
else
|
175
|
+
raise "Not sure where to find packages with a package format of '#{package_format}'"
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
def repo_path(platform_tag, options = { :legacy => false })
|
180
|
+
repo_target = repo_name
|
181
|
+
# in legacy packaging methods, there was no consistent way to determine the
|
182
|
+
# repo name. There were separate variables for apt_repo_name and
|
183
|
+
# yum_repo_name. At times, either or both of these were unset, and they had
|
184
|
+
# different defaults. So, for legacy automation we need to just use a splat
|
185
|
+
# and globbing to find our packages.
|
186
|
+
repo_target = '**' if options[:legacy]
|
187
|
+
platform, version, arch = Pkg::Platforms.parse_platform_tag(platform_tag)
|
188
|
+
package_format = Pkg::Platforms.package_format_for_tag(platform_tag)
|
189
|
+
|
190
|
+
case package_format
|
191
|
+
when 'rpm', 'swix'
|
192
|
+
if options[:legacy]
|
193
|
+
File.join('repos', platform, version, repo_target, arch)
|
194
|
+
else
|
195
|
+
File.join('repos', repo_target, platform, version, arch)
|
196
|
+
end
|
197
|
+
when 'deb'
|
198
|
+
File.join('repos', 'apt', Pkg::Platforms.get_attribute(platform_tag, :codename), 'pool', repo_target)
|
199
|
+
when 'svr4', 'ips'
|
200
|
+
if options[:legacy]
|
201
|
+
File.join('repos', 'solaris', version, repo_target)
|
202
|
+
else
|
203
|
+
File.join('repos', 'solaris', repo_target, version)
|
204
|
+
end
|
205
|
+
when 'dmg'
|
206
|
+
if options[:legacy]
|
207
|
+
File.join('repos', 'apple', version, repo_target, arch)
|
208
|
+
else
|
209
|
+
File.join('repos', 'mac', repo_target, version, arch)
|
210
|
+
end
|
211
|
+
when 'msi'
|
212
|
+
if options[:legacy]
|
213
|
+
File.join('repos', 'windows')
|
214
|
+
else
|
215
|
+
File.join('repos', 'windows', repo_target)
|
216
|
+
end
|
217
|
+
else
|
218
|
+
raise "Not sure what to do with a package format of '#{package_format}'"
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
def repo_config_path(platform_tag)
|
223
|
+
package_format = Pkg::Platforms.package_format_for_tag(platform_tag)
|
224
|
+
|
225
|
+
case package_format
|
226
|
+
when 'rpm'
|
227
|
+
# rpm/pl-puppet-agent-1.2.5-el-5-i386.repo for example
|
228
|
+
File.join('repo_configs', 'rpm', "*#{platform_tag}*.repo")
|
229
|
+
when 'deb'
|
230
|
+
# deb/pl-puppet-agent-1.2.5-jessie.list
|
231
|
+
File.join('repo_configs', 'deb', "*#{Pkg::Platforms.get_attribute(platform_tag, :codename)}*.list")
|
232
|
+
when 'msi', 'swix', 'dmg', 'svr4', 'ips'
|
233
|
+
nil
|
234
|
+
else
|
235
|
+
raise "Not sure what to do with a package format of '#{package_format}'"
|
236
|
+
end
|
237
|
+
end
|
238
|
+
end
|