mixlib-install 3.14.0 → 3.16.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.
Files changed (30) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +0 -14
  3. data/lib/mixlib/install/backend/base.rb +15 -1
  4. data/lib/mixlib/install/backend/package_router.rb +60 -17
  5. data/lib/mixlib/install/cli.rb +2 -1
  6. data/lib/mixlib/install/dist.rb +24 -4
  7. data/lib/mixlib/install/generator/base.rb +1 -14
  8. data/lib/mixlib/install/generator/bourne/scripts/check_product.sh +11 -3
  9. data/lib/mixlib/install/generator/bourne/scripts/fetch_metadata.sh.erb +89 -19
  10. data/lib/mixlib/install/generator/bourne/scripts/fetch_package.sh +47 -23
  11. data/lib/mixlib/install/generator/bourne/scripts/helpers.sh.erb +30 -32
  12. data/lib/mixlib/install/generator/bourne/scripts/install_package.sh +2 -2
  13. data/lib/mixlib/install/generator/bourne/scripts/platform_detection.sh +22 -22
  14. data/lib/mixlib/install/generator/bourne/scripts/proxy_env.sh +4 -4
  15. data/lib/mixlib/install/generator/bourne/scripts/script_cli_parameters.sh.erb +9 -2
  16. data/lib/mixlib/install/generator/bourne.rb +11 -6
  17. data/lib/mixlib/install/generator/powershell/scripts/get_project_metadata.ps1.erb +52 -36
  18. data/lib/mixlib/install/generator/powershell/scripts/helpers.ps1.erb +8 -4
  19. data/lib/mixlib/install/generator/powershell/scripts/install_project.ps1.erb +57 -26
  20. data/lib/mixlib/install/generator/powershell/scripts/platform_detection.ps1 +1 -0
  21. data/lib/mixlib/install/generator/powershell.rb +5 -4
  22. data/lib/mixlib/install/generator.rb +5 -4
  23. data/lib/mixlib/install/options.rb +41 -0
  24. data/lib/mixlib/install/product_matrix.rb +1 -1
  25. data/lib/mixlib/install/script_generator.rb +80 -23
  26. data/lib/mixlib/install/util.rb +47 -0
  27. data/lib/mixlib/install/version.rb +1 -1
  28. data/lib/mixlib/install.rb +82 -11
  29. data/support/install_command.ps1 +3 -0
  30. metadata +2 -2
@@ -103,6 +103,7 @@ module Mixlib
103
103
  uri = URI.parse(artifact.url)
104
104
  filename = nil
105
105
  final_body = nil
106
+ final_uri = uri
106
107
 
107
108
  Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == "https") do |http|
108
109
  # Build the request path including query string
@@ -112,23 +113,27 @@ module Mixlib
112
113
  # Get the response, following redirects
113
114
  response = http.request_get(request_path)
114
115
 
116
+ # Try to extract filename from Content-Disposition in initial response
117
+ if response["content-disposition"]
118
+ filename = response["content-disposition"][/filename="?([^"]+)"?/, 1]
119
+ end
120
+
115
121
  # Follow redirects
116
122
  redirect_limit = 5
117
123
  while response.is_a?(Net::HTTPRedirection) && redirect_limit > 0
118
124
  redirect_uri = URI.parse(response["location"])
119
125
  # Handle relative redirects
120
126
  redirect_uri = uri + redirect_uri if redirect_uri.relative?
127
+ final_uri = redirect_uri
121
128
 
122
129
  Net::HTTP.start(redirect_uri.host, redirect_uri.port, use_ssl: redirect_uri.scheme == "https") do |redirect_http|
123
130
  redirect_path = redirect_uri.path
124
131
  redirect_path += "?#{redirect_uri.query}" if redirect_uri.query
125
132
  response = redirect_http.request_get(redirect_path)
126
133
 
127
- # Try to get filename from Content-Disposition or final URL
128
- if response["content-disposition"]
134
+ # Try to get filename from Content-Disposition in redirect response
135
+ if response["content-disposition"] && filename.nil?
129
136
  filename = response["content-disposition"][/filename="?([^"]+)"?/, 1]
130
- else
131
- filename = File.basename(redirect_uri.path)
132
137
  end
133
138
  end
134
139
 
@@ -136,9 +141,23 @@ module Mixlib
136
141
  end
137
142
 
138
143
  final_body = response.body
144
+
145
+ # Try Content-Disposition from final successful response
146
+ if response["content-disposition"] && filename.nil?
147
+ filename = response["content-disposition"][/filename="?([^"]+)"?/, 1]
148
+ end
149
+ end
150
+
151
+ # Fallback: extract filename from final URL path (works for direct package URLs)
152
+ if filename.nil?
153
+ path_filename = File.basename(final_uri.path.split("?").first)
154
+ # Only use path filename if it looks like a package file
155
+ if /\.(rpm|deb|pkg|msi|dmg|bff|p5p|sh|tar|gz|appx)$/.match?(path_filename)
156
+ filename = path_filename
157
+ end
139
158
  end
140
159
 
141
- # Use the extracted filename or fall back to basename of original URL
160
+ # Final fallback: use basename of original URL
142
161
  filename ||= File.basename(uri.path)
143
162
  file = File.join(directory, filename)
144
163
 
@@ -158,10 +177,19 @@ module Mixlib
158
177
  def root
159
178
  # This only works for chef and chefdk but they are the only projects
160
179
  # we are supporting as of now.
161
- if options.for_ps1?
162
- "$env:systemdrive\\#{Mixlib::Install::Dist::WINDOWS_INSTALL_DIR}\\#{options.product_name}"
180
+ # chef-ice uses Habitat install directories
181
+ if options.product_name.casecmp("chef-ice") == 0
182
+ if options.for_ps1?
183
+ "$env:systemdrive\\#{Mixlib::Install::Dist::HABITAT_WINDOWS_INSTALL_DIR}\\chef\\chef-infra-client\\*\\*"
184
+ else
185
+ "#{Mixlib::Install::Dist::HABITAT_LINUX_INSTALL_DIR}/chef/chef-infra-client/*/*"
186
+ end
163
187
  else
164
- "/opt/#{options.product_name}"
188
+ if options.for_ps1?
189
+ "$env:systemdrive\\#{Mixlib::Install::Dist::OMNIBUS_WINDOWS_INSTALL_DIR}\\#{options.product_name}"
190
+ else
191
+ "#{Mixlib::Install::Dist::OMNIBUS_LINUX_INSTALL_DIR}/#{options.product_name}"
192
+ end
165
193
  end
166
194
  end
167
195
 
@@ -175,10 +203,19 @@ module Mixlib
175
203
  # install directory which can be different than the product name (e.g.
176
204
  # chef-server -> /opt/opscode). But this is OK for now since
177
205
  # chef & chefdk are the only supported products.
178
- version_manifest_file = if options.for_ps1?
179
- "$env:systemdrive\\#{Mixlib::Install::Dist::WINDOWS_INSTALL_DIR}\\#{options.product_name}\\version-manifest.json"
206
+ # chef-ice uses Habitat install directories
207
+ version_manifest_file = if options.product_name.casecmp("chef-ice") == 0
208
+ if options.for_ps1?
209
+ "$env:systemdrive\\#{Mixlib::Install::Dist::HABITAT_WINDOWS_INSTALL_DIR}\\chef\\chef-infra-client\\*\\*\\version-manifest.json"
210
+ else
211
+ "#{Mixlib::Install::Dist::HABITAT_LINUX_INSTALL_DIR}/chef/chef-infra-client/*/*/version-manifest.json"
212
+ end
180
213
  else
181
- "/opt/#{options.product_name}/version-manifest.json"
214
+ if options.for_ps1?
215
+ "$env:systemdrive\\#{Mixlib::Install::Dist::OMNIBUS_WINDOWS_INSTALL_DIR}\\#{options.product_name}\\version-manifest.json"
216
+ else
217
+ "/opt/#{options.product_name}/version-manifest.json"
218
+ end
182
219
  end
183
220
 
184
221
  if File.exist? version_manifest_file
@@ -258,8 +295,25 @@ module Mixlib
258
295
  # ------------------
259
296
  # base_url [String]
260
297
  # url pointing to the omnitruck to be queried by the script.
298
+ # license_id [String]
299
+ # license ID for commercial or trial API access.
300
+ # If license_id starts with 'free-' or 'trial-', trial API defaults are enforced.
261
301
  #
262
302
  def self.install_sh(context = {})
303
+ # Apply trial API defaults if license_id indicates trial
304
+ if context[:license_id] && Mixlib::Install::Dist.trial_license?(context[:license_id])
305
+ # Warn and override if non-compliant values provided
306
+ if context[:channel] && context[:channel].to_s != "stable"
307
+ warn "WARNING: Trial API only supports 'stable' channel. Changing from '#{context[:channel]}' to 'stable'."
308
+ context[:channel] = "stable"
309
+ end
310
+
311
+ if context[:version] && !["latest", nil].include?(context[:version].to_s)
312
+ warn "WARNING: Trial API only supports 'latest' version. Changing from '#{context[:version]}' to 'latest'."
313
+ context[:version] = "latest"
314
+ end
315
+ end
316
+
263
317
  Mixlib::Install::Generator::Bourne.install_sh(context)
264
318
  end
265
319
 
@@ -269,8 +323,25 @@ module Mixlib
269
323
  # ------------------
270
324
  # base_url [String]
271
325
  # url pointing to the omnitruck to be queried by the script.
326
+ # license_id [String]
327
+ # license ID for commercial or trial API access.
328
+ # If license_id starts with 'free-' or 'trial-', trial API defaults are enforced.
272
329
  #
273
330
  def self.install_ps1(context = {})
331
+ # Apply trial API defaults if license_id indicates trial
332
+ if context[:license_id] && Mixlib::Install::Dist.trial_license?(context[:license_id])
333
+ # Warn and override if non-compliant values provided
334
+ if context[:channel] && context[:channel].to_s != "stable"
335
+ warn "WARNING: Trial API only supports 'stable' channel. Changing from '#{context[:channel]}' to 'stable'."
336
+ context[:channel] = "stable"
337
+ end
338
+
339
+ if context[:version] && !["latest", nil].include?(context[:version].to_s)
340
+ warn "WARNING: Trial API only supports 'latest' version. Changing from '#{context[:version]}' to 'latest'."
341
+ context[:version] = "latest"
342
+ end
343
+ end
344
+
274
345
  Mixlib::Install::Generator::PowerShell.install_ps1(context)
275
346
  end
276
347
  end
@@ -1,3 +1,6 @@
1
+ # Set strict error handling to ensure errors cause script failures
2
+ $ErrorActionPreference = 'Stop'
3
+
1
4
  Function Check-UpdateChef($root, $version) {
2
5
  if (-Not (Test-Path "$root\embedded")) { return $true }
3
6
  elseif ("$version" -eq "true") { return $false }
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mixlib-install
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.14.0
4
+ version: 3.16.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Thom May
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2026-01-14 00:00:00.000000000 Z
12
+ date: 2026-02-24 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: mixlib-shellout