diff --git a/etc/ironic/ironic.conf.sample b/etc/ironic/ironic.conf.sample index 7490edadbb..c1362dbf5a 100644 --- a/etc/ironic/ironic.conf.sample +++ b/etc/ironic/ironic.conf.sample @@ -166,7 +166,11 @@ # The name of a logging configuration file. This file is # appended to any existing logging configuration files. For # details about logging configuration files, see the Python -# logging module documentation. (string value) +# logging module documentation. Note that when logging +# configuration files are used then all logging configuration +# is set in the configuration file and other logging +# configuration options are ignored (for example, log_format). +# (string value) # Deprecated group/name - [DEFAULT]/log_config #log_config_append= @@ -174,38 +178,54 @@ # which may use any of the available logging.LogRecord # attributes. This option is deprecated. Please use # logging_context_format_string and -# logging_default_format_string instead. (string value) +# logging_default_format_string instead. This option is +# ignored if log_config_append is set. (string value) #log_format= # Format string for %%(asctime)s in log records. Default: -# %(default)s . (string value) +# %(default)s . This option is ignored if log_config_append is +# set. (string value) #log_date_format=%Y-%m-%d %H:%M:%S # (Optional) Name of log file to output to. If no default is -# set, logging will go to stdout. (string value) +# set, logging will go to stdout. This option is ignored if +# log_config_append is set. (string value) # Deprecated group/name - [DEFAULT]/logfile #log_file= # (Optional) The base directory used for relative --log-file -# paths. (string value) +# paths. This option is ignored if log_config_append is set. +# (string value) # Deprecated group/name - [DEFAULT]/logdir #log_dir= +# (Optional) Uses logging handler designed to watch file +# system. When log file is moved or removed this handler will +# open a new log file with specified path instantaneously. It +# makes sense only if log-file option is specified and Linux +# platform is used. This option is ignored if +# log_config_append is set. (boolean value) +#watch_log_file=false + # Use syslog for logging. Existing syslog format is DEPRECATED -# and will be changed later to honor RFC5424. (boolean value) +# and will be changed later to honor RFC5424. This option is +# ignored if log_config_append is set. (boolean value) #use_syslog=false # (Optional) Enables or disables syslog rfc5424 format for # logging. If enabled, prefixes the MSG part of the syslog # message with APP-NAME (RFC5424). The format without the APP- # NAME is deprecated in Kilo, and will be removed in Mitaka, -# along with this option. (boolean value) +# along with this option. This option is ignored if +# log_config_append is set. (boolean value) #use_syslog_rfc_format=true -# Syslog facility to receive log lines. (string value) +# Syslog facility to receive log lines. This option is ignored +# if log_config_append is set. (string value) #syslog_log_facility=LOG_USER -# Log output to standard error. (boolean value) +# Log output to standard error. This option is ignored if +# log_config_append is set. (boolean value) #use_stderr=true # Format string to use for log messages with context. (string @@ -224,7 +244,8 @@ # (string value) #logging_exception_prefix=%(asctime)s.%(msecs)03d %(process)d ERROR %(name)s %(instance)s -# List of logger=LEVEL pairs. (list value) +# List of logger=LEVEL pairs. This option is ignored if +# log_config_append is set. (list value) #default_log_levels=amqp=WARN,amqplib=WARN,boto=WARN,qpid=WARN,sqlalchemy=WARN,suds=INFO,oslo.messaging=INFO,iso8601=WARN,requests.packages.urllib3.connectionpool=WARN,urllib3.connectionpool=WARN,websocket=WARN,requests.packages.urllib3.util.retry=WARN,urllib3.util.retry=WARN,keystonemiddleware=WARN,routes.middleware=WARN,stevedore=WARN,taskflow=WARN # Enables or disables publication of error events. (boolean @@ -257,10 +278,15 @@ #rpc_zmq_bind_address=* # MatchMaker driver. (string value) -#rpc_zmq_matchmaker=local +#rpc_zmq_matchmaker=redis -# ZeroMQ receiver listening port. (integer value) -#rpc_zmq_port=9501 +# Use REQ/REP pattern for all methods CALL/CAST/FANOUT. +# (boolean value) +#rpc_zmq_all_req_rep=true + +# Type of concurrency used. Either "native" or "eventlet" +# (string value) +#rpc_zmq_concurrency=eventlet # Number of ZeroMQ contexts, defaults to 1. (integer value) #rpc_zmq_contexts=1 @@ -281,11 +307,23 @@ # by impl_zmq. (integer value) #rpc_cast_timeout=30 -# Heartbeat frequency. (integer value) -#matchmaker_heartbeat_freq=300 +# The default number of seconds that poll should wait. Poll +# raises timeout exception when timeout expired. (integer +# value) +#rpc_poll_timeout=1 -# Heartbeat time-to-live. (integer value) -#matchmaker_heartbeat_ttl=600 +# Shows whether zmq-messaging uses broker or not. (boolean +# value) +#zmq_use_broker=true + +# Host to locate redis. (string value) +#host=127.0.0.1 + +# Use this port to connect to redis host. (integer value) +#port=6379 + +# Password for Redis server (optional). (string value) +#password= # Size of executor thread pool. (integer value) # Deprecated group/name - [DEFAULT]/rpc_thread_pool_size @@ -998,6 +1036,10 @@ # operations (integer value) #retry_interval=1 +# Time (in seconds) to sleep between when rebooting (powering +# off and on again). (integer value) +#reboot_delay=5 + [ilo] @@ -1376,18 +1418,7 @@ #port=6379 # Password for Redis server (optional). (string value) -#password= - - -[matchmaker_ring] - -# -# Options defined in oslo.messaging -# - -# Matchmaker ring file (JSON). (string value) -# Deprecated group/name - [DEFAULT]/matchmaker_ringfile -#ringfile=/etc/oslo/matchmaker_ring.json +#password= [neutron] @@ -1444,7 +1475,7 @@ # Max connection retries to check changes on OneView (integer # value) -#max_polling_attempts=20 +#max_polling_attempts=12 [oslo_concurrency] @@ -1511,6 +1542,24 @@ # Accept clients using either SSL or plain TCP (boolean value) #allow_insecure_clients=false +# Space separated list of acceptable SASL mechanisms (string +# value) +#sasl_mechanisms= + +# Path to directory that contains the SASL configuration +# (string value) +#sasl_config_dir= + +# Name of configuration file (without .conf suffix) (string +# value) +#sasl_config_name= + +# User name for message broker authentication (string value) +#username= + +# Password for message broker authentication (string value) +#password= + [oslo_messaging_qpid] @@ -1782,7 +1831,7 @@ #ipxe_boot_script=$pybasedir/drivers/modules/boot.ipxe # The IP version that will be used for PXE booting. Can be -# either 4 or 6. Defaults to 4. EXPERIMENTAL (integer value) +# either 4 or 6. Defaults to 4. EXPERIMENTAL (string value) #ip_version=4 diff --git a/ironic/drivers/modules/iboot.py b/ironic/drivers/modules/iboot.py index 56d45ebe35..c784c371c7 100644 --- a/ironic/drivers/modules/iboot.py +++ b/ironic/drivers/modules/iboot.py @@ -19,6 +19,8 @@ Ironic iBoot PDU power manager. """ +import time + from oslo_config import cfg from oslo_log import log as logging from oslo_service import loopingcall @@ -41,6 +43,11 @@ opts = [ default=1, help=_('Time (in seconds) between retry attempts for iBoot ' 'operations')), + cfg.IntOpt('reboot_delay', + default=5, + min=0, + help=_('Time (in seconds) to sleep between when rebooting ' + '(powering off and on again).')) ] CONF = cfg.CONF @@ -139,6 +146,11 @@ def _switch(driver_info, enabled): return mutable['response'] +def _sleep_switch(seconds): + """Function broken out for testing purpose.""" + time.sleep(seconds) + + def _power_status(driver_info): conn = _get_connection(driver_info) relay_id = driver_info['relay_id'] @@ -258,6 +270,7 @@ class IBootPower(base.PowerInterface): """ driver_info = _parse_driver_info(task.node) _switch(driver_info, False) + _sleep_switch(CONF.iboot.reboot_delay) _switch(driver_info, True) state = _power_status(driver_info) diff --git a/ironic/tests/unit/drivers/modules/test_iboot.py b/ironic/tests/unit/drivers/modules/test_iboot.py index 2ad9ed09fa..9e9f371a84 100644 --- a/ironic/tests/unit/drivers/modules/test_iboot.py +++ b/ironic/tests/unit/drivers/modules/test_iboot.py @@ -259,6 +259,7 @@ class IBootDriverTestCase(db_base.DbTestCase): super(IBootDriverTestCase, self).setUp() self.config(max_retry=0, group='iboot') self.config(retry_interval=0, group='iboot') + self.config(reboot_delay=0, group='iboot') mgr_utils.mock_the_extension_manager(driver='fake_iboot') self.driver = driver_factory.get_driver('fake_iboot') self.node = obj_utils.create_test_node( @@ -310,14 +311,19 @@ class IBootDriverTestCase(db_base.DbTestCase): task.driver.power.set_power_state, task, states.NOSTATE) + @mock.patch.object(iboot, '_sleep_switch', spec_set=types.FunctionType) @mock.patch.object(iboot, '_power_status', autospec=True) @mock.patch.object(iboot, '_switch', spec_set=types.FunctionType) - def test_reboot_good(self, mock_switch, mock_power_status): - manager = mock.MagicMock(spec_set=['switch']) + def test_reboot_good(self, mock_switch, mock_power_status, + mock_sleep_switch): + self.config(reboot_delay=3, group='iboot') + manager = mock.MagicMock(spec_set=['switch', 'sleep']) mock_power_status.return_value = states.POWER_ON manager.attach_mock(mock_switch, 'switch') + manager.attach_mock(mock_sleep_switch, 'sleep') expected = [mock.call.switch(self.info, False), + mock.call.sleep(3), mock.call.switch(self.info, True)] with task_manager.acquire(self.context, self.node.uuid) as task: @@ -325,14 +331,19 @@ class IBootDriverTestCase(db_base.DbTestCase): self.assertEqual(manager.mock_calls, expected) + @mock.patch.object(iboot, '_sleep_switch', spec_set=types.FunctionType) @mock.patch.object(iboot, '_power_status', autospec=True) @mock.patch.object(iboot, '_switch', spec_set=types.FunctionType) - def test_reboot_bad(self, mock_switch, mock_power_status): - manager = mock.MagicMock(spec_set=['switch']) + def test_reboot_bad(self, mock_switch, mock_power_status, + mock_sleep_switch): + self.config(reboot_delay=3, group='iboot') + manager = mock.MagicMock(spec_set=['switch', 'sleep']) mock_power_status.return_value = states.POWER_OFF manager.attach_mock(mock_switch, 'switch') + manager.attach_mock(mock_sleep_switch, 'sleep') expected = [mock.call.switch(self.info, False), + mock.call.sleep(3), mock.call.switch(self.info, True)] with task_manager.acquire(self.context, self.node.uuid) as task: