idrac 0.10.7 → 0.11.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bfa684ed67c2db2f200633f5db13d173a30f49c67b07b05da83844708bdacfa4
4
- data.tar.gz: 1308339f369f5d9ec0c028f64effac7d43e39cc93dcfad88e2d5d88a6b954f53
3
+ metadata.gz: f24b2229f786a83cbdcaf74c4511953d92b4081194aec3885e825a83426a8ff7
4
+ data.tar.gz: d5b0b13b8f51b43936e01601e031617b2704bd5d09b4fffcb8c99f35864fe130
5
5
  SHA512:
6
- metadata.gz: abc37992c28ab713b5960b51144bcda9f3d80ed197e7a35284c5509392f82b258072bfce2b3a3b1c3d30956b2996459b42a18582de2896d61a1e3df6851a2946
7
- data.tar.gz: 65219a49a799565089f2bb59722314ba3433a2c5dc17c035d92a2bf0d6a1712b4c964f0489fa0d1a5935a65390ed9d1fbd4c99a7832d055b11730739d5068f6a
6
+ metadata.gz: 3d71bfb2ca893fed352c34c4726a9c76bee97c9978933f3d0928e48f8ba4a0a12fe5b3045fdc3f7a33c8ab107156e6b71d14275ca377fb93fb146a64f7be6525
7
+ data.tar.gz: aca2e4227201a36da2f657bfacbe2109c95ae63ddccca6a85f3c1aee84f08180987cf1b50e9f623214466c6d46701920f56a2182a74ba2616e61bfa263614b04
data/README.md CHANGED
@@ -36,6 +36,19 @@ Or install it yourself as:
36
36
 
37
37
  $ gem install idrac
38
38
 
39
+ ## Compatibility
40
+
41
+ `activesupport` below 8.1 and `json` 3 cannot be used together: activesupport's
42
+ JSON encoder calls `JSON.generate(..., quirks_mode: true)`, and json 3 removed
43
+ that keyword, so any `hash.to_json` raises `ArgumentError: unknown keyword:
44
+ quirks_mode`. This is not specific to this gem — it bites anything that loads
45
+ `active_support/core_ext` — but idrac depends on activesupport, so pick one of:
46
+
47
+ - activesupport >= 8.1 with json 3, or
48
+ - activesupport 7.x with json 2.
49
+
50
+ CI covers both ends.
51
+
39
52
  ## Usage
40
53
 
41
54
  ### Command Line Interface
data/lib/idrac/boot.rb CHANGED
@@ -140,7 +140,8 @@ module IDRAC
140
140
  end
141
141
 
142
142
  # Set boot override for next boot
143
- def set_boot_override(target, enabled: "Once", mode: nil)
143
+ def set_boot_override(target, persistence: nil, mode: nil)
144
+ persistence = "Once" unless persistence
144
145
  # Validate target against allowed values
145
146
  boot_data = boot
146
147
  valid_targets = boot_data["allowed_override_targets"]
@@ -150,11 +151,11 @@ module IDRAC
150
151
  raise Error, "Invalid boot target: #{target}"
151
152
  end
152
153
 
153
- debug "Setting boot override to #{target} (#{enabled})...", 1, :yellow
154
+ debug "Setting boot override to #{target} (#{persistence})...", 1, :yellow
154
155
 
155
156
  body = {
156
157
  "Boot" => {
157
- "BootSourceOverrideEnabled" => enabled, # Disabled/Once/Continuous
158
+ "BootSourceOverrideEnabled" => persistence, # Disabled/Once/Continuous
158
159
  "BootSourceOverrideTarget" => target # None/Pxe/Hdd/Cd/etc
159
160
  }
160
161
  }
@@ -225,24 +226,24 @@ module IDRAC
225
226
  end
226
227
 
227
228
  # Convenience methods for common boot targets
228
- def boot_to_pxe(enabled: "Once", mode: nil)
229
- set_boot_override("Pxe", enabled: enabled, mode: mode)
229
+ def boot_to_pxe(persistence: nil, mode: nil)
230
+ set_boot_override("Pxe", persistence: persistence, mode: mode)
230
231
  end
231
232
 
232
- def boot_to_disk(enabled: "Once", mode: nil)
233
- set_boot_override("Hdd", enabled: enabled, mode: mode)
233
+ def boot_to_disk(persistence: nil, mode: nil)
234
+ set_boot_override("Hdd", persistence: persistence, mode: mode)
234
235
  end
235
236
 
236
- def boot_to_cd(enabled: "Once", mode: nil)
237
- set_boot_override("Cd", enabled: enabled, mode: mode)
237
+ def boot_to_cd(persistence: nil, mode: nil)
238
+ set_boot_override("Cd", persistence: persistence, mode: mode)
238
239
  end
239
240
 
240
- def boot_to_usb(enabled: "Once", mode: nil)
241
- set_boot_override("Usb", enabled: enabled, mode: mode)
241
+ def boot_to_usb(persistence: nil, mode: nil)
242
+ set_boot_override("Usb", persistence: persistence, mode: mode)
242
243
  end
243
244
 
244
- def boot_to_bios_setup(enabled: "Once", mode: nil)
245
- set_boot_override("BiosSetup", enabled: enabled, mode: mode)
245
+ def boot_to_bios_setup(persistence: nil, mode: nil)
246
+ set_boot_override("BiosSetup", persistence: persistence, mode: mode)
246
247
  end
247
248
 
248
249
  private
@@ -590,11 +590,10 @@ module IDRAC
590
590
  end
591
591
 
592
592
  # Construct the firmware URI from the upload response
593
- image_uri = if firmware_id
594
- "#{http_push_uri}/#{firmware_id}"
595
- else
596
- upload_response.headers['Location'] || http_push_uri
597
- end
593
+ # Prefer @odata.id from response body, then Location header, then constructed path
594
+ image_uri = upload_data&.dig('@odata.id') ||
595
+ upload_response.headers['Location'] ||
596
+ (firmware_id ? "#{http_push_uri}/#{firmware_id}" : http_push_uri)
598
597
 
599
598
  # Check if Dell OEM Install action is available (iDRAC8)
600
599
  # This is more reliable than SimpleUpdate on older iDRACs
@@ -604,9 +603,10 @@ module IDRAC
604
603
  if dell_install_target
605
604
  puts "Using Dell OEM Install action (iDRAC8)...".light_cyan
606
605
  puts "Firmware URI: #{image_uri}".light_cyan
606
+ # iDRAC8 DellUpdateService.Install expects @odata.id URIs
607
607
  install_payload = {
608
608
  "SoftwareIdentityURIs" => [image_uri],
609
- "InstallUpon" => "Now"
609
+ "InstallUpon" => "NowAndReboot"
610
610
  }
611
611
  update_response = client.authenticated_request(
612
612
  :post,
data/lib/idrac/utility.rb CHANGED
@@ -194,11 +194,28 @@ module IDRAC
194
194
  # @param data_selector_values [Array] Array of log types to include (optional)
195
195
  # @param wait_timeout [Integer] Maximum time to wait for generation in seconds (default: 600)
196
196
  # @return [String, nil] Path to downloaded file or nil if failed
197
- def generate_and_download_tsr(output_file: nil, data_selector_values: nil, wait_timeout: 600)
197
+ def generate_and_download_tsr(output_file: nil, data_selector_values: nil, accept_eula: false, wait_timeout: 600)
198
198
  debug "Starting TSR generation and download process...", 1
199
-
199
+
200
200
  output_file ||= "supportassist_#{@host}_#{Time.now.strftime('%Y%m%d_%H%M%S')}.zip"
201
-
201
+
202
+ # Accept the EULA up front when asked -- generate_tsr_logs only errors out otherwise.
203
+ accept_supportassist_eula if accept_eula
204
+
205
+ # Wait out a collection that is still running server-side. The iDRAC allows only one
206
+ # SupportAssist collection at a time, so generating now would fail with "a SupportAssist job
207
+ # is already running". Give up after wait_timeout seconds and fail the same way the rest of
208
+ # this method does (return nil).
209
+ wait_deadline = Time.now + wait_timeout
210
+ while supportassist_collection_running?
211
+ if Time.now > wait_deadline
212
+ debug "Timed out after #{wait_timeout}s waiting for a running SupportAssist collection to finish", 1, :red
213
+ return nil
214
+ end
215
+ debug "A SupportAssist collection is already running; waiting...", 1, :yellow
216
+ sleep 15
217
+ end
218
+
202
219
  # First, generate the TSR
203
220
  result = generate_tsr_logs(data_selector_values: data_selector_values)
204
221
 
@@ -267,8 +284,9 @@ module IDRAC
267
284
  collection_in_progress: false
268
285
  }
269
286
 
270
- # Check if there's an active collection job
271
- jobs_response = authenticated_request(:get, "/redfish/v1/Managers/iDRAC.Embedded.1/Jobs")
287
+ # Check if there's an active collection job. The list must be expanded, otherwise each
288
+ # Members entry is a bare @odata.id with no Name/JobState and the check never fires.
289
+ jobs_response = authenticated_request(:get, "/redfish/v1/Managers/iDRAC.Embedded.1/Jobs?$expand=*($levels=1)")
272
290
  if jobs_response.status == 200
273
291
  jobs_data = JSON.parse(jobs_response.body)
274
292
  if jobs_data["Members"]
@@ -294,6 +312,25 @@ module IDRAC
294
312
  { available: false, error: e.message }
295
313
  end
296
314
 
315
+ # True when a SupportAssist Collection job is still running server-side. Reads the expanded Dell
316
+ # Jobs list (bare @odata.id members carry no Name/JobState) and treats a job as running when its
317
+ # Name matches SupportAssist Collection, its JobState is not terminal, and it is below 100%.
318
+ # Use this to wait out a prior collection before starting a new one (the iDRAC allows only one).
319
+ def supportassist_collection_running?
320
+ response = authenticated_request(:get, "/redfish/v1/Managers/iDRAC.Embedded.1/Jobs?$expand=*($levels=1)")
321
+ return false unless response.status == 200
322
+
323
+ members = JSON.parse(response.body)["Members"] || []
324
+ members.any? do |job|
325
+ job["Name"].to_s =~ /SupportAssist Collection/i &&
326
+ !IDRAC::Firmware::TERMINAL_JOB_STATES.include?(job["JobState"]) &&
327
+ job["PercentComplete"].to_i < 100
328
+ end
329
+ rescue => e
330
+ debug "Error checking SupportAssist collection state: #{e.message}", 1, :red
331
+ false
332
+ end
333
+
297
334
  # Check SupportAssist EULA status
298
335
  # @return [Hash] EULA status information
299
336
  def supportassist_eula_status
data/lib/idrac/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module IDRAC
4
- VERSION = "0.10.7"
4
+ VERSION = "0.11.1"
5
5
  end
metadata CHANGED
@@ -1,13 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: idrac
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.7
4
+ version: 0.11.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jonathan Siegel
8
+ autorequire:
8
9
  bindir: bin
9
10
  cert_chain: []
10
- date: 1980-01-02 00:00:00.000000000 Z
11
+ date: 2026-10-04 00:00:00.000000000 Z
11
12
  dependencies:
12
13
  - !ruby/object:Gem::Dependency
13
14
  name: httparty
@@ -281,6 +282,7 @@ licenses:
281
282
  metadata:
282
283
  homepage_uri: https://github.com/buildio/idrac
283
284
  source_code_uri: https://github.com/buildio/idrac
285
+ post_install_message:
284
286
  rdoc_options: []
285
287
  require_paths:
286
288
  - lib
@@ -295,7 +297,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
295
297
  - !ruby/object:Gem::Version
296
298
  version: '0'
297
299
  requirements: []
298
- rubygems_version: 3.6.9
300
+ rubygems_version: 3.5.16
301
+ signing_key:
299
302
  specification_version: 4
300
303
  summary: API Client for Dell iDRAC
301
304
  test_files: []