diff options
-rw-r--r-- | ironic/conductor/manager.py | 34 | ||||
-rw-r--r-- | ironic/conf/conductor.py | 10 | ||||
-rw-r--r-- | ironic/conf/drac.py | 1 | ||||
-rw-r--r-- | ironic/drivers/modules/drac/inspect.py | 15 | ||||
-rw-r--r-- | ironic/drivers/modules/oneview/deploy.py | 6 | ||||
-rw-r--r-- | ironic/tests/unit/drivers/modules/drac/test_inspect.py | 24 | ||||
-rw-r--r-- | releasenotes/notes/disable_periodic_tasks-0ea39fa7a8a108c6.yaml | 49 | ||||
-rw-r--r-- | releasenotes/notes/fix-cpu-count-8904a4e1a24456f4.yaml | 7 | ||||
-rw-r--r-- | zuul.d/ironic-jobs.yaml | 1 |
9 files changed, 129 insertions, 18 deletions
diff --git a/ironic/conductor/manager.py b/ironic/conductor/manager.py index 2ee2bd031..a730b362c 100644 --- a/ironic/conductor/manager.py +++ b/ironic/conductor/manager.py @@ -1584,7 +1584,8 @@ class ConductorManager(base_manager.BaseConductorManager): return @METRICS.timer('ConductorManager._sync_power_states') - @periodics.periodic(spacing=CONF.conductor.sync_power_state_interval) + @periodics.periodic(spacing=CONF.conductor.sync_power_state_interval, + enabled=CONF.conductor.sync_power_state_interval > 0) def _sync_power_states(self, context): """Periodic task to sync power states for the nodes. @@ -1744,7 +1745,10 @@ class ConductorManager(base_manager.BaseConductorManager): eventlet.sleep(0) @METRICS.timer('ConductorManager._check_deploy_timeouts') - @periodics.periodic(spacing=CONF.conductor.check_provision_state_interval) + @periodics.periodic( + spacing=CONF.conductor.check_provision_state_interval, + enabled=CONF.conductor.check_provision_state_interval > 0 + and CONF.conductor.deploy_callback_timeout != 0) def _check_deploy_timeouts(self, context): """Periodically checks whether a deploy RPC call has timed out. @@ -1752,6 +1756,8 @@ class ConductorManager(base_manager.BaseConductorManager): :param context: request context. """ + # FIXME(rloo): If the value is < 0, it will be enabled. That doesn't + # seem right. callback_timeout = CONF.conductor.deploy_callback_timeout if not callback_timeout: return @@ -1767,7 +1773,9 @@ class ConductorManager(base_manager.BaseConductorManager): sort_key, callback_method, err_handler) @METRICS.timer('ConductorManager._check_orphan_nodes') - @periodics.periodic(spacing=CONF.conductor.check_provision_state_interval) + @periodics.periodic( + spacing=CONF.conductor.check_provision_state_interval, + enabled=CONF.conductor.check_provision_state_interval > 0) def _check_orphan_nodes(self, context): """Periodically checks the status of nodes that were taken over. @@ -1954,7 +1962,10 @@ class ConductorManager(base_manager.BaseConductorManager): task, 'console_restore', fields.NotificationStatus.ERROR) @METRICS.timer('ConductorManager._check_cleanwait_timeouts') - @periodics.periodic(spacing=CONF.conductor.check_provision_state_interval) + @periodics.periodic( + spacing=CONF.conductor.check_provision_state_interval, + enabled=CONF.conductor.check_provision_state_interval > 0 + and CONF.conductor.clean_callback_timeout != 0) def _check_cleanwait_timeouts(self, context): """Periodically checks for nodes being cleaned. @@ -1963,6 +1974,8 @@ class ConductorManager(base_manager.BaseConductorManager): :param context: request context. """ + # FIXME(rloo): If the value is < 0, it will be enabled. That doesn't + # seem right. callback_timeout = CONF.conductor.clean_callback_timeout if not callback_timeout: return @@ -1998,7 +2011,8 @@ class ConductorManager(base_manager.BaseConductorManager): ) @METRICS.timer('ConductorManager._sync_local_state') - @periodics.periodic(spacing=CONF.conductor.sync_local_state_interval) + @periodics.periodic(spacing=CONF.conductor.sync_local_state_interval, + enabled=CONF.conductor.sync_local_state_interval > 0) def _sync_local_state(self, context): """Perform any actions necessary to sync local state. @@ -2739,7 +2753,8 @@ class ConductorManager(base_manager.BaseConductorManager): eventlet.sleep(0) @METRICS.timer('ConductorManager._send_sensor_data') - @periodics.periodic(spacing=CONF.conductor.send_sensor_data_interval) + @periodics.periodic(spacing=CONF.conductor.send_sensor_data_interval, + enabled=CONF.conductor.send_sensor_data) def _send_sensor_data(self, context): """Periodically sends sensor data to Ceilometer.""" @@ -2952,13 +2967,18 @@ class ConductorManager(base_manager.BaseConductorManager): state=task.node.provision_state) @METRICS.timer('ConductorManager._check_inspect_wait_timeouts') - @periodics.periodic(spacing=CONF.conductor.check_provision_state_interval) + @periodics.periodic( + spacing=CONF.conductor.check_provision_state_interval, + enabled=CONF.conductor.check_provision_state_interval > 0 + and CONF.conductor.inspect_wait_timeout != 0) def _check_inspect_wait_timeouts(self, context): """Periodically checks inspect_wait_timeout and fails upon reaching it. :param: context: request context """ + # FIXME(rloo): If the value is < 0, it will be enabled. That doesn't + # seem right. callback_timeout = CONF.conductor.inspect_wait_timeout if not callback_timeout: return diff --git a/ironic/conf/conductor.py b/ironic/conf/conductor.py index 3b2ae1d57..0149b51bc 100644 --- a/ironic/conf/conductor.py +++ b/ironic/conf/conductor.py @@ -47,11 +47,12 @@ opts = [ cfg.IntOpt('sync_power_state_interval', default=60, help=_('Interval between syncing the node power state to the ' - 'database, in seconds.')), + 'database, in seconds. Set to 0 to disable syncing.')), cfg.IntOpt('check_provision_state_interval', default=60, + min=0, help=_('Interval between checks of provision timeouts, ' - 'in seconds.')), + 'in seconds. Set to 0 to disable checks.')), cfg.IntOpt('check_rescue_state_interval', default=60, min=1, @@ -90,6 +91,7 @@ opts = [ 'notification bus')), cfg.IntOpt('send_sensor_data_interval', default=600, + min=1, help=_('Seconds between conductor sending sensor data message ' 'to ceilometer via the notification bus.')), cfg.IntOpt('send_sensor_data_workers', @@ -115,8 +117,8 @@ opts = [ 'local state as nodes are moved around the cluster. ' 'This option controls how often, in seconds, each ' 'conductor will check for nodes that it should ' - '"take over". Set it to a negative value to disable ' - 'the check entirely.')), + '"take over". Set it to 0 (or a negative value) to ' + 'disable the check entirely.')), cfg.StrOpt('configdrive_swift_container', default='ironic_configdrive_container', help=_('Name of the Swift container to store config drive ' diff --git a/ironic/conf/drac.py b/ironic/conf/drac.py index fcc193012..f132574be 100644 --- a/ironic/conf/drac.py +++ b/ironic/conf/drac.py @@ -18,6 +18,7 @@ from ironic.common.i18n import _ opts = [ cfg.IntOpt('query_raid_config_job_status_interval', default=120, + min=1, help=_('Interval (in seconds) between periodic RAID job status ' 'checks to determine whether the asynchronous RAID ' 'configuration was successfully finished or not.')) diff --git a/ironic/drivers/modules/drac/inspect.py b/ironic/drivers/modules/drac/inspect.py index e6029a242..bdccfd018 100644 --- a/ironic/drivers/modules/drac/inspect.py +++ b/ironic/drivers/modules/drac/inspect.py @@ -80,7 +80,8 @@ class DracInspect(base.InspectInterface): [memory.size_mb for memory in client.list_memory()]) cpus = client.list_cpus() if cpus: - properties['cpus'] = len(cpus) + properties['cpus'] = sum( + [self._calculate_cpus(cpu) for cpu in cpus]) properties['cpu_arch'] = 'x86_64' if cpus[0].arch64 else 'x86' virtual_disks = client.list_virtual_disks() @@ -148,3 +149,15 @@ class DracInspect(base.InspectInterface): for disk in disks: if disk.size_mb >= min_size_required_mb: return disk + + def _calculate_cpus(self, cpu): + """Find actual CPU count. + + :param cpu: Pass cpu. + + :returns: returns total cpu count. + """ + if cpu.ht_enabled: + return cpu.cores * 2 + else: + return cpu.cores diff --git a/ironic/drivers/modules/oneview/deploy.py b/ironic/drivers/modules/oneview/deploy.py index 71a3cb8a7..acceed987 100644 --- a/ironic/drivers/modules/oneview/deploy.py +++ b/ironic/drivers/modules/oneview/deploy.py @@ -37,7 +37,8 @@ METRICS = metrics_utils.get_metrics_logger(__name__) class OneViewPeriodicTasks(object): @periodics.periodic(spacing=CONF.oneview.periodic_check_interval, - enabled=CONF.oneview.enable_periodic_tasks) + enabled=CONF.oneview.enable_periodic_tasks + and CONF.oneview.periodic_check_interval > 0) def _periodic_check_nodes_taken_by_oneview(self, manager, context): """Checks if nodes in Ironic were taken by OneView users. @@ -94,7 +95,8 @@ class OneViewPeriodicTasks(object): manager.do_provisioning_action(context, node.uuid, 'manage') @periodics.periodic(spacing=CONF.oneview.periodic_check_interval, - enabled=CONF.oneview.enable_periodic_tasks) + enabled=CONF.oneview.enable_periodic_tasks + and CONF.oneview.periodic_check_interval > 0) def _periodic_check_nodes_freed_by_oneview(self, manager, context): """Checks if nodes taken by OneView users were freed. diff --git a/ironic/tests/unit/drivers/modules/drac/test_inspect.py b/ironic/tests/unit/drivers/modules/drac/test_inspect.py index 2c6b25936..1d650e29f 100644 --- a/ironic/tests/unit/drivers/modules/drac/test_inspect.py +++ b/ironic/tests/unit/drivers/modules/drac/test_inspect.py @@ -63,7 +63,7 @@ class DracInspectionTestCase(test_utils.BaseDracTest): 'speed': 2400, 'model': 'Intel(R) Xeon(R) CPU E5-2620 v3 @ 2.40GHz', 'state': 'ok', - 'ht_enabled': True, + 'ht_enabled': False, 'turbo_enabled': True, 'vt_enabled': True, 'arch64': True}] @@ -141,7 +141,7 @@ class DracInspectionTestCase(test_utils.BaseDracTest): expected_node_properties = { 'memory_mb': 32768, 'local_gb': 1116, - 'cpus': 2, + 'cpus': 18, 'cpu_arch': 'x86_64'} mock_client = mock.Mock() mock_get_drac_client.return_value = mock_client @@ -184,7 +184,7 @@ class DracInspectionTestCase(test_utils.BaseDracTest): expected_node_properties = { 'memory_mb': 32768, 'local_gb': 279, - 'cpus': 2, + 'cpus': 18, 'cpu_arch': 'x86_64'} mock_client = mock.Mock() mock_get_drac_client.return_value = mock_client @@ -229,7 +229,7 @@ class DracInspectionTestCase(test_utils.BaseDracTest): expected_node_properties = { 'memory_mb': 32768, 'local_gb': 1116, - 'cpus': 2, + 'cpus': 18, 'cpu_arch': 'x86_64'} mock_client = mock.Mock() mock_get_drac_client.return_value = mock_client @@ -255,3 +255,19 @@ class DracInspectionTestCase(test_utils.BaseDracTest): self.physical_disks) self.assertEqual(285888, root_disk.size_mb) + + def test__calculate_cpus(self): + with task_manager.acquire(self.context, self.node.uuid, + shared=True) as task: + cpu = task.driver.inspect._calculate_cpus( + self.cpus[0]) + + self.assertEqual(12, cpu) + + def test__calculate_cpus_without_ht_enabled(self): + with task_manager.acquire(self.context, self.node.uuid, + shared=True) as task: + cpu = task.driver.inspect._calculate_cpus( + self.cpus[1]) + + self.assertEqual(6, cpu) diff --git a/releasenotes/notes/disable_periodic_tasks-0ea39fa7a8a108c6.yaml b/releasenotes/notes/disable_periodic_tasks-0ea39fa7a8a108c6.yaml new file mode 100644 index 000000000..a2811537e --- /dev/null +++ b/releasenotes/notes/disable_periodic_tasks-0ea39fa7a8a108c6.yaml @@ -0,0 +1,49 @@ +--- +features: + - | + Setting these configuration options to 0 will disable the periodic tasks: + + * [conductor]sync_power_state_interval: sync power states for the nodes + * [conductor]check_provision_state_interval: + + * check deployments and time out if the deployment takes too long + * check the status of cleaning a node and time out if it takes too long + * check the status of inspecting a node and time out if it takes too long + * check for and handle nodes that are taken over by new conductors (if an + old conductor disappeared) + + * [conductor]send_sensor_data_interval: send sensor data to ceilometer + * [conductor]sync_local_state_interval: refresh a conductor's copy of the + consistent hash ring. If any mappings have changed, determines which, + if any, nodes need to be "taken over". The ensuing actions could include + preparing a PXE environment, updating the DHCP server, and so on. + * [oneview]periodic_check_interval: + + * check for nodes taken over by OneView users + * check for nodes freed by OneView users + +fixes: + - | + Fixes an issue where setting these configuration options to 0 caused a + ValueError exception to be raised. You can now set them to 0 to disable the + associated periodic tasks. (For more information, see `story 2002059 + <https://storyboard.openstack.org/#!/story/2002059>`_.): + + * [conductor]sync_power_state_interval: sync power states for the nodes + * [conductor]check_provision_state_interval: + + * check deployments and time out if the deployment takes too long + * check the status of cleaning a node and time out if it takes too long + * check the status of inspecting a node and time out if it takes too long + * check for and handle nodes that are taken over by new conductors (if an + old conductor disappeared) + + * [conductor]send_sensor_data_interval: send sensor data to ceilometer + * [conductor]sync_local_state_interval: refresh a conductor's copy of the + consistent hash ring. If any mappings have changed, determines which, + if any, nodes need to be "taken over". The ensuing actions could include + preparing a PXE environment, updating the DHCP server, and so on. + * [oneview]periodic_check_interval: + + * check for nodes taken over by OneView users + * check for nodes freed by OneView users diff --git a/releasenotes/notes/fix-cpu-count-8904a4e1a24456f4.yaml b/releasenotes/notes/fix-cpu-count-8904a4e1a24456f4.yaml new file mode 100644 index 000000000..e609f2ab5 --- /dev/null +++ b/releasenotes/notes/fix-cpu-count-8904a4e1a24456f4.yaml @@ -0,0 +1,7 @@ +--- +fixes: + - | + Fixes a bug where the number of CPU sockets was being returned by the + ``idrac`` hardware type during introspection, instead of the number of + virtual CPUs. See bug `2004155 + <https://storyboard.openstack.org/#!/story/2004155>`_ for details. diff --git a/zuul.d/ironic-jobs.yaml b/zuul.d/ironic-jobs.yaml index 1cc346366..a38f38d41 100644 --- a/zuul.d/ironic-jobs.yaml +++ b/zuul.d/ironic-jobs.yaml @@ -196,6 +196,7 @@ vars: devstack_localrc: IRONIC_BOOT_MODE: uefi + IRONIC_VM_SPECS_RAM: 512 - job: name: ironic-tempest-dsvm-ipa-partition-pxe_ipmitool-tinyipa-python3 |