From 46eb5aedd6f50259c9d7d5dc4b2d32ca8818e1dd Mon Sep 17 00:00:00 2001 From: Aurelien Lourot Date: Tue, 1 Mar 2022 15:24:06 +0100 Subject: [PATCH] Add unit status reboot hint Change-Id: I00343e72cb5be25e1dbd19338a0bead04076ac35 --- src/charm.py | 6 +++++- src/charm_utils.py | 24 ++++++++++++++++++++---- unit_tests/test_charm.py | 2 +- unit_tests/test_charm_utils.py | 29 +++++++++++++++++++++++------ 4 files changed, 49 insertions(+), 12 deletions(-) diff --git a/src/charm.py b/src/charm.py index f1fbfaf..3108ca2 100755 --- a/src/charm.py +++ b/src/charm.py @@ -82,6 +82,10 @@ class NovaComputeNvidiaVgpuCharm(ops_openstack.core.OSBaseCharm): self.config, self.services()) def services(self): + """Determine the list of services that should be running. + + :rtype: List[str] + """ # If no NVIDIA software is expected to be installed on this particular # unit, then no service should be expected to run by # OSBaseCharm.update_status(). Otherwise the services from the @@ -95,7 +99,7 @@ class NovaComputeNvidiaVgpuCharm(ops_openstack.core.OSBaseCharm): :rtype: ops.model.StatusBase """ - return check_status(self.config) + return check_status(self.config, self.services()) if __name__ == '__main__': diff --git a/src/charm_utils.py b/src/charm_utils.py index 2c02510..51aff65 100644 --- a/src/charm_utils.py +++ b/src/charm_utils.py @@ -23,6 +23,7 @@ from ruamel.yaml import YAML from charmhelpers.contrib.openstack.utils import ( CompareOpenStackReleases, get_os_codename_package, + ows_check_services_running, ) from charmhelpers.core.hookenv import cached from charmhelpers.core.host import file_hash @@ -95,25 +96,40 @@ def install_nvidia_software_if_needed(stored, config, resources): stored.last_installed_resource_hash = nvidia_software_hash -def check_status(config): +def check_status(config, services): """Determine the unit status to be set. :param config: Juju application config. :type config: ops.model.ConfigData + :param services: List of services expected to be running. + :type services: List[str] :rtype: ops.model.StatusBase """ unit_status_msg = ('no ' if not nvidia_utils.has_nvidia_gpu_hardware() else '') + 'NVIDIA GPU found; ' installed_versions = nvidia_utils.installed_nvidia_software_versions() - if len(installed_versions) > 0: + software_is_installed = len(installed_versions) > 0 + + _, services_not_running_msg = ows_check_services_running(services, + ports=[]) + software_is_running = services_not_running_msg is None + + if software_is_installed: unit_status_msg += 'installed NVIDIA software: ' unit_status_msg += ', '.join(installed_versions) + if not software_is_running: + # NOTE(lourot): the exact list of services not running that should + # be will be displayed in the principal's blocked status message + # already, so no need to repeat it here on the subordinate. + unit_status_msg += '; reboot required?' else: unit_status_msg += 'no NVIDIA software installed' - if (is_nvidia_software_to_be_installed(config) and - len(installed_versions) == 0): + if ((is_nvidia_software_to_be_installed(config) and + not software_is_installed) or + (software_is_installed and + not software_is_running)): return BlockedStatus(unit_status_msg) return ActiveStatus('Unit is ready: ' + unit_status_msg) diff --git a/unit_tests/test_charm.py b/unit_tests/test_charm.py index 1fa1b34..0a68e7a 100644 --- a/unit_tests/test_charm.py +++ b/unit_tests/test_charm.py @@ -81,5 +81,5 @@ class TestNovaComputeNvidiaVgpuCharm(CharmTestCase): self.harness.add_relation_unit(relation_id, 'nova-compute/0') # Verify that nova-compute-vgpu-charm sets relation data to its - # principle nova-compute. + # principal nova-compute. self.assertTrue(self.set_principal_unit_relation_data.called) diff --git a/unit_tests/test_charm_utils.py b/unit_tests/test_charm_utils.py index f046d8e..b747e38 100644 --- a/unit_tests/test_charm_utils.py +++ b/unit_tests/test_charm_utils.py @@ -76,16 +76,19 @@ class TestCharmUtils(unittest.TestCase): apt_install_mock.assert_called_once_with(['path-to-software'], fatal=True) + @patch('charm_utils.ows_check_services_running') @patch('charm_utils.is_nvidia_software_to_be_installed') @patch('nvidia_utils.installed_nvidia_software_versions') @patch('nvidia_utils.has_nvidia_gpu_hardware') - def test_check_status(self, has_hw_mock, installed_sw_mock, - is_sw_to_be_installed_mock): + def test_check_status( + self, has_hw_mock, installed_sw_mock, is_sw_to_be_installed_mock, + check_services_running_mock): has_hw_mock.return_value = True installed_sw_mock.return_value = ['42', '43'] is_sw_to_be_installed_mock.return_value = True + check_services_running_mock.return_value = (None, None) self.assertEqual( - charm_utils.check_status(None), + charm_utils.check_status(None, None), ActiveStatus( 'Unit is ready: ' 'NVIDIA GPU found; installed NVIDIA software: 42, 43')) @@ -93,8 +96,9 @@ class TestCharmUtils(unittest.TestCase): has_hw_mock.return_value = False installed_sw_mock.return_value = ['42', '43'] is_sw_to_be_installed_mock.return_value = True + check_services_running_mock.return_value = (None, None) self.assertEqual( - charm_utils.check_status(None), + charm_utils.check_status(None, None), ActiveStatus( 'Unit is ready: ' 'no NVIDIA GPU found; installed NVIDIA software: 42, 43')) @@ -102,20 +106,33 @@ class TestCharmUtils(unittest.TestCase): has_hw_mock.return_value = True installed_sw_mock.return_value = [] is_sw_to_be_installed_mock.return_value = True + check_services_running_mock.return_value = (None, None) self.assertEqual( - charm_utils.check_status(None), + charm_utils.check_status(None, None), BlockedStatus( 'NVIDIA GPU found; no NVIDIA software installed')) has_hw_mock.return_value = True installed_sw_mock.return_value = [] is_sw_to_be_installed_mock.return_value = False + check_services_running_mock.return_value = (None, None) self.assertEqual( - charm_utils.check_status(None), + charm_utils.check_status(None, None), ActiveStatus( 'Unit is ready: ' 'NVIDIA GPU found; no NVIDIA software installed')) + has_hw_mock.return_value = True + installed_sw_mock.return_value = ['42', '43'] + is_sw_to_be_installed_mock.return_value = True + check_services_running_mock.return_value = ( + None, 'Services not running that should be: nvidia-vgpu-mgr') + self.assertEqual( + charm_utils.check_status(None, None), + BlockedStatus( + 'NVIDIA GPU found; installed NVIDIA software: 42, 43; ' + 'reboot required?')) + @patch('nvidia_utils._installed_nvidia_software_packages') @patch('charm_utils.get_os_codename_package') def test_set_principal_unit_relation_data(self, release_codename_mock,