From 50ad6a0a9f5280de95afac8b2d216079d9bf607a Mon Sep 17 00:00:00 2001 From: benank Date: Mon, 11 Apr 2022 09:57:11 -0700 Subject: [PATCH 1/3] Ignore repeat/reboot on dry run commands --- .../package_managers/ZypperPackageManager.py | 27 ++++++++++++++----- 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/src/core/src/package_managers/ZypperPackageManager.py b/src/core/src/package_managers/ZypperPackageManager.py index c9a286f1..278a2bec 100644 --- a/src/core/src/package_managers/ZypperPackageManager.py +++ b/src/core/src/package_managers/ZypperPackageManager.py @@ -158,14 +158,29 @@ def invoke_package_manager(self, command): else: # verbose diagnostic log self.log_success_on_invoke(code, out) - if code == self.zypper_exitcode_zypper_updated: - self.composite_logger.log_debug(" - Package manager update detected. Patch installation run will be repeated.") - self.set_package_manager_setting(Constants.PACKAGE_MGR_SETTING_REPEAT_PATCH_OPERATION, True) - elif code == self.zypper_exitcode_reboot_required: - self.composite_logger.log_warning("Machine requires reboot after patch installation. Setting force_reboot flag to True.") - self.force_reboot = True + if code == self.zypper_exitcode_zypper_updated or code == self.zypper_exitcode_reboot_required: + self.__handle_repeat_or_reboot_exit_codes(command, code) + return out + def __handle_repeat_or_reboot_exit_codes(self, command, code): + """ Handles exit code 102 or 103 when returned from invoking package manager. + Does not repeat installation or reboot if it is a dry run. """ + if "--dry-run" in command: + self.composite_logger.log_debug( + "Exit code {0} detected from command \"{1}\", but it was a dry run. Continuing execution without repeating installation or rebooting.".format( + str(code), command)) + return + + if code == self.zypper_exitcode_zypper_updated: + self.composite_logger.log_debug( + " - Package manager update detected. Patch installation run will be repeated.") + self.set_package_manager_setting(Constants.PACKAGE_MGR_SETTING_REPEAT_PATCH_OPERATION, True) + elif code == self.zypper_exitcode_reboot_required: + self.composite_logger.log_warning( + "Machine requires reboot after patch installation. Setting force_reboot flag to True.") + self.force_reboot = True + def modify_upgrade_or_patch_command_to_replacefiles(self, command): """ Modifies a command to invoke_package_manager for update or patch to include a --replacefiles flag. If it is a dry run or already has the flag, it returns None. Otherwise, returns the new command. """ From a5580d0a4c2c29c0a1543814ebb6b50c2e041fac Mon Sep 17 00:00:00 2001 From: benank Date: Mon, 11 Apr 2022 10:14:16 -0700 Subject: [PATCH 2/3] Rename method --- src/core/src/package_managers/ZypperPackageManager.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/src/package_managers/ZypperPackageManager.py b/src/core/src/package_managers/ZypperPackageManager.py index 278a2bec..200ecd13 100644 --- a/src/core/src/package_managers/ZypperPackageManager.py +++ b/src/core/src/package_managers/ZypperPackageManager.py @@ -159,11 +159,11 @@ def invoke_package_manager(self, command): self.log_success_on_invoke(code, out) if code == self.zypper_exitcode_zypper_updated or code == self.zypper_exitcode_reboot_required: - self.__handle_repeat_or_reboot_exit_codes(command, code) - + self.__handle_zypper_updated_or_reboot_exit_codes(command, code) + return out - def __handle_repeat_or_reboot_exit_codes(self, command, code): + def __handle_zypper_updated_or_reboot_exit_codes(self, command, code): """ Handles exit code 102 or 103 when returned from invoking package manager. Does not repeat installation or reboot if it is a dry run. """ if "--dry-run" in command: From 6dd9d95b7c24c23ebb10e3ce3eeac01bbb9e064d Mon Sep 17 00:00:00 2001 From: benank Date: Mon, 11 Apr 2022 10:28:07 -0700 Subject: [PATCH 3/3] Add UTs --- src/core/tests/Test_ZypperPackageManager.py | 31 +++++++++++++++++++ .../tests/library/LegacyEnvLayerExtensions.py | 6 ++++ 2 files changed, 37 insertions(+) diff --git a/src/core/tests/Test_ZypperPackageManager.py b/src/core/tests/Test_ZypperPackageManager.py index 7eaad27d..c2ec11a6 100644 --- a/src/core/tests/Test_ZypperPackageManager.py +++ b/src/core/tests/Test_ZypperPackageManager.py @@ -604,6 +604,37 @@ def mock_run_command_output(cmd, no_output=False, chk_err=False): package_manager.env_layer.run_command_output = backup_mocked_method + def test_package_manager_exit_reboot_required(self): + # AnotherSadPath returns code 102 for this command + package_manager = self.container.get('package_manager') + self.runtime.status_handler.set_current_operation(Constants.INSTALLATION) + self.runtime.set_legacy_test_type('AnotherSadPath') + + cmd = "sudo LANG=en_US.UTF8 zypper --non-interactive patch --category security --dry-run" + package_manager.invoke_package_manager(cmd) + self.assertFalse(package_manager.force_reboot) + + # AnotherSadPath returns code 102 on this command, but should actually set reboot flag + cmd = "sudo LANG=en_US.UTF8 zypper --non-interactive patch --category security" + package_manager.invoke_package_manager(cmd) + self.assertTrue(package_manager.force_reboot) + + def test_package_manager_exit_repeat_operation(self): + # SadPath returns code 103 for this command + package_manager = self.container.get('package_manager') + self.runtime.status_handler.set_current_operation(Constants.INSTALLATION) + self.runtime.set_legacy_test_type('SadPath') + + # Should not set reboot flag (as it is a dry run) + cmd = "sudo LANG=en_US.UTF8 zypper --non-interactive patch --category security --dry-run" + package_manager.invoke_package_manager(cmd) + self.assertFalse(package_manager.get_package_manager_setting(Constants.PACKAGE_MGR_SETTING_REPEAT_PATCH_OPERATION, False)) + + # Should set reboot flag + cmd = "sudo LANG=en_US.UTF8 zypper --non-interactive patch --category security" + package_manager.invoke_package_manager(cmd) + self.assertTrue(package_manager.get_package_manager_setting(Constants.PACKAGE_MGR_SETTING_REPEAT_PATCH_OPERATION, False)) + if __name__ == '__main__': unittest.main() diff --git a/src/core/tests/library/LegacyEnvLayerExtensions.py b/src/core/tests/library/LegacyEnvLayerExtensions.py index ff222d3f..f62bf66f 100644 --- a/src/core/tests/library/LegacyEnvLayerExtensions.py +++ b/src/core/tests/library/LegacyEnvLayerExtensions.py @@ -556,6 +556,9 @@ def run_command_output(self, cmd, no_output=False, chk_err=True): elif cmd.find('sudo zypper refresh') > -1: code = 7 output = 'System management is locked by the application with pid 7914 (/usr/bin/zypper).' + elif cmd.find('sudo LANG=en_US.UTF8 zypper --non-interactive patch --category security') > -1: + code = 103 + output = '' elif cmd.find("systemctl") > -1: code = 1 output = '' @@ -606,6 +609,9 @@ def run_command_output(self, cmd, no_output=False, chk_err=True): elif cmd.find('sudo zypper --non-interactive update samba-libs=4.15.4+git.327.37e0a40d45f-3.57.1') > -1: code = 8 output = '' + elif cmd.find('sudo LANG=en_US.UTF8 zypper --non-interactive patch --category security') > -1: + code = 102 + output = '' elif self.legacy_test_type == 'ExceptionPath': code = -1 output = ''