mixlib-install 3.15.0 → 3.17.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 +4 -4
- data/Gemfile +0 -14
- data/lib/mixlib/install/backend/base.rb +1 -1
- data/lib/mixlib/install/backend/package_router.rb +101 -12
- data/lib/mixlib/install/cli.rb +5 -1
- data/lib/mixlib/install/dist.rb +24 -4
- data/lib/mixlib/install/generator/base.rb +1 -14
- data/lib/mixlib/install/generator/bourne/scripts/check_product.sh +1 -1
- data/lib/mixlib/install/generator/bourne/scripts/fetch_metadata.sh.erb +49 -19
- data/lib/mixlib/install/generator/bourne/scripts/fetch_package.sh +47 -23
- data/lib/mixlib/install/generator/bourne/scripts/helpers.sh.erb +40 -38
- data/lib/mixlib/install/generator/bourne/scripts/install_package.sh +2 -2
- data/lib/mixlib/install/generator/bourne/scripts/platform_detection.sh +22 -22
- data/lib/mixlib/install/generator/bourne/scripts/proxy_env.sh +4 -4
- data/lib/mixlib/install/generator/bourne/scripts/script_cli_parameters.sh.erb +9 -3
- data/lib/mixlib/install/generator/bourne.rb +5 -20
- data/lib/mixlib/install/generator/powershell/scripts/get_project_metadata.ps1.erb +60 -36
- data/lib/mixlib/install/generator/powershell/scripts/helpers.ps1.erb +8 -4
- data/lib/mixlib/install/generator/powershell/scripts/install_project.ps1.erb +36 -16
- data/lib/mixlib/install/generator/powershell/scripts/platform_detection.ps1 +1 -0
- data/lib/mixlib/install/generator/powershell.rb +5 -9
- data/lib/mixlib/install/generator.rb +5 -4
- data/lib/mixlib/install/options.rb +40 -0
- data/lib/mixlib/install/product_matrix.rb +6 -1
- data/lib/mixlib/install/script_generator.rb +72 -22
- data/lib/mixlib/install/version.rb +1 -1
- data/lib/mixlib/install.rb +91 -16
- data/mixlib-install.gemspec +2 -0
- data/support/install_command.ps1 +3 -0
- metadata +17 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a8834bc88f13ec12a50e22d4173262a60a525c4c1841d7fbf078a078f05aaa75
|
|
4
|
+
data.tar.gz: 606b0c99f0b2245e5e5b7ccc50c15b306dd3a7e20406225342733075c9bf1069
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: fbc683eca04103659882fdf18678b7e7221b590285794896ecfb5d73fee6d5313407eb959565ee2ae320fef92e911f47b5fe810e63d7af77d44c1f05d1da1bdc
|
|
7
|
+
data.tar.gz: b4fa005ff07749845435b43d5df9fcf4a256924415e416beaa145c91f5cf0251d01945d90749cd34c375d5591bac18643ca65668686b242d8e3661ac68de801a
|
data/Gemfile
CHANGED
|
@@ -3,20 +3,6 @@ source "https://rubygems.org"
|
|
|
3
3
|
gemspec
|
|
4
4
|
|
|
5
5
|
gem "chef-utils", "= 16.6.14" if RUBY_VERSION < "2.6.0"
|
|
6
|
-
# OpenSSL version constraints to fix CRL checking issues in OpenSSL 3.6+
|
|
7
|
-
# Ruby 2.6-2.7 bundled openssl needs update to 3.1.2+
|
|
8
|
-
# Ruby 3.0-3.2 bundled openssl needs update to 3.1.2+
|
|
9
|
-
# Ruby 3.3 bundled openssl needs update to 3.2.2+
|
|
10
|
-
# Ruby 3.4 bundled openssl needs update to 3.3.1+
|
|
11
|
-
if RUBY_VERSION < "2.7.0"
|
|
12
|
-
gem "openssl", ">= 3.1.2", "< 3.2.0"
|
|
13
|
-
elsif RUBY_VERSION < "3.3.0"
|
|
14
|
-
gem "openssl", ">= 3.1.2"
|
|
15
|
-
elsif RUBY_VERSION < "3.4.0"
|
|
16
|
-
gem "openssl", ">= 3.2.2"
|
|
17
|
-
elsif RUBY_VERSION < "4.0.0"
|
|
18
|
-
gem "openssl", ">= 3.3.1"
|
|
19
|
-
end
|
|
20
6
|
|
|
21
7
|
group :test do
|
|
22
8
|
gem "contracts", "~> 0.16.0" # this entry can go away when ruby < 3 support is gone
|
|
@@ -84,7 +84,7 @@ module Mixlib
|
|
|
84
84
|
def filter_artifacts(artifacts)
|
|
85
85
|
return artifacts unless platform_filters_available?
|
|
86
86
|
|
|
87
|
-
#
|
|
87
|
+
# Filter by the exact platform and architecture the user requested.
|
|
88
88
|
artifacts.select! do |a|
|
|
89
89
|
a.platform == options.platform && a.architecture == options.architecture
|
|
90
90
|
end
|
|
@@ -33,12 +33,19 @@ module Mixlib
|
|
|
33
33
|
|
|
34
34
|
COMPAT_DOWNLOAD_URL_ENDPOINT = "http://packages.chef.io".freeze
|
|
35
35
|
|
|
36
|
+
# Architecture strings that appear as level-2 keys in PM-structure packages
|
|
37
|
+
# responses (platform -> arch -> pm -> ...) vs version strings in standard
|
|
38
|
+
# responses (platform -> version -> arch -> ...).
|
|
39
|
+
KNOWN_ARCHITECTURES = %w{x86_64 aarch64 i386 arm64 ppc64 ppc64le s390x universal x86}.freeze
|
|
40
|
+
|
|
36
41
|
# Create filtered list of artifacts
|
|
37
42
|
#
|
|
38
43
|
# @return [Array<ArtifactInfo>] list of artifacts for the configured
|
|
39
44
|
# channel, product name, and product version.
|
|
40
45
|
def available_artifacts
|
|
41
|
-
artifacts = if
|
|
46
|
+
artifacts = if use_licensed_api? && platform_filters_available?
|
|
47
|
+
artifact_from_licensed_metadata
|
|
48
|
+
elsif options.latest_version? || options.partial_version?
|
|
42
49
|
latest_version
|
|
43
50
|
else
|
|
44
51
|
artifacts_for_version(options.product_version)
|
|
@@ -78,10 +85,12 @@ module Mixlib
|
|
|
78
85
|
|
|
79
86
|
# Circumvent early when there are no product artifacts in a specific channel
|
|
80
87
|
if items.empty?
|
|
88
|
+
hint = options.license_id ? "" : "For habitat based products please provide a license ID with -L or set CHEF_LICENSE_KEY."
|
|
81
89
|
raise ArtifactsNotFound, <<-EOF
|
|
82
90
|
No artifacts found matching criteria.
|
|
83
91
|
product name: #{options.product_name}
|
|
84
92
|
channel: #{options.channel}
|
|
93
|
+
#{hint}
|
|
85
94
|
EOF
|
|
86
95
|
end
|
|
87
96
|
|
|
@@ -106,6 +115,9 @@ EOF
|
|
|
106
115
|
#
|
|
107
116
|
# @return [Array<ArtifactInfo>] Array of info about found artifacts
|
|
108
117
|
def latest_version
|
|
118
|
+
# Trial API only supports "latest" as the version — skip version resolution
|
|
119
|
+
return artifacts_for_version("latest") if use_trial_api?
|
|
120
|
+
|
|
109
121
|
product_versions = if options.partial_version?
|
|
110
122
|
v = options.product_version
|
|
111
123
|
partial_version = v.end_with?(".") ? v : v + "."
|
|
@@ -137,16 +149,18 @@ EOF
|
|
|
137
149
|
# Commercial/trial APIs use the packages endpoint which returns metadata for all platforms
|
|
138
150
|
query = "v=#{version}"
|
|
139
151
|
packages_hash = get("/#{options.channel}/#{omnibus_project}/packages?#{query}")
|
|
140
|
-
# Response
|
|
141
|
-
#
|
|
152
|
+
# Response structure differs between products:
|
|
153
|
+
# - PM-structure products (e.g. chef-ice, inspec-enterprise): platform -> architecture -> package_manager -> package_info
|
|
154
|
+
# - Standard products: platform -> platform_version -> architecture -> package_info
|
|
142
155
|
results = []
|
|
143
|
-
packages_hash
|
|
144
|
-
|
|
145
|
-
architectures.each do |arch,
|
|
156
|
+
if pm_structure_response?(packages_hash)
|
|
157
|
+
packages_hash.each do |platform, architectures|
|
|
158
|
+
architectures.each do |arch, package_managers|
|
|
159
|
+
pkg_info = package_managers.values.first
|
|
146
160
|
results << {
|
|
147
161
|
"omnibus.version" => pkg_info["version"],
|
|
148
162
|
"omnibus.platform" => platform,
|
|
149
|
-
"omnibus.platform_version" =>
|
|
163
|
+
"omnibus.platform_version" => "",
|
|
150
164
|
"omnibus.architecture" => arch,
|
|
151
165
|
"omnibus.project" => omnibus_project,
|
|
152
166
|
"omnibus.license" => "Apache-2.0",
|
|
@@ -156,6 +170,25 @@ EOF
|
|
|
156
170
|
}
|
|
157
171
|
end
|
|
158
172
|
end
|
|
173
|
+
else
|
|
174
|
+
# Standard structure: platform -> platform_version -> architecture -> package_info
|
|
175
|
+
packages_hash.each do |platform, platform_versions|
|
|
176
|
+
platform_versions.each do |platform_version, architectures|
|
|
177
|
+
architectures.each do |arch, pkg_info|
|
|
178
|
+
results << {
|
|
179
|
+
"omnibus.version" => pkg_info["version"],
|
|
180
|
+
"omnibus.platform" => platform,
|
|
181
|
+
"omnibus.platform_version" => platform_version,
|
|
182
|
+
"omnibus.architecture" => arch,
|
|
183
|
+
"omnibus.project" => omnibus_project,
|
|
184
|
+
"omnibus.license" => "Apache-2.0",
|
|
185
|
+
"omnibus.sha256" => pkg_info["sha256"],
|
|
186
|
+
"omnibus.sha1" => pkg_info.fetch("sha1", ""),
|
|
187
|
+
"omnibus.md5" => pkg_info.fetch("md5", ""),
|
|
188
|
+
}
|
|
189
|
+
end
|
|
190
|
+
end
|
|
191
|
+
end
|
|
159
192
|
end
|
|
160
193
|
else
|
|
161
194
|
results = get("/api/v1/#{options.channel}/#{omnibus_project}/#{version}/artifacts")["results"]
|
|
@@ -198,6 +231,16 @@ EOF
|
|
|
198
231
|
res = http.request(create_http_request(full_path))
|
|
199
232
|
res.value
|
|
200
233
|
JSON.parse(res.body)
|
|
234
|
+
rescue Net::HTTPClientError, Net::HTTPServerError => e
|
|
235
|
+
# Provide helpful error messages for licensed API failures
|
|
236
|
+
if use_trial_api?
|
|
237
|
+
if options.channel != :stable || (options.product_version != :latest && options.product_version.to_sym != :latest)
|
|
238
|
+
raise "Trial API only supports stable channel and latest version. " \
|
|
239
|
+
"Current settings: channel=#{options.channel}, version=#{options.product_version}. " \
|
|
240
|
+
"Error: #{e.message}"
|
|
241
|
+
end
|
|
242
|
+
end
|
|
243
|
+
raise e
|
|
201
244
|
end
|
|
202
245
|
|
|
203
246
|
def create_http_request(full_path)
|
|
@@ -208,6 +251,50 @@ EOF
|
|
|
208
251
|
request
|
|
209
252
|
end
|
|
210
253
|
|
|
254
|
+
# Detects whether a packages API response uses PM-structure format.
|
|
255
|
+
# Standard: platform -> platform_version -> architecture -> pkg_info
|
|
256
|
+
#
|
|
257
|
+
# Detection: PM-structure has architecture strings (x86_64, aarch64, …) as
|
|
258
|
+
# the second-level keys; standard has version strings (20.04, 18.04, …).
|
|
259
|
+
def pm_structure_response?(packages_hash)
|
|
260
|
+
first_platform = packages_hash.values.first
|
|
261
|
+
return false unless first_platform.is_a?(Hash)
|
|
262
|
+
|
|
263
|
+
first_platform.keys.any? { |k| KNOWN_ARCHITECTURES.include?(k) }
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
# Fetches a single artifact from the licensed API metadata endpoint.
|
|
267
|
+
# Used when a platform is specified, giving the server full context to
|
|
268
|
+
# derive the package manager and return the correct sha256 — no pm needed.
|
|
269
|
+
def artifact_from_licensed_metadata
|
|
270
|
+
version = (options.latest_version? || options.partial_version?) ? "latest" : options.product_version
|
|
271
|
+
query = "v=#{version}&p=#{options.platform}&m=#{Util.normalize_architecture(options.architecture)}"
|
|
272
|
+
query += "&pv=#{options.platform_version}" unless options.platform_version.to_s.empty?
|
|
273
|
+
|
|
274
|
+
begin
|
|
275
|
+
metadata = get("/#{options.channel}/#{omnibus_project}/metadata?#{query}")
|
|
276
|
+
rescue Net::HTTPServerException => e
|
|
277
|
+
return [] if e.message.match?(/400|404/)
|
|
278
|
+
|
|
279
|
+
raise e
|
|
280
|
+
end
|
|
281
|
+
|
|
282
|
+
return [] if metadata.nil? || metadata.empty?
|
|
283
|
+
|
|
284
|
+
artifact_map = {
|
|
285
|
+
"omnibus.version" => metadata["version"],
|
|
286
|
+
"omnibus.platform" => options.platform,
|
|
287
|
+
"omnibus.platform_version" => options.platform_version.to_s,
|
|
288
|
+
"omnibus.architecture" => options.architecture,
|
|
289
|
+
"omnibus.project" => omnibus_project,
|
|
290
|
+
"omnibus.license" => "Apache-2.0",
|
|
291
|
+
"omnibus.sha256" => metadata["sha256"],
|
|
292
|
+
"omnibus.sha1" => metadata.fetch("sha1", ""),
|
|
293
|
+
"omnibus.md5" => metadata.fetch("md5", ""),
|
|
294
|
+
}
|
|
295
|
+
[create_artifact(artifact_map)]
|
|
296
|
+
end
|
|
297
|
+
|
|
211
298
|
def create_artifact(artifact_map)
|
|
212
299
|
# set normalized platform and platform version
|
|
213
300
|
platform, platform_version = normalize_platform(
|
|
@@ -245,13 +332,15 @@ EOF
|
|
|
245
332
|
|
|
246
333
|
# create the download path with the correct endpoint
|
|
247
334
|
if use_licensed_api?
|
|
248
|
-
# Commercial/trial APIs use the download endpoint with query parameters
|
|
249
|
-
|
|
250
|
-
p_param = platform
|
|
251
|
-
pv_param = platform_version
|
|
335
|
+
# Commercial/trial APIs use the download endpoint with query parameters.
|
|
336
|
+
|
|
252
337
|
m_param = Util.normalize_architecture(artifact_map["omnibus.architecture"])
|
|
253
338
|
v_param = artifact_map["omnibus.version"]
|
|
254
|
-
|
|
339
|
+
# Use the user's actual platform (e.g. "ubuntu", "el") so the server can derive pm.
|
|
340
|
+
p_param = options.platform || platform
|
|
341
|
+
pv_param = options.platform_version || platform_version
|
|
342
|
+
pv_part = pv_param.to_s.empty? ? "" : "&pv=#{pv_param}"
|
|
343
|
+
download_url = "#{endpoint}/#{options.channel}/#{omnibus_project}/download?p=#{p_param}#{pv_part}&m=#{m_param}&v=#{v_param}&license_id=#{options.license_id}"
|
|
255
344
|
else
|
|
256
345
|
base_url = if use_compat_download_url_endpoint?(platform, platform_version)
|
|
257
346
|
COMPAT_DOWNLOAD_URL_ENDPOINT
|
data/lib/mixlib/install/cli.rb
CHANGED
|
@@ -31,8 +31,12 @@ module Mixlib
|
|
|
31
31
|
end
|
|
32
32
|
|
|
33
33
|
desc "list-versions PRODUCT_NAME CHANNEL", "list available version for a product/channel"
|
|
34
|
+
option :license_id,
|
|
35
|
+
desc: "License ID for commercial/trial API",
|
|
36
|
+
aliases: ["-L"]
|
|
34
37
|
def list_versions(product_name, channel)
|
|
35
|
-
|
|
38
|
+
lid = options[:license_id] || ENV["CHEF_LICENSE_KEY"]
|
|
39
|
+
say Mixlib::Install.available_versions(product_name, channel, license_id: lid).join("\n")
|
|
36
40
|
end
|
|
37
41
|
|
|
38
42
|
desc "list-products", "list available products"
|
data/lib/mixlib/install/dist.rb
CHANGED
|
@@ -26,10 +26,30 @@ module Mixlib
|
|
|
26
26
|
RESOURCES_URL = "https://www.chef.io/support".freeze
|
|
27
27
|
# MacOS volume name
|
|
28
28
|
MACOS_VOLUME = "chef_software".freeze
|
|
29
|
-
# Windows install directory name
|
|
30
|
-
|
|
31
|
-
# Linux install directory name
|
|
32
|
-
|
|
29
|
+
# Omnibus Windows install directory name
|
|
30
|
+
OMNIBUS_WINDOWS_INSTALL_DIR = "opscode".freeze
|
|
31
|
+
# Omnibus Linux install directory name
|
|
32
|
+
OMNIBUS_LINUX_INSTALL_DIR = "/opt".freeze
|
|
33
|
+
# Habitat Windows install directory name
|
|
34
|
+
HABITAT_WINDOWS_INSTALL_DIR = "hab\\pkgs".freeze
|
|
35
|
+
# Habitat Linux install directory name
|
|
36
|
+
HABITAT_LINUX_INSTALL_DIR = "/hab/pkgs".freeze
|
|
37
|
+
|
|
38
|
+
# Check if a license_id is for trial API
|
|
39
|
+
# @param license_id [String] the license ID to check
|
|
40
|
+
# @return [Boolean] true if license_id indicates trial API usage
|
|
41
|
+
def self.trial_license?(license_id)
|
|
42
|
+
!license_id.nil? && !license_id.to_s.empty? &&
|
|
43
|
+
license_id.start_with?("free-", "trial-")
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# Check if a license_id is for commercial API
|
|
47
|
+
# @param license_id [String] the license ID to check
|
|
48
|
+
# @return [Boolean] true if license_id indicates commercial API usage
|
|
49
|
+
def self.commercial_license?(license_id)
|
|
50
|
+
!license_id.nil? && !license_id.to_s.empty? &&
|
|
51
|
+
!trial_license?(license_id)
|
|
52
|
+
end
|
|
33
53
|
end
|
|
34
54
|
end
|
|
35
55
|
end
|
|
@@ -19,7 +19,6 @@ require "erb" unless defined?(Erb)
|
|
|
19
19
|
require "ostruct" unless defined?(OpenStruct)
|
|
20
20
|
require_relative "../util"
|
|
21
21
|
require_relative "../dist"
|
|
22
|
-
require "net/http" unless defined?(Net::HTTP)
|
|
23
22
|
|
|
24
23
|
module Mixlib
|
|
25
24
|
class Install
|
|
@@ -50,13 +49,12 @@ module Mixlib
|
|
|
50
49
|
if File.exist? "#{script_path}.erb"
|
|
51
50
|
# Default values to use incase they are not set in the context
|
|
52
51
|
context[:project_name] ||= Mixlib::Install::Dist::PROJECT_NAME.freeze
|
|
53
|
-
context[:base_url] ||= Mixlib::Install::Dist::OMNITRUCK_ENDPOINT.freeze
|
|
54
52
|
context[:default_product] ||= Mixlib::Install::Dist::DEFAULT_PRODUCT.freeze
|
|
55
53
|
context[:bug_url] ||= Mixlib::Install::Dist::BUG_URL.freeze
|
|
56
54
|
context[:support_url] ||= Mixlib::Install::Dist::SUPPORT_URL.freeze
|
|
57
55
|
context[:resources_url] ||= Mixlib::Install::Dist::RESOURCES_URL.freeze
|
|
58
56
|
context[:macos_dir] ||= Mixlib::Install::Dist::MACOS_VOLUME.freeze
|
|
59
|
-
context[:windows_dir] ||= Mixlib::Install::Dist::
|
|
57
|
+
context[:windows_dir] ||= context[:default_product].casecmp("chef-ice") == 0 ? Mixlib::Install::Dist::HABITAT_WINDOWS_INSTALL_DIR.freeze : Mixlib::Install::Dist::OMNIBUS_WINDOWS_INSTALL_DIR.freeze
|
|
60
58
|
context[:user_agent_string] = Util.user_agent_string(context[:user_agent_headers])
|
|
61
59
|
|
|
62
60
|
context_object = OpenStruct.new(context).instance_eval { binding }
|
|
@@ -69,17 +67,6 @@ module Mixlib
|
|
|
69
67
|
def get_script(name, context = {})
|
|
70
68
|
self.class.get_script(name, context)
|
|
71
69
|
end
|
|
72
|
-
|
|
73
|
-
def install_sh_from_upstream
|
|
74
|
-
uri = URI.parse(options.options[:new_omnibus_download_url])
|
|
75
|
-
response = Net::HTTP.get_response(uri)
|
|
76
|
-
|
|
77
|
-
if response.code == "200"
|
|
78
|
-
response.body
|
|
79
|
-
else
|
|
80
|
-
raise StandardError, "unable to fetch the install.sh"
|
|
81
|
-
end
|
|
82
|
-
end
|
|
83
70
|
end
|
|
84
71
|
end
|
|
85
72
|
end
|
|
@@ -8,7 +8,7 @@ else
|
|
|
8
8
|
fi
|
|
9
9
|
|
|
10
10
|
for path in $install_paths; do
|
|
11
|
-
if [ -d "$path" ]
|
|
11
|
+
if [ -d "$path" ] && [ "$install_strategy" = "once" ]; then
|
|
12
12
|
echo "$project installation detected at $path"
|
|
13
13
|
echo "install_strategy set to 'once'"
|
|
14
14
|
echo "Nothing to install"
|
|
@@ -3,7 +3,15 @@
|
|
|
3
3
|
# This section calls omnitruck to get the information about the build to be
|
|
4
4
|
# installed.
|
|
5
5
|
#
|
|
6
|
+
# EXAMPLE
|
|
7
|
+
# curl -L '<%= base_url || "https://chefdownload-commercial.chef.io" %>/install.sh<%= base_url && base_url.include?("chefdownload") ? "?license_id=$CHEF_LICENSE_KEY" : "" %>' | sudo bash -s -- -P chef -c stable
|
|
8
|
+
#
|
|
9
|
+
# Gets the download url and SHA256 checksum for the latest stable release of Chef Workstation.
|
|
10
|
+
# EXAMPLE
|
|
11
|
+
# curl -L '<%= base_url || "https://chefdownload-commercial.chef.io" %>/install.sh<%= base_url && base_url.include?("chefdownload") ? "?license_id=$CHEF_LICENSE_KEY" : "" %>' | sudo bash -s -- -P chef-workstation -c stable
|
|
12
|
+
#
|
|
6
13
|
# Inputs:
|
|
14
|
+
# $base_api_url:
|
|
7
15
|
# $channel:
|
|
8
16
|
# $project:
|
|
9
17
|
# $version:
|
|
@@ -17,38 +25,60 @@
|
|
|
17
25
|
# $sha256:
|
|
18
26
|
############
|
|
19
27
|
|
|
20
|
-
if
|
|
28
|
+
if [ -z "$download_url_override" ]; then
|
|
21
29
|
echo "Getting information for $project $channel $version for $platform..."
|
|
22
30
|
|
|
23
31
|
metadata_filename="$tmp_dir/metadata.txt"
|
|
32
|
+
<% if base_url && !base_url.to_s.empty? %>
|
|
33
|
+
# Set base_api_url from option if not already set via CLI parameter
|
|
34
|
+
if [ -z "$base_api_url" ]; then
|
|
35
|
+
base_api_url="<%= base_url %>"
|
|
36
|
+
fi
|
|
37
|
+
<% end %>
|
|
24
38
|
|
|
25
39
|
# Use commercial API if license_id is provided, otherwise use omnitruck
|
|
26
|
-
if
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
40
|
+
if [ -z "$base_api_url" ]; then
|
|
41
|
+
if [ -n "$license_id" ]; then
|
|
42
|
+
# Check if license_id starts with 'free-' or 'trial-' for trial API
|
|
43
|
+
case "$license_id" in
|
|
44
|
+
free-*|trial-*)
|
|
45
|
+
# Trial API endpoint
|
|
46
|
+
base_api_url="<%= Mixlib::Install::Dist::TRIAL_API_ENDPOINT %>"
|
|
47
|
+
;;
|
|
48
|
+
*)
|
|
49
|
+
# Commercial API endpoint
|
|
50
|
+
base_api_url="<%= Mixlib::Install::Dist::COMMERCIAL_API_ENDPOINT %>"
|
|
51
|
+
;;
|
|
52
|
+
esac
|
|
53
|
+
else
|
|
54
|
+
# Omnitruck endpoint
|
|
55
|
+
base_api_url="<%= Mixlib::Install::Dist::OMNITRUCK_ENDPOINT %>"
|
|
56
|
+
fi
|
|
57
|
+
fi
|
|
58
|
+
|
|
59
|
+
if [ -n "$license_id" ]; then
|
|
60
|
+
license_param="&license_id=$license_id"
|
|
39
61
|
else
|
|
40
|
-
|
|
41
|
-
metadata_url="<%= base_url %>/$channel/$project/metadata?v=$version&p=$platform&pv=$platform_version&m=$machine"
|
|
62
|
+
license_param=""
|
|
42
63
|
fi
|
|
43
64
|
|
|
44
|
-
|
|
65
|
+
if [ -n "$package_manager" ]; then
|
|
66
|
+
pm_param="&pm=$package_manager"
|
|
67
|
+
else
|
|
68
|
+
pm_param=""
|
|
69
|
+
fi
|
|
70
|
+
|
|
71
|
+
# Build the metadata URL.
|
|
72
|
+
metadata_url="$base_api_url/$channel/$project/metadata?v=$version&p=$platform&pv=$platform_version&m=$machine${license_param}${pm_param}"
|
|
73
|
+
|
|
74
|
+
do_download "$metadata_url" "$metadata_filename"
|
|
45
75
|
|
|
46
76
|
cat "$metadata_filename"
|
|
47
77
|
|
|
48
78
|
echo ""
|
|
49
79
|
|
|
50
80
|
# Commercial and trial APIs return JSON, omnitruck returns text format
|
|
51
|
-
if
|
|
81
|
+
if [ -n "$license_id" ]; then
|
|
52
82
|
# Parse JSON response from commercial/trial API
|
|
53
83
|
# Check if response looks like JSON
|
|
54
84
|
if grep -q '^{' "$metadata_filename" 2>/dev/null; then
|
|
@@ -57,7 +87,7 @@ if test "x$download_url_override" = "x"; then
|
|
|
57
87
|
download_url=`sed -n 's/.*"url":"\([^"]*\)".*/\1/p' "$metadata_filename"`
|
|
58
88
|
sha256=`sed -n 's/.*"sha256":"\([^"]*\)".*/\1/p' "$metadata_filename"`
|
|
59
89
|
|
|
60
|
-
if
|
|
90
|
+
if [ -n "$download_url" ] && [ -n "$sha256" ]; then
|
|
61
91
|
echo "downloaded metadata file looks valid..."
|
|
62
92
|
else
|
|
63
93
|
echo "downloaded metadata file is corrupted or an uncaught error was encountered in downloading the file..."
|
|
@@ -17,16 +17,36 @@
|
|
|
17
17
|
|
|
18
18
|
# For licensed APIs (commercial/trial), the URL is an endpoint, not a direct file URL
|
|
19
19
|
# The actual filename will come from the Content-Disposition header
|
|
20
|
-
if
|
|
21
|
-
|
|
20
|
+
# Also check if download_url_override is used with a URL that doesn't have a filename
|
|
21
|
+
# (e.g., ends with /download or /download?params instead of /package-1.2.3.rpm)
|
|
22
|
+
|
|
23
|
+
# Function to check if URL path contains a valid package filename
|
|
24
|
+
has_package_filename() {
|
|
25
|
+
url_path=`echo "$1" | sed -e 's/?.*//' -e 's/^.*\///'`
|
|
26
|
+
# Check if the path segment has a package extension
|
|
27
|
+
case "$url_path" in
|
|
28
|
+
*.rpm|*.deb|*.pkg|*.msi|*.dmg|*.bff|*.p5p|*.solaris|*.sh)
|
|
29
|
+
return 0 # has valid filename
|
|
30
|
+
;;
|
|
31
|
+
*)
|
|
32
|
+
return 1 # no valid filename
|
|
33
|
+
;;
|
|
34
|
+
esac
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
# Determine if we need to use content-disposition based on license_id or URL structure
|
|
38
|
+
if [ -n "$license_id" ] || ! has_package_filename "$download_url"; then
|
|
39
|
+
# Use content-disposition to get the filename if:
|
|
40
|
+
# 1. license_id is set (commercial/trial API)
|
|
41
|
+
# 2. URL doesn't contain a package filename (e.g., ends with /download or /download?params)
|
|
22
42
|
use_content_disposition="true"
|
|
23
43
|
# We don't know the filename yet - it will come from Content-Disposition
|
|
24
44
|
# Just set the download directory
|
|
25
|
-
if
|
|
45
|
+
if [ -n "$cmdline_filename" ]; then
|
|
26
46
|
download_filename="$cmdline_filename"
|
|
27
47
|
download_dir=`dirname $download_filename`
|
|
28
48
|
use_content_disposition="false" # User specified exact filename
|
|
29
|
-
elif
|
|
49
|
+
elif [ -n "$cmdline_dl_dir" ]; then
|
|
30
50
|
download_dir="$cmdline_dl_dir"
|
|
31
51
|
download_filename="" # Will be determined after download
|
|
32
52
|
else
|
|
@@ -41,9 +61,9 @@ else
|
|
|
41
61
|
filetype=`echo $filename | sed -e 's/^.*\.//'`
|
|
42
62
|
|
|
43
63
|
# use either $tmp_dir, the provided directory (-d) or the provided filename (-f)
|
|
44
|
-
if
|
|
64
|
+
if [ -n "$cmdline_filename" ]; then
|
|
45
65
|
download_filename="$cmdline_filename"
|
|
46
|
-
elif
|
|
66
|
+
elif [ -n "$cmdline_dl_dir" ]; then
|
|
47
67
|
download_filename="$cmdline_dl_dir/$filename"
|
|
48
68
|
else
|
|
49
69
|
download_filename="$tmp_dir/$filename"
|
|
@@ -64,19 +84,19 @@ cached_file_available="false"
|
|
|
64
84
|
verify_checksum="true"
|
|
65
85
|
|
|
66
86
|
# Skip caching checks when using content-disposition since we don't know the real filename yet
|
|
67
|
-
if
|
|
87
|
+
if [ "$use_content_disposition" = "true" ]; then
|
|
68
88
|
cached_file_available="false"
|
|
69
89
|
verify_checksum="true"
|
|
70
|
-
elif
|
|
90
|
+
elif [ -n "$download_filename" ] && [ -f "$download_filename" ]; then
|
|
71
91
|
echo "$download_filename exists"
|
|
72
92
|
cached_file_available="true"
|
|
73
93
|
fi
|
|
74
94
|
|
|
75
|
-
if
|
|
95
|
+
if [ -n "$download_url_override" ] && [ "$use_content_disposition" = "false" ]; then
|
|
76
96
|
echo "Download URL override specified"
|
|
77
|
-
if
|
|
97
|
+
if [ "$cached_file_available" = "true" ]; then
|
|
78
98
|
echo "Verifying local file"
|
|
79
|
-
if
|
|
99
|
+
if [ -z "$sha256" ]; then
|
|
80
100
|
echo "Checksum not specified, ignoring existing file"
|
|
81
101
|
cached_file_available="false" # download new file
|
|
82
102
|
verify_checksum="false" # no checksum to compare after download
|
|
@@ -92,7 +112,7 @@ if test "x$download_url_override" != "x" && test "x$use_content_disposition" = "
|
|
|
92
112
|
else
|
|
93
113
|
echo "$download_filename not found"
|
|
94
114
|
cached_file_available="false" # download new file
|
|
95
|
-
if
|
|
115
|
+
if [ -z "$sha256" ]; then
|
|
96
116
|
verify_checksum="false" # no checksum to compare after download
|
|
97
117
|
else
|
|
98
118
|
verify_checksum="true" # checksum new downloaded file
|
|
@@ -100,8 +120,8 @@ if test "x$download_url_override" != "x" && test "x$use_content_disposition" = "
|
|
|
100
120
|
fi
|
|
101
121
|
fi
|
|
102
122
|
|
|
103
|
-
if
|
|
104
|
-
if
|
|
123
|
+
if [ "$cached_file_available" != "true" ]; then
|
|
124
|
+
if [ "$use_content_disposition" = "true" ]; then
|
|
105
125
|
# For licensed APIs, download to a temporary file and extract filename from response headers
|
|
106
126
|
# The download_dir was already set during initialization above
|
|
107
127
|
|
|
@@ -112,33 +132,33 @@ if test "x$cached_file_available" != "xtrue"; then
|
|
|
112
132
|
do_download "$download_url" "$temp_download"
|
|
113
133
|
|
|
114
134
|
# Extract filename from response headers (try multiple methods for compatibility)
|
|
115
|
-
if
|
|
135
|
+
if [ -f "$tmp_dir/stderr" ]; then
|
|
116
136
|
# Method 1: Try to extract filename from content-disposition header
|
|
117
137
|
# Format: content-disposition: attachment; filename="chef-18.8.54-1.el9.x86_64.rpm"
|
|
118
138
|
actual_filename=`grep -i 'content-disposition' $tmp_dir/stderr | sed -n 's/.*filename="\([^"]*\)".*/\1/p' | head -1`
|
|
119
139
|
|
|
120
140
|
# Method 2: If content-disposition failed, try to extract from location redirect header
|
|
121
141
|
# Format: location: https://packages.chef.io/files/stable/chef/18.8.54/el/9/chef-18.8.54-1.el9.x86_64.rpm?licenseId=...
|
|
122
|
-
if
|
|
142
|
+
if [ -z "$actual_filename" ]; then
|
|
123
143
|
actual_filename=`grep -i '^location:' $tmp_dir/stderr | head -1 | sed 's/.*\///' | sed 's/?.*//'`
|
|
124
144
|
fi
|
|
125
145
|
|
|
126
146
|
# Method 3: Try extracting from any URL-like pattern in stderr
|
|
127
|
-
if
|
|
147
|
+
if [ -z "$actual_filename" ]; then
|
|
128
148
|
actual_filename=`grep -i '\.rpm\|\.deb\|\.pkg\|\.msi\|\.dmg' $tmp_dir/stderr | sed -n 's/.*\/\([^/?]*\.\(rpm\|deb\|pkg\|msi\|dmg\)\).*/\1/p' | head -1`
|
|
129
149
|
fi
|
|
130
150
|
fi
|
|
131
151
|
|
|
132
152
|
# If we still couldn't extract from headers, construct filename from metadata
|
|
133
|
-
if
|
|
153
|
+
if [ -z "$actual_filename" ]; then
|
|
134
154
|
echo "Warning: Could not extract filename from response headers, using fallback"
|
|
135
155
|
# Construct a reasonable filename from available metadata
|
|
136
156
|
# This is a fallback and may not match the exact package name
|
|
137
|
-
if
|
|
157
|
+
if [ "$platform" = "el" ] || [ "$platform" = "fedora" ] || [ "$platform" = "amazon" ]; then
|
|
138
158
|
actual_filename="chef-${version}-1.${platform}${platform_version}.${machine}.rpm"
|
|
139
|
-
elif
|
|
159
|
+
elif [ "$platform" = "debian" ] || [ "$platform" = "ubuntu" ]; then
|
|
140
160
|
actual_filename="chef_${version}-1_${machine}.deb"
|
|
141
|
-
elif
|
|
161
|
+
elif [ "$platform" = "mac_os_x" ]; then
|
|
142
162
|
actual_filename="chef-${version}.dmg"
|
|
143
163
|
else
|
|
144
164
|
actual_filename="chef-${version}.pkg"
|
|
@@ -160,8 +180,12 @@ if test "x$cached_file_available" != "xtrue"; then
|
|
|
160
180
|
fi
|
|
161
181
|
fi
|
|
162
182
|
|
|
163
|
-
if
|
|
164
|
-
|
|
183
|
+
if [ "$verify_checksum" = "true" ]; then
|
|
184
|
+
if [ -z "$sha256" ]; then
|
|
185
|
+
echo "Skipping checksum verification - no checksum provided"
|
|
186
|
+
else
|
|
187
|
+
do_checksum "$download_filename" "$sha256" || checksum_mismatch
|
|
188
|
+
fi
|
|
165
189
|
fi
|
|
166
190
|
|
|
167
191
|
############
|