Add reboot_delay option to snmp driver

When node is powered off via "soft off" (during deploy with agent for
example) a off/on cycle is required on external power controller.
If pause between off and on is too short node's hardware unable
to detect external power loss.
This patch adds new 'reboot_delay' config option. Some of
SNMP-enabled power controller have own value for this pause
(configurable or hardcoded). So default value of Ironic option
is "0" for keeping of current behavior.

Closes-Bug: #1506860
Change-Id: I91617f1a296ad38ff4c31872e6e3ac20f8619a38
This commit is contained in:
Yuriy Zveryanskyy 2015-10-13 15:16:21 +03:00
parent 5ca6e64e33
commit bdcf98a3d9
3 changed files with 33 additions and 1 deletions

View File

@ -1810,6 +1810,10 @@
# value)
#power_timeout=10
# Time (in seconds) to sleep between when rebooting (powering
# off and on again) (integer value)
#reboot_delay=0
[ssh]

View File

@ -28,6 +28,7 @@ models.
"""
import abc
import time
from oslo_config import cfg
from oslo_log import log as logging
@ -55,7 +56,14 @@ else:
opts = [
cfg.IntOpt('power_timeout',
default=10,
help=_('Seconds to wait for power action to be completed'))
help=_('Seconds to wait for power action to be completed')),
# NOTE(yuriyz): some of SNMP-enabled hardware have own options for pause
# between off and on. This option guarantees minimal value.
cfg.IntOpt('reboot_delay',
default=0,
min=0,
help=_('Time (in seconds) to sleep between when rebooting '
'(powering off and on again)'))
]
LOG = logging.getLogger(__name__)
@ -310,6 +318,7 @@ class SNMPDriverBase(object):
power_result = self.power_off()
if power_result != states.POWER_OFF:
return states.ERROR
time.sleep(CONF.snmp.reboot_delay)
power_result = self.power_on()
if power_result != states.POWER_ON:
return states.ERROR

View File

@ -20,6 +20,8 @@
"""Test class for SNMP power driver module."""
import time
import mock
from oslo_config import cfg
from pysnmp.entity.rfc3413.oneliner import cmdgen
@ -754,6 +756,23 @@ class SNMPDeviceDriverTestCase(db_base.DbTestCase):
mock_client.set.assert_has_calls(calls)
mock_client.get.assert_called_once_with(driver._snmp_oid())
@mock.patch.object(time, 'sleep', autospec=True)
def test_power_reset_delay_option(self, mock_sleep, mock_get_client):
# Test for 'reboot_delay' config option
self.config(reboot_delay=5, group='snmp')
mock_client = mock_get_client.return_value
driver = snmp._get_driver(self.node)
mock_client.get.side_effect = [driver.value_power_off,
driver.value_power_on]
pstate = driver.power_reset()
calls = [mock.call(driver._snmp_oid(), driver.value_power_off),
mock.call(driver._snmp_oid(), driver.value_power_on)]
mock_client.set.assert_has_calls(calls)
calls = [mock.call(driver._snmp_oid())] * 2
mock_client.get.assert_has_calls(calls)
self.assertEqual(states.POWER_ON, pstate)
mock_sleep.assert_called_once_with(5)
def test_power_reset_on_snmp_get_failure(self, mock_get_client):
# Ensure SNMP failure exceptions raised during a reset power on get
# operation are propagated