예제 #1
0
    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()
예제 #2
0
    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()