Module: IDRAC::Power

Included in:
Client
Defined in:
lib/idrac/power.rb

Instance Method Summary collapse

Instance Method Details

#get_power_stateObject



136
137
138
139
140
141
142
143
144
# File 'lib/idrac/power.rb', line 136

def get_power_state
  # Login to iDRAC if needed
   unless @session_id
  
  # Get system information
  response = authenticated_request(:get, "/redfish/v1/Systems/System.Embedded.1?$select=PowerState")
  
  JSON.parse(handle_response(response))&.dig("PowerState")
end

#get_power_usage_wattsObject



146
147
148
149
150
151
152
153
# File 'lib/idrac/power.rb', line 146

def get_power_usage_watts
  # Login to iDRAC if needed
   unless @session_id
  
  response = authenticated_request(:get, "/redfish/v1/Chassis/System.Embedded.1/Power")
  
  JSON.parse(handle_response(response))&.dig("PowerControl", 0, "PowerConsumedWatts")&.to_f
end

#power_off(wait: true, kind: "ForceOff") ⇒ Object



62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/idrac/power.rb', line 62

def power_off(wait: true, kind: "ForceOff")
  # Login to iDRAC if needed
   unless @session_id
  
  puts "Powering off server...".light_cyan
  
  # Check current power state first
  current_state = get_power_state rescue "Unknown"
  if current_state == "Off"
    puts "Server is already powered OFF.".yellow
    return false
  end
  
  # Send power off command
  path = "/redfish/v1/Systems/System.Embedded.1/Actions/ComputerSystem.Reset"
  payload = { "ResetType" => kind }
  
  response = authenticated_request(:post, path, body: payload.to_json, headers: { 'Content-Type' => 'application/json' })
  
  if response.status == 409
    puts "Server is already powered OFF.".yellow
  else
    handle_response(response)
  end
  
  # Wait for power state change if requested
  if wait
    success = wait_for_power_state(target_state: "Off", tries: 6)
    
    # If graceful shutdown failed, try force shutdown
    if !success && kind != "ForceOff"
      return power_off(wait: wait, kind: "ForceOff")
    end
  end
  
  return true
end

#power_on(wait: true) ⇒ Object

Raises:



6
7
8
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
# File 'lib/idrac/power.rb', line 6

def power_on(wait: true)
  # Login to iDRAC if needed
   unless @session_id
  
  puts "Powering on server...".light_cyan
  
  # Check current power state first
  current_state = get_power_state rescue "Unknown"
  if current_state == "On"
    puts "Server is already powered ON.".yellow
    return false
  end
  
  # Send power on command (Reset with ResetType=On)
  path = "/redfish/v1/Systems/System.Embedded.1/Actions/ComputerSystem.Reset"
  payload = { "ResetType" => "On" }
  
  tries = 10
  while tries > 0
    response = authenticated_request(:post, path, body: payload.to_json, headers: { 'Content-Type' => 'application/json' })
    
    case response.status
    when 200, 204
      puts "Server power on command sent successfully".green
      break
    when 409
      begin
        error_data = JSON.parse(response.body)
        if error_data["error"] && error_data["error"]["@Message.ExtendedInfo"] &&
           error_data["error"]["@Message.ExtendedInfo"].any? { |m| m["Message"] =~ /Server is already powered ON/ }
          puts "Server is already powered ON.".yellow
          return false
        else
          raise Error, "Failed to power on: #{error_data.inspect}"
        end
      rescue JSON::ParserError
        raise Error, "Failed to power on with status 409: #{response.body}"
      end
    when 500
      puts "[iDRAC 500] Server is busy...".red
      tries -= 1
      puts "Retrying... #{tries}/10".yellow if tries > 0
      sleep 10
    else
      raise Error, "Unknown response code #{response.status}: #{response.body}"
    end
  end
  
  raise Error, "Failed to power on after 10 retries" if tries <= 0
  
  # Wait for power state change if requested
  wait_for_power_state(target_state: "On", tries: 10) if wait
  
  return true
end

#rebootObject



100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# File 'lib/idrac/power.rb', line 100

def reboot
  # Login to iDRAC if needed
   unless @session_id
  
  puts "Rebooting server...".light_cyan

  # Check current power state first
  current_state = get_power_state rescue "Unknown"
  if current_state == "Off"
    puts "Server is currently off, powering on instead of rebooting".yellow
    return power_on
  end
  
  # Send reboot command (Reset with ResetType=ForceRestart)
  path = "/redfish/v1/Systems/System.Embedded.1/Actions/ComputerSystem.Reset"
  payload = { "ResetType" => "ForceRestart" }
  
  response = authenticated_request(:post, path, body: payload.to_json, headers: { 'Content-Type' => 'application/json' })
  
  if response.status >= 200 && response.status < 300
    puts "Server reboot command sent successfully".green
    return true
  elsif response.status == 409
    error_data = JSON.parse(response.body) rescue nil
    puts "Received conflict (409) error from iDRAC: #{error_data.inspect}"
    # Try gracefulRestart as an alternative
    puts "Trying GracefulRestart instead...".yellow
    payload = { "ResetType" => "GracefulRestart" }
    response = authenticated_request(:post, path, body: payload.to_json, headers: { 'Content-Type' => 'application/json' })
    
    handle_response(response)
  else
    raise Error, "Failed to reboot server. Status code: #{response.status}"
  end
end