def uninstall(self, name: str, force=False): """ Uninstall SONiC Package referenced by name. The uninstallation can be forced if force argument is True. Args: name: SONiC Package name. force: Force the installation. Raises: PackageManagerError """ with failure_ignore(force): if not self.is_installed(name): raise PackageUninstallationError(f'{name} is not installed') package = self.get_installed_package(name) service_name = package.manifest['service']['name'] with failure_ignore(force): if self.feature_registry.is_feature_enabled(service_name): raise PackageUninstallationError( f'{service_name} is enabled. Disable the feature first') if package.built_in: raise PackageUninstallationError( f'Cannot uninstall built-in package {package.name}') installed_packages = self._get_installed_packages_except(package) with failure_ignore(force): validate_package_tree(installed_packages) # After all checks are passed we proceed to actual uninstallation try: self._uninstall_cli_plugins(package) self.service_creator.remove(package) self.service_creator.generate_shutdown_sequence_files( self._get_installed_packages_except(package) ) # Clean containers based on this image containers = self.docker.ps(filters={'ancestor': package.image_id}, all=True) for container in containers: self.docker.rm(container.id, force=True) self.docker.rmi(package.image_id, force=True) package.entry.image_id = None except Exception as err: raise PackageUninstallationError( f'Failed to uninstall {package.name}: {err}' ) package.entry.installed = False package.entry.version = None self.database.update_package(package.entry) self.database.commit()
def uninstall(self, name: str, force: bool = False, keep_config: bool = False): """ Uninstall SONiC Package referenced by name. The uninstallation can be forced if force argument is True. Args: name: SONiC Package name. force: Force the installation. keep_config: Keep feature configuration in databases. Raises: PackageManagerError """ with failure_ignore(force): if not self.is_installed(name): raise PackageUninstallationError(f'{name} is not installed') package = self.get_installed_package(name) service_name = package.manifest['service']['name'] with failure_ignore(force): if self.feature_registry.is_feature_enabled(service_name): raise PackageUninstallationError( f'{service_name} is enabled. Disable the feature first') if package.built_in: raise PackageUninstallationError( f'Cannot uninstall built-in package {package.name}') installed_packages = self._get_installed_packages_except(package) with failure_ignore(force): validate_package_tree(installed_packages) # After all checks are passed we proceed to actual uninstallation try: # Stop and disable the service. # First to make sure we are not uninstalling # package before the service has fully stopped # since "config feature state" command is not blocking. # Second, we make sure the service is in disabled state # so that after reinstall and enablement hostcfgd will enable # it and start it. # TODO: once there is a way to block till hostcfgd will stop # the service, replace it with new approach. self._systemctl_action(package, 'stop') self._systemctl_action(package, 'disable') self._uninstall_cli_plugins(package) self.service_creator.remove(package, keep_config=keep_config) self.service_creator.generate_shutdown_sequence_files( self._get_installed_packages_except(package)) self.docker.rm_by_ancestor(package.image_id, force=True) self.docker.rmi(package.image_id, force=True) package.entry.image_id = None except Exception as err: raise PackageUninstallationError( f'Failed to uninstall {package.name}: {err}') package.entry.installed = False package.entry.version = None self.database.update_package(package.entry) self.database.commit()