idrac 0.10.4 → 0.10.5
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/lib/idrac/firmware.rb +18 -1
- data/lib/idrac/firmware_catalog.rb +65 -12
- data/lib/idrac/version.rb +1 -1
- metadata +3 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9c4504dd010f1458b9705e73489d4d68ec18214ef13a5a5187dde3ed52812d1a
|
|
4
|
+
data.tar.gz: eb9ab621e77b1ad17ade9579b4286a7696f7f0bb9dc0761e8862446ee8f39963
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: af0824a2ceb96d5c89a2552277d24bdf754eb748a7644d756deb3864620130b005d3f5cefa1f0921d6617fd03aab79c31fd8d9de8b0716a2e3124a8916f1bde4
|
|
7
|
+
data.tar.gz: 3c85876b2e93b31bed8f8dd4a8ea2ab4ae851048a2767c18e319151b74748c797502971c0932b9e534150c95ce66c3bb9ff93e5194a0d6e37108714724363396
|
data/lib/idrac/firmware.rb
CHANGED
|
@@ -90,12 +90,29 @@ module IDRAC
|
|
|
90
90
|
# Id ("Installed-<componentID>-<version>"). Used to match DUPs by
|
|
91
91
|
# componentID rather than by ambiguous display name.
|
|
92
92
|
fw_id = component_data['Id'].to_s
|
|
93
|
-
|
|
93
|
+
oem = component_data.dig('Oem', 'Dell', 'DellSoftwareInventory') || {}
|
|
94
|
+
component_id = oem['ComponentID']
|
|
94
95
|
component_id ||= fw_id[/\A(?:Installed|Current|Previous|Available)-(\d+)-/, 1]
|
|
96
|
+
# The same Oem block carries the device's PCI IDs, and it carries
|
|
97
|
+
# them exactly where the componentID is missing. The iDRAC reports
|
|
98
|
+
# componentID "0" for firmware it did not install itself, so
|
|
99
|
+
# factory-flashed hardware is unmatchable by componentID: on an
|
|
100
|
+
# R6525, 13 of 23 entries report "0" (both LOMs, both ConnectX-6,
|
|
101
|
+
# the PERC, all 8 NVMe drives) and each publishes all four PCI
|
|
102
|
+
# IDs, while the 10 with a real componentID publish none. An
|
|
103
|
+
# entry gains its componentID once a DUP is applied — a LOM went
|
|
104
|
+
# from "Installed-0-22.91.5" to "Installed-108255-23.61.3" — so
|
|
105
|
+
# the unmatchable set is first-touch hardware, not an edge case.
|
|
106
|
+
# No PCIeDevices/PCIeFunctions lookup is needed to identify what
|
|
107
|
+
# the componentID cannot; see #updates_for_component.
|
|
95
108
|
firmware_inventory << {
|
|
96
109
|
name: component_data['Name'],
|
|
97
110
|
id: component_data['Id'],
|
|
98
111
|
component_id: component_id,
|
|
112
|
+
vendor_id: oem['VendorID'],
|
|
113
|
+
device_id: oem['DeviceID'],
|
|
114
|
+
sub_vendor_id: oem['SubVendorID'],
|
|
115
|
+
sub_device_id: oem['SubDeviceID'],
|
|
99
116
|
version: component_data['Version'],
|
|
100
117
|
updateable: component_data['Updateable'] || false,
|
|
101
118
|
status: component_data['Status'] ? component_data['Status']['State'] : 'Unknown'
|
|
@@ -172,6 +172,16 @@ module IDRAC
|
|
|
172
172
|
# picks wrong DUPs and iDRAC rejects them (RED097 / "not compatible").
|
|
173
173
|
component_ids = component.xpath(".//SupportedDevices/Device/@componentID").map(&:value).uniq
|
|
174
174
|
|
|
175
|
+
# The PCI IDs this DUP declares it can flash. The PCIe/storage half of
|
|
176
|
+
# the iDRAC inventory reports componentID "0" (measured on an R6525:
|
|
177
|
+
# every NIC, the PERC and all 8 NVMe drives), so componentID alone
|
|
178
|
+
# cannot match them and the old name heuristic guessed — it offered a
|
|
179
|
+
# Broadcom LOM an Intel package. PCI IDs are the identity both sides
|
|
180
|
+
# publish, so a cross-vendor match becomes impossible.
|
|
181
|
+
pci_ids = component.xpath(".//SupportedDevices/Device/PCIInfo").map { |p|
|
|
182
|
+
pci_key(p["vendorID"], p["deviceID"], p["subVendorID"], p["subDeviceID"])
|
|
183
|
+
}.compact.uniq
|
|
184
|
+
|
|
175
185
|
# Skip if missing essential information
|
|
176
186
|
next if name.empty? || path.empty? || version.empty?
|
|
177
187
|
|
|
@@ -191,6 +201,7 @@ module IDRAC
|
|
|
191
201
|
component_type: component_type,
|
|
192
202
|
category: category,
|
|
193
203
|
component_ids: component_ids,
|
|
204
|
+
pci_ids: pci_ids,
|
|
194
205
|
download_url: "https://downloads.dell.com/#{path}"
|
|
195
206
|
}
|
|
196
207
|
end
|
|
@@ -200,24 +211,66 @@ module IDRAC
|
|
|
200
211
|
updates
|
|
201
212
|
end
|
|
202
213
|
|
|
214
|
+
# Normalize one PCI ID quad to a comparable key. Dell publishes the same
|
|
215
|
+
# four IDs on both sides but spells them differently: the catalog writes
|
|
216
|
+
# bare uppercase hex (<PCIInfo vendorID="14E4" deviceID="165F"/>) while
|
|
217
|
+
# Redfish writes "0x790e". Returns nil unless all four are present, so a
|
|
218
|
+
# caller can tell "no PCI identity" from "PCI identity that matched
|
|
219
|
+
# nothing".
|
|
220
|
+
def pci_key(vendor_id, device_id, sub_vendor_id, sub_device_id)
|
|
221
|
+
parts = [vendor_id, device_id, sub_vendor_id, sub_device_id].map do |id|
|
|
222
|
+
id.to_s.strip.sub(/\A0x/i, "").upcase
|
|
223
|
+
end
|
|
224
|
+
return nil if parts.any?(&:empty?)
|
|
225
|
+
|
|
226
|
+
parts.map { |p| p.rjust(4, "0") }.join("/")
|
|
227
|
+
end
|
|
228
|
+
|
|
203
229
|
# Select the catalog DUPs that apply to one installed component (`fw` from
|
|
204
|
-
# the iDRAC inventory)
|
|
205
|
-
#
|
|
206
|
-
#
|
|
230
|
+
# the iDRAC inventory), most specific key first.
|
|
231
|
+
#
|
|
232
|
+
# 1. Dell componentID, when the inventory gives a real one. Exact and
|
|
233
|
+
# unambiguous; unchanged.
|
|
234
|
+
# 2. PCI IDs, for the entries that report componentID "0" — on an R6525
|
|
235
|
+
# that is every NIC, the PERC and every drive. The full quad first, then
|
|
236
|
+
# vendor+device if the catalog lists no package for that exact subsystem
|
|
237
|
+
# ID. Both tiers pin the vendor, which is the whole point: name matching
|
|
238
|
+
# reduced any NIC to the token "NIC" and any RAID device to "PERC", then
|
|
239
|
+
# substring-matched the DUP's package name, so a "Broadcom NetXtreme
|
|
240
|
+
# Gigabit Ethernet" LOM was offered "Intel NIC Family Version 25.0.0
|
|
241
|
+
# Firmware for Intel I350 and X550 Adapters" — wrong vendor — and a
|
|
242
|
+
# "PERC H755N Front" was offered the H355 package. It was also unstable:
|
|
243
|
+
# the same tool offered two identical PERCs different packages, because
|
|
244
|
+
# the winner depended on catalog order.
|
|
245
|
+
# 3. The name heuristic, only when the inventory gave neither key. When PCI
|
|
246
|
+
# IDs are present they are the answer: if nothing matches them, the
|
|
247
|
+
# catalog has no package for this device, and guessing by name is how
|
|
248
|
+
# the wrong-vendor DUPs got offered in the first place.
|
|
207
249
|
def updates_for_component(catalog_updates, fw)
|
|
208
250
|
component_id = fw[:component_id]
|
|
209
251
|
if component_id && component_id != "0"
|
|
210
|
-
catalog_updates.select { |u| Array(u[:component_ids]).include?(component_id) }
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
252
|
+
return catalog_updates.select { |u| Array(u[:component_ids]).include?(component_id) }
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
key = pci_key(fw[:vendor_id], fw[:device_id], fw[:sub_vendor_id], fw[:sub_device_id])
|
|
256
|
+
if key
|
|
257
|
+
exact = catalog_updates.select { |u| Array(u[:pci_ids]).include?(key) }
|
|
258
|
+
return exact if exact.any?
|
|
259
|
+
|
|
260
|
+
chip = key.split("/").first(2).join("/")
|
|
261
|
+
return catalog_updates.select do |u|
|
|
262
|
+
Array(u[:pci_ids]).any? { |k| k.start_with?("#{chip}/") }
|
|
219
263
|
end
|
|
220
264
|
end
|
|
265
|
+
|
|
266
|
+
name = fw[:name] || ""
|
|
267
|
+
ids = extract_identifiers(name)
|
|
268
|
+
catalog_updates.select do |u|
|
|
269
|
+
un = u[:name] || ""
|
|
270
|
+
ids.any? { |id| un.downcase.include?(id.downcase) } ||
|
|
271
|
+
un.downcase.include?(name.downcase) ||
|
|
272
|
+
name.downcase.include?(un.downcase)
|
|
273
|
+
end
|
|
221
274
|
end
|
|
222
275
|
|
|
223
276
|
# Sortable key for a Dell version string (e.g. "25.5.9.0001", "22.00.6").
|
data/lib/idrac/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: idrac
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.10.
|
|
4
|
+
version: 0.10.5
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Jonathan Siegel
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
13
|
name: httparty
|
|
@@ -282,7 +281,6 @@ licenses:
|
|
|
282
281
|
metadata:
|
|
283
282
|
homepage_uri: https://github.com/buildio/idrac
|
|
284
283
|
source_code_uri: https://github.com/buildio/idrac
|
|
285
|
-
post_install_message:
|
|
286
284
|
rdoc_options: []
|
|
287
285
|
require_paths:
|
|
288
286
|
- lib
|
|
@@ -297,8 +295,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
297
295
|
- !ruby/object:Gem::Version
|
|
298
296
|
version: '0'
|
|
299
297
|
requirements: []
|
|
300
|
-
rubygems_version: 3.
|
|
301
|
-
signing_key:
|
|
298
|
+
rubygems_version: 3.6.9
|
|
302
299
|
specification_version: 4
|
|
303
300
|
summary: API Client for Dell iDRAC
|
|
304
301
|
test_files: []
|