From 3610ce9360ed6dbbdc42bd6d10849adf111bcad9 Mon Sep 17 00:00:00 2001 From: Stepan Blyshchak <38952541+stepanblyschak@users.noreply.github.com> Date: Mon, 20 Nov 2023 18:59:44 +0200 Subject: [PATCH] [sonic-package-manager] Fix YANG validation failure on upgrade when feature has constraints in YANG model on FEATURE table (#2933) * [sonic-package-manager] Fix YANG validation failure on upgrade when feature has constraints in YANG model on FEATURE table Signed-off-by: Stepan Blyschak --- sonic_package_manager/manager.py | 36 ++++++++++++++------- tests/sonic_package_manager/test_manager.py | 5 +++ 2 files changed, 30 insertions(+), 11 deletions(-) diff --git a/sonic_package_manager/manager.py b/sonic_package_manager/manager.py index d01ed9cb44..e41bb00e8f 100644 --- a/sonic_package_manager/manager.py +++ b/sonic_package_manager/manager.py @@ -44,7 +44,10 @@ from sonic_package_manager.reference import PackageReference from sonic_package_manager.registry import RegistryResolver from sonic_package_manager.service_creator import SONIC_CLI_COMMANDS -from sonic_package_manager.service_creator.creator import ServiceCreator +from sonic_package_manager.service_creator.creator import ( + ServiceCreator, + run_command +) from sonic_package_manager.service_creator.feature import FeatureRegistry from sonic_package_manager.service_creator.sonic_db import ( INIT_CFG_JSON, @@ -483,7 +486,7 @@ def uninstall(self, name: str, # After all checks are passed we proceed to actual uninstallation try: - self._stop_feature(package) + self._disable_feature(package) self._uninstall_cli_plugins(package) self.service_creator.remove(package, keep_config=keep_config) self.service_creator.generate_shutdown_sequence_files( @@ -934,18 +937,29 @@ def _get_installed_packages_except(self, package: Package) -> Dict[str, Package] packages.pop(package.name) return packages - def _start_feature(self, package: Package, block: bool = True): - """ Starts the feature and blocks till operation is finished if - block argument is set to True. + def _stop_feature(self, package: Package): + self._systemctl_action(package, 'stop') - Args: - package: Package object of the feature that will be started. - block: Whether to block for operation completion. - """ + def _start_feature(self, package: Package): + self._systemctl_action(package, 'start') + + def _systemctl_action(self, package: Package, action: str): + """ Execute systemctl action for a service. """ + + name = package.manifest['service']['name'] + log.info('Execute systemctl action {} on {} service'.format(action, name)) - self._set_feature_state(package, 'enabled', block) + host_service = package.manifest['service']['host-service'] + asic_service = package.manifest['service']['asic-service'] + single_instance = host_service or (asic_service and not self.is_multi_npu) + multi_instance = asic_service and self.is_multi_npu + if single_instance: + run_command(['systemctl', action, name]) + if multi_instance: + for npu in range(self.num_npus): + run_command(['systemctl', action, f'{name}@{npu}']) - def _stop_feature(self, package: Package, block: bool = True): + def _disable_feature(self, package: Package, block: bool = True): """ Stops the feature and blocks till operation is finished if block argument is set to True. diff --git a/tests/sonic_package_manager/test_manager.py b/tests/sonic_package_manager/test_manager.py index db9a79b309..46ea3f6acb 100644 --- a/tests/sonic_package_manager/test_manager.py +++ b/tests/sonic_package_manager/test_manager.py @@ -9,6 +9,11 @@ from sonic_package_manager.errors import * from sonic_package_manager.version import Version +@pytest.fixture(autouse=True) +def mock_run_command(): + with patch('sonic_package_manager.manager.run_command') as run_command: + yield run_command + def test_installation_not_installed(package_manager): package_manager.install('test-package')