Module: Supermicro::Boot
- Included in:
- Client
- Defined in:
- lib/supermicro/boot.rb
Instance Method Summary collapse
-
#boot ⇒ Object
Shorter alias for convenience.
-
#boot_config ⇒ Object
Get boot configuration with snake_case fields.
-
#boot_options ⇒ Object
Get boot options collection (detailed boot devices) with snake_case.
-
#boot_raw ⇒ Object
Get raw Redfish boot data (CamelCase).
- #boot_to_bios_setup(enabled: "Once", mode: nil) ⇒ Object
- #boot_to_cd(enabled: "Once", mode: "UEFI") ⇒ Object
- #boot_to_disk(enabled: "Once", mode: nil) ⇒ Object
-
#boot_to_pxe(enabled: "Once", mode: nil) ⇒ Object
Convenience methods for common boot targets.
- #boot_to_usb(enabled: "Once", mode: nil) ⇒ Object
- #clear_boot_override ⇒ Object
- #configure_boot_settings(persistence: nil, mode: nil) ⇒ Object
-
#get_boot_devices ⇒ Object
Alias for backwards compatibility.
- #set_boot_order(devices) ⇒ Object
-
#set_boot_order_hd_first ⇒ Object
Set boot order with hard drive first.
-
#set_boot_override(target, enabled: "Once", mode: nil) ⇒ Object
Set boot override for next boot.
-
#set_one_time_boot_to_virtual_media ⇒ Object
Set one-time boot to virtual media (CD).
Instance Method Details
#boot ⇒ Object
Shorter alias for convenience
76 77 78 |
# File 'lib/supermicro/boot.rb', line 76 def boot boot_config end |
#boot_config ⇒ Object
Get boot configuration with snake_case fields
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
# File 'lib/supermicro/boot.rb', line 9 def boot_config response = authenticated_request(:get, "/redfish/v1/Systems/1") if response.status == 200 begin data = JSON.parse(response.body) boot_data = data["Boot"] || {} # Get boot options for resolving references = {} begin = .each do |opt| [opt["id"]] = opt["display_name"] || opt["name"] end rescue # Ignore errors fetching boot options end # Build boot order with resolved names boot_order = (boot_data["BootOrder"] || []).map do |ref| { "reference" => ref, "name" => [ref] || ref } end # Return hash with snake_case fields { # Boot override settings (for one-time or continuous boot) "boot_source_override_enabled" => boot_data["BootSourceOverrideEnabled"], # Disabled/Once/Continuous "boot_source_override_target" => boot_data["BootSourceOverrideTarget"], # None/Pxe/Hdd/Cd/etc "boot_source_override_mode" => boot_data["BootSourceOverrideMode"], # UEFI/Legacy "allowed_override_targets" => boot_data["[email protected]"] || [], # Permanent boot order with resolved names "boot_order" => boot_order, # [{reference: "Boot0002", name: "PXE IPv4"}] "boot_order_refs" => boot_data["BootOrder"] || [], # Raw references for set_boot_order # Supermicro specific fields "boot_next" => boot_data["BootNext"], "http_boot_uri" => boot_data["HttpBootUri"], # References to other resources "boot_options_uri" => boot_data.dig("BootOptions", "@odata.id") }.compact rescue JSON::ParserError raise Error, "Failed to parse boot response: #{response.body}" end else raise Error, "Failed to get boot configuration. Status code: #{response.status}" end end |
#boot_options ⇒ Object
Get boot options collection (detailed boot devices) with snake_case
197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 |
# File 'lib/supermicro/boot.rb', line 197 def response = authenticated_request(:get, "/redfish/v1/Systems/1/BootOptions") if response.status == 200 begin data = JSON.parse(response.body) = [] # Supermicro doesn't support $expand, fetch each individually data["Members"]&.each do |member| if member["@odata.id"] opt_response = authenticated_request(:get, member["@odata.id"]) if opt_response.status == 200 opt_data = JSON.parse(opt_response.body) << { "id" => opt_data["Id"], # Boot0002 "boot_option_reference" => opt_data["BootOptionReference"], # Boot0002 "display_name" => opt_data["DisplayName"], # "UEFI PXE IPv4: Intel..." "name" => opt_data["DisplayName"] || opt_data["Name"], # Alias for display_name "enabled" => opt_data["BootOptionEnabled"], # true/false "uefi_device_path" => opt_data["UefiDevicePath"], # UEFI device path if present "description" => opt_data["Description"] }.compact end end end rescue JSON::ParserError raise Error, "Failed to parse boot options response: #{response.body}" end else [] end end |
#boot_raw ⇒ Object
Get raw Redfish boot data (CamelCase)
64 65 66 67 68 69 70 71 72 73 |
# File 'lib/supermicro/boot.rb', line 64 def boot_raw response = authenticated_request(:get, "/redfish/v1/Systems/1") if response.status == 200 data = JSON.parse(response.body) data["Boot"] || {} else raise Error, "Failed to get boot configuration. Status code: #{response.status}" end end |
#boot_to_bios_setup(enabled: "Once", mode: nil) ⇒ Object
256 257 258 |
# File 'lib/supermicro/boot.rb', line 256 def boot_to_bios_setup(enabled: "Once", mode: nil) set_boot_override("BiosSetup", enabled: enabled, mode: mode) end |
#boot_to_cd(enabled: "Once", mode: "UEFI") ⇒ Object
247 248 249 250 |
# File 'lib/supermicro/boot.rb', line 247 def boot_to_cd(enabled: "Once", mode: "UEFI") # Always use UEFI mode for CD boot since we're booting UEFI media set_boot_override("Cd", enabled: enabled, mode: mode) end |
#boot_to_disk(enabled: "Once", mode: nil) ⇒ Object
243 244 245 |
# File 'lib/supermicro/boot.rb', line 243 def boot_to_disk(enabled: "Once", mode: nil) set_boot_override("Hdd", enabled: enabled, mode: mode) end |
#boot_to_pxe(enabled: "Once", mode: nil) ⇒ Object
Convenience methods for common boot targets
239 240 241 |
# File 'lib/supermicro/boot.rb', line 239 def boot_to_pxe(enabled: "Once", mode: nil) set_boot_override("Pxe", enabled: enabled, mode: mode) end |
#boot_to_usb(enabled: "Once", mode: nil) ⇒ Object
252 253 254 |
# File 'lib/supermicro/boot.rb', line 252 def boot_to_usb(enabled: "Once", mode: nil) set_boot_override("Usb", enabled: enabled, mode: mode) end |
#clear_boot_override ⇒ Object
148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 |
# File 'lib/supermicro/boot.rb', line 148 def clear_boot_override puts "Clearing boot override...".yellow body = { "Boot" => { "BootSourceOverrideEnabled" => "Disabled" } } response = authenticated_request( :patch, "/redfish/v1/Systems/1", body: body.to_json, headers: { 'Content-Type': 'application/json' } ) if response.status.between?(200, 299) puts "Boot override cleared successfully.".green return true else raise Error, "Failed to clear boot override: #{response.status} - #{response.body}" end end |
#configure_boot_settings(persistence: nil, mode: nil) ⇒ Object
118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 |
# File 'lib/supermicro/boot.rb', line 118 def configure_boot_settings(persistence: nil, mode: nil) debug "Configuring boot settings..." body = { "Boot" => {} } if persistence body["Boot"]["BootSourceOverrideEnabled"] = persistence end if mode body["Boot"]["BootSourceOverrideMode"] = mode end return false if body["Boot"].empty? response = authenticated_request( :patch, "/redfish/v1/Systems/1", body: body.to_json, headers: { 'Content-Type': 'application/json' } ) if response.status.between?(200, 299) debug "Boot settings configured successfully." return true else raise Error, "Failed to configure boot settings: #{response.status} - #{response.body}" end end |
#get_boot_devices ⇒ Object
Alias for backwards compatibility
234 235 236 |
# File 'lib/supermicro/boot.rb', line 234 def get_boot_devices end |
#set_boot_order(devices) ⇒ Object
172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 |
# File 'lib/supermicro/boot.rb', line 172 def set_boot_order(devices) puts "Setting boot order...".yellow body = { "Boot" => { "BootOrder" => devices } } response = authenticated_request( :patch, "/redfish/v1/Systems/1", body: body.to_json, headers: { 'Content-Type': 'application/json' } ) if response.status.between?(200, 299) puts "Boot order set successfully.".green return true else raise Error, "Failed to set boot order: #{response.status} - #{response.body}" end end |
#set_boot_order_hd_first ⇒ Object
Set boot order with hard drive first
304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 |
# File 'lib/supermicro/boot.rb', line 304 def set_boot_order_hd_first debug "Configuring system to boot from HD after OS installation...", 1, :yellow # First check if there's actually a hard disk present boot_opts = hd_option = boot_opts.find { |opt| opt["display_name"] =~ /Hard Drive|HDD|SATA|NVMe|SSD|RAID|UEFI OS/i } if hd_option # HD exists, set it as first in boot order = boot_opts.select { |opt| opt["enabled"] && opt["id"] != hd_option["id"] }.sort_by { |opt| opt["id"] } new_order = [hd_option["id"]] + .map { |opt| opt["id"] } debug "Setting boot order with HD first: #{new_order.join(', ')}", 2, :yellow result = set_boot_order(new_order) if result debug "Boot order set with HD first", 1, :green end else # No HD yet - this is expected before OS install # DO NOT clear boot overrides as that would clear one-time boot settings # Just log that HD will be available after OS install debug "No HD found yet (expected before OS install)", 1, :yellow debug "HD will become available after OS installation", 1, :yellow debug "System will boot from HD naturally after the one-time virtual media boot", 1, :yellow result = true # Return success since this is expected end result end |
#set_boot_override(target, enabled: "Once", mode: nil) ⇒ Object
Set boot override for next boot
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
# File 'lib/supermicro/boot.rb', line 81 def set_boot_override(target, enabled: "Once", mode: nil) # Validate target against allowed values boot_data = boot valid_targets = boot_data["allowed_override_targets"] if valid_targets && !valid_targets.include?(target) debug "Invalid boot target '#{target}'. Allowed values: #{valid_targets.join(', ')}" raise Error, "Invalid boot target: #{target}" end debug "Setting boot override to #{target} (#{enabled})..." body = { "Boot" => { "BootSourceOverrideEnabled" => enabled, # Disabled/Once/Continuous "BootSourceOverrideTarget" => target # None/Pxe/Hdd/Cd/etc } } # Add boot mode if specified body["Boot"]["BootSourceOverrideMode"] = mode if mode response = authenticated_request( :patch, "/redfish/v1/Systems/1", body: body.to_json, headers: { 'Content-Type': 'application/json' } ) if response.status.between?(200, 299) debug "Boot override set successfully." return true else raise Error, "Failed to set boot override: #{response.status} - #{response.body}" end end |
#set_one_time_boot_to_virtual_media ⇒ Object
Set one-time boot to virtual media (CD)
261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 |
# File 'lib/supermicro/boot.rb', line 261 def set_one_time_boot_to_virtual_media debug "Setting one-time boot to virtual media...", 1, :yellow # Supermicro often needs virtual media remounted to ensure it's properly recognized # Check if virtual media is already mounted and remount if so begin require_relative 'virtual_media' vm_status = virtual_media_status if vm_status && vm_status["Inserted"] current_image = vm_status["Image"] if current_image debug "Remounting virtual media to ensure fresh connection...", 1, :yellow # Eject current media eject_virtual_media rescue nil sleep 2 # Re-insert the media insert_virtual_media(current_image) sleep 3 debug "Virtual media remounted: #{current_image}", 1, :green end end rescue => e debug "Note: Could not remount virtual media: #{e.}", 2, :yellow end # Now try the standard boot override - this often works after remount result = boot_to_cd(enabled: "Once") if result debug "One-time boot to virtual media configured", 1, :green debug "System will boot from virtual CD on next restart", 1, :green else debug "Failed to set boot override, may need manual intervention", 1, :red end result end |