add snmp power action delay

This patch adds a new snmp configuration value for power_action_delay.
It is a pause before power on and again after power off.

some of PDU equipment fails to perform correctly if commands are sent to quickly.
This patch add a configurable delay to correct that behavior.

Change-Id: I433af25f03e5baf96c0868a28b99be290adca5eb
This commit is contained in:
Chris Krelle 2021-09-17 15:24:22 -07:00 committed by Julia Kreger
parent de50ff2df5
commit 330693306a
4 changed files with 28 additions and 2 deletions

View File

@ -30,6 +30,16 @@ opts = [
min=0,
help=_('Time (in seconds) to sleep between when rebooting '
'(powering off and on again)')),
cfg.IntOpt('power_action_delay',
default=0,
min=0,
help=_('Time (in seconds) to sleep before power on and '
'after powering off. Which may be needed with some '
'PDUs as they may not honor toggling a specific power '
'port in rapid succession without a delay. This option '
'may be useful if the attached physical machine has a '
'substantial power supply to hold it over in the event '
'of a brownout.')),
cfg.FloatOpt('udp_transport_timeout',
default=1.0,
min=0.0,

View File

@ -511,6 +511,7 @@ class SNMPDriverBase(object, metaclass=abc.ABCMeta):
:raises: SNMPFailure if an SNMP request fails.
:returns: power state. One of :class:`ironic.common.states`.
"""
time.sleep(CONF.snmp.power_action_delay)
self._snmp_power_on()
return self._snmp_wait_for_state(states.POWER_ON)
@ -521,6 +522,7 @@ class SNMPDriverBase(object, metaclass=abc.ABCMeta):
:returns: power state. One of :class:`ironic.common.states`.
"""
self._snmp_power_off()
time.sleep(CONF.snmp.power_action_delay)
return self._snmp_wait_for_state(states.POWER_OFF)
def power_reset(self):

View File

@ -725,23 +725,29 @@ class SNMPDeviceDriverTestCase(db_base.DbTestCase):
driver.power_state)
mock_client.get.assert_called_once_with(driver._snmp_oid())
def test_power_on(self, mock_get_client):
@mock.patch.object(time, 'sleep', autospec=True)
def test_power_on(self, mock_sleep, mock_get_client):
# Ensure the device is powered on correctly
self.config(power_action_delay=1, group='snmp')
mock_client = mock_get_client.return_value
driver = snmp._get_driver(self.node)
mock_client.get.return_value = driver.value_power_on
pstate = driver.power_on()
mock_sleep.assert_called_once_with(1)
mock_client.set.assert_called_once_with(driver._snmp_oid(),
driver.value_power_on)
mock_client.get.assert_called_once_with(driver._snmp_oid())
self.assertEqual(states.POWER_ON, pstate)
def test_power_off(self, mock_get_client):
@mock.patch.object(time, 'sleep', autospec=True)
def test_power_off(self, mock_sleep, mock_get_client):
# Ensure the device is powered off correctly
self.config(power_action_delay=1, group='snmp')
mock_client = mock_get_client.return_value
driver = snmp._get_driver(self.node)
mock_client.get.return_value = driver.value_power_off
pstate = driver.power_off()
mock_sleep.assert_called_once_with(1)
mock_client.set.assert_called_once_with(driver._snmp_oid(),
driver.value_power_off)
mock_client.get.assert_called_once_with(driver._snmp_oid())

View File

@ -0,0 +1,8 @@
features:
- |
Adds new configuration option: ``[snmp]power_action_delay``
This option will add a delay in seconds before a snmp power on and after
power off. Which may be needed with some PDUs as they may not honor
toggling a specific power port in rapid succession without a delay.
This option may be useful if the attached physical machine has a
substantial power supply to hold it over in the event of a brownout.