Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions modules/bmc/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ def powercycle
raise NotImplementedError.new
end

def powerreset
raise NotImplementedError.new
end

def bootdevice
raise NotImplementedError.new
end
Expand Down
1 change: 1 addition & 0 deletions modules/bmc/bmc_plugin.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ class Plugin < Proxy::Plugin
capability 'shell'
capability 'ssh'
capability -> { Proxy::BMC::IPMI.providers_installed }
capability 'power_action_v2'

# Load IPMI to ensure the capabilities can be determined
load_classes do
Expand Down
4 changes: 4 additions & 0 deletions modules/bmc/redfish.rb
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,10 @@ def powercycle
poweraction('PowerCycle')
end

def powerreset
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks the same as the powercycle implementation. Is there a reason you can't use `cycle?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ekohl san

Thank you for your comment.
Because powercycle and power reset is different power action.

According to the Redfish specification (DSP2046_2025.1, p.513), these actions are different one and should use different reset type:

  • powercycle should use the PowerCycle
  • powerreset should use ForceRestart

The current implementation uses ForceRestart against powercycle and this is wrong implementation.
This is described in ticket #38498.
I plan to submit a separate PR to correct the powercycle behavior.

poweraction('ForceRestart')
end

def poweron
poweraction('On')
end
Expand Down
19 changes: 19 additions & 0 deletions test/bmc/bmc_api_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -583,6 +583,25 @@ def test_api_calls_redfish_provider_cycle
assert expect.once
end

def test_api_calls_ipmi_provider_reset
Rubyipmi.stubs(:is_provider_installed?).returns(true)
Proxy::BMC::IPMI.any_instance.stubs(:powerreset).returns(true)
Rack::Auth::Basic::Request.any_instance.stubs(:provided?).returns(true)
Rack::Auth::Basic::Request.any_instance.stubs(:basic?).returns(true)
Rack::Auth::Basic::Request.any_instance.stubs(:credentials).returns(['user', 'pass'])
put "/#{@host}/chassis/power/reset", { 'bmc_provider' => 'ipmitool' }
assert last_response.ok?, "Last response was not ok: #{last_response.body}"
data = JSON.parse(last_response.body)
assert_equal true, data["result"]
end

def test_api_calls_redfish_provider_reset
expect = Proxy::BMC::Redfish.any_instance.stubs(:powerreset)
test_args = { 'bmc_provider' => 'redfish' }
put "/#{@host}/chassis/power/reset", test_args
assert expect.once
end

def test_api_can_pass_options_in_body
Rubyipmi.stubs(:is_provider_installed?).returns(true)
args = { 'bmc_provider' => 'freeipmi', :options => {:driver => 'lan20', :privilege => 'USER'} }.to_json
Expand Down
7 changes: 7 additions & 0 deletions test/bmc/bmc_redfish_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,11 @@ def test_redfish_provider_cycle
to_return(status: 200, body: JSON.generate({}))
assert @bmc.powercycle
end

def test_redfish_provider_reset
stub_request(:post, "#{@protocol}://#{@host}#{SYSTEM_DATA['Actions']['#ComputerSystem.Reset']['target']}").
with(body: JSON.generate({"ResetType" => "ForceRestart"})).
to_return(status: 200, body: JSON.generate({}))
assert @bmc.powerreset
end
end
4 changes: 2 additions & 2 deletions test/bmc/integration_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ def test_features
mod = response['bmc']
refute_nil(mod)
assert_equal('running', mod['state'], Proxy::LogBuffer::Buffer.instance.info[:failed_modules][:bmc])
assert_equal(['redfish', 'shell', 'ssh'], mod['capabilities'])
assert_equal(['power_action_v2', 'redfish', 'shell', 'ssh'], mod['capabilities'])

assert_equal({}, mod['settings'])
end
Expand All @@ -32,7 +32,7 @@ def test_features_with_freeipmi_installed
mod = response['bmc']
refute_nil(mod)
assert_equal('running', mod['state'], Proxy::LogBuffer::Buffer.instance.info[:failed_modules][:bmc])
assert_equal(['freeipmi', 'redfish', 'shell', 'ssh'], mod['capabilities'])
assert_equal(['freeipmi', 'power_action_v2', 'redfish', 'shell', 'ssh'], mod['capabilities'])

assert_equal({}, mod['settings'])
end
Expand Down