Example #1
0
    def test_correct_command_called(self, m_subp):
        get_installed_packages()

        expected_call = mock.call(
            ["dpkg-query", "-W", "--showformat=${Package}\\n"]
        )
        assert [expected_call] == m_subp.call_args_list
Example #2
0
    def enable(self, *, silent_if_inapplicable: bool = False) -> bool:
        """Enable specific entitlement.

        :param silent_if_inapplicable:
            Don't emit any messages until after it has been determined that
            this entitlement is applicable to the current machine.

        @return: True on success, False otherwise.
        """
        if not self.can_enable(silent=silent_if_inapplicable):
            return False
        if not util.which('/snap/bin/canonical-livepatch'):
            if not util.which(SNAP_CMD):
                print('Installing snapd')
                util.subp(['apt-get', 'install', '--assume-yes', 'snapd'],
                          capture=True,
                          retry_sleeps=apt.APT_RETRIES)
                util.subp([SNAP_CMD, 'wait', 'system', 'seed.loaded'],
                          capture=True)
            elif 'snapd' not in apt.get_installed_packages():
                raise exceptions.UserFacingError(
                    '/usr/bin/snap is present but snapd is not installed;'
                    ' cannot enable {}'.format(self.title))
            print('Installing canonical-livepatch snap')
            try:
                util.subp([SNAP_CMD, 'install', 'canonical-livepatch'],
                          capture=True,
                          retry_sleeps=SNAP_INSTALL_RETRIES)
            except util.ProcessExecutionError as e:
                msg = 'Unable to install Livepatch client: ' + str(e)
                print(msg)
                logging.error(msg)
                return False
        return self.setup_livepatch_config(process_directives=True,
                                           process_token=True)
Example #3
0
 def packages(self) -> "List[str]":
     packages = list(self.fips_required_packages)
     installed_packages = apt.get_installed_packages()
     for pkg_name, extra_pkgs in self.fips_packages.items():
         if pkg_name in installed_packages:
             packages.append(pkg_name)
             packages.extend(extra_pkgs)
     return packages
    def enable(self, *, silent_if_inapplicable: bool = False) -> bool:
        """Enable specific entitlement.

        :param silent_if_inapplicable:
            Don't emit any messages until after it has been determined that
            this entitlement is applicable to the current machine.

        @return: True on success, False otherwise.
        """
        if not self.can_enable(silent=silent_if_inapplicable):
            return False
        if not util.which("/snap/bin/canonical-livepatch"):
            if not util.which(SNAP_CMD):
                print("Installing snapd")
                print(status.MESSAGE_APT_UPDATING_LISTS)
                try:
                    apt.run_apt_command(
                        ["apt-get", "update"], status.MESSAGE_APT_UPDATE_FAILED
                    )
                except exceptions.UserFacingError as e:
                    logging.debug(
                        "Trying to install snapd."
                        " Ignoring apt-get update failure: %s",
                        str(e),
                    )
                util.subp(
                    ["apt-get", "install", "--assume-yes", "snapd"],
                    capture=True,
                    retry_sleeps=apt.APT_RETRIES,
                )
            elif "snapd" not in apt.get_installed_packages():
                raise exceptions.UserFacingError(
                    "/usr/bin/snap is present but snapd is not installed;"
                    " cannot enable {}".format(self.title)
                )
            util.subp(
                [SNAP_CMD, "wait", "system", "seed.loaded"], capture=True
            )
            print("Installing canonical-livepatch snap")
            try:
                util.subp(
                    [SNAP_CMD, "install", "canonical-livepatch"],
                    capture=True,
                    retry_sleeps=SNAP_INSTALL_RETRIES,
                )
            except util.ProcessExecutionError as e:
                msg = "Unable to install Livepatch client: " + str(e)
                raise exceptions.UserFacingError(msg)
        return self.setup_livepatch_config(
            process_directives=True, process_token=True
        )
Example #5
0
    def packages(self) -> "List[str]":
        packages = super().packages
        installed_packages = apt.get_installed_packages()

        pkg_groups = groupby(
            self.conditional_packages,
            key=lambda pkg_name: pkg_name.replace("-hmac", ""),
        )

        for pkg_name, pkg_list in pkg_groups:
            if pkg_name in installed_packages:
                packages += pkg_list

        return packages
    def install_packages(
        self,
        package_list: List[str] = None,
        cleanup_on_failure: bool = True,
        verbose: bool = True,
    ) -> None:
        """Install contract recommended packages for the entitlement.

        :param package_list: Optional package list to use instead of
            self.packages.
        :param cleanup_on_failure: Cleanup apt files if apt install fails.
        :param verbose: If true, print messages to stdout
        """
        if verbose:
            event.info("Installing {title} packages".format(title=self.title))

        # We need to guarantee that the metapackage is installed.
        # While the other packages should still be installed, if they
        # fail, we should not block the enable operation.
        mandatory_packages = self.packages
        super().install_packages(
            package_list=mandatory_packages, verbose=False
        )

        # Any conditional packages should still be installed, but if
        # they fail to install we should not block the enable operation.
        desired_packages = []  # type: List[str]
        installed_packages = apt.get_installed_packages()
        pkg_groups = groupby(
            sorted(self.conditional_packages),
            key=lambda pkg_name: pkg_name.replace("-hmac", ""),
        )

        for pkg_name, pkg_list in pkg_groups:
            if pkg_name in installed_packages:
                desired_packages += pkg_list

        for pkg in desired_packages:
            try:
                super().install_packages(
                    package_list=[pkg], cleanup_on_failure=False, verbose=False
                )
            except exceptions.UserFacingError:
                event.info(
                    messages.FIPS_PACKAGE_NOT_AVAILABLE.format(
                        service=self.title, pkg=pkg
                    )
                )
Example #7
0
    def packages(self) -> "List[str]":
        packages = []  # type: List[str]
        installed_packages = apt.get_installed_packages()

        pkg_groups = groupby(
            super().packages,
            key=lambda pkg_name: pkg_name.replace("-hmac", ""),
        )

        for pkg_name, pkg_list in pkg_groups:
            if pkg_name in installed_packages:
                packages += pkg_list
            elif pkg_name in self.fips_required_packages:
                packages += pkg_list

        return packages
    def remove_packages(self) -> None:
        """Remove fips meta package to disable the service.

        FIPS meta-package will unset grub config options which will deactivate
        FIPS on any related packages.
        """
        installed_packages = set(apt.get_installed_packages())
        fips_metapackage = set(self.packages).difference(
            set(self.conditional_packages)
        )
        remove_packages = fips_metapackage.intersection(installed_packages)
        if remove_packages:
            env = {"DEBIAN_FRONTEND": "noninteractive"}
            apt_options = [
                '-o Dpkg::Options::="--force-confdef"',
                '-o Dpkg::Options::="--force-confold"',
            ]
            apt.run_apt_command(
                ["apt-get", "remove", "--assume-yes"]
                + apt_options
                + list(remove_packages),
                messages.DISABLE_FAILED_TMPL.format(title=self.title),
                env=env,
            )
Example #9
0
 def test_assert_missing_eof_newline_works(self, m_subp):
     assert ["a", "b"] == get_installed_packages()
Example #10
0
 def test_lines_are_split(self, m_subp):
     assert ["a", "b"] == get_installed_packages()
Example #11
0
 def test_empty_output_means_empty_list(self, m_subp):
     assert [] == get_installed_packages()
    def _perform_enable(self, silent: bool = False) -> bool:
        """Enable specific entitlement.

        @return: True on success, False otherwise.
        """
        if not util.which(snap.SNAP_CMD):
            event.info("Installing snapd")
            event.info(messages.APT_UPDATING_LISTS)
            try:
                apt.run_apt_update_command()
            except exceptions.UserFacingError as e:
                logging.debug(
                    "Trying to install snapd."
                    " Ignoring apt-get update failure: %s",
                    str(e),
                )
            util.subp(
                ["apt-get", "install", "--assume-yes", "snapd"],
                capture=True,
                retry_sleeps=apt.APT_RETRIES,
            )
        elif "snapd" not in apt.get_installed_packages():
            raise exceptions.SnapdNotProperlyInstalledError(
                snap_cmd=snap.SNAP_CMD, service=self.title
            )

        try:
            util.subp(
                [snap.SNAP_CMD, "wait", "system", "seed.loaded"], capture=True
            )
        except exceptions.ProcessExecutionError as e:
            if re.search(r"unknown command .*wait", str(e).lower()):
                logging.warning(messages.SNAPD_DOES_NOT_HAVE_WAIT_CMD)
            else:
                raise

        http_proxy = util.validate_proxy(
            "http", self.cfg.http_proxy, util.PROXY_VALIDATION_SNAP_HTTP_URL
        )
        https_proxy = util.validate_proxy(
            "https", self.cfg.https_proxy, util.PROXY_VALIDATION_SNAP_HTTPS_URL
        )
        snap.configure_snap_proxy(
            http_proxy=http_proxy,
            https_proxy=https_proxy,
            retry_sleeps=snap.SNAP_INSTALL_RETRIES,
        )

        if not util.which(LIVEPATCH_CMD):
            event.info("Installing canonical-livepatch snap")
            try:
                util.subp(
                    [snap.SNAP_CMD, "install", "canonical-livepatch"],
                    capture=True,
                    retry_sleeps=snap.SNAP_INSTALL_RETRIES,
                )
            except exceptions.ProcessExecutionError as e:
                raise exceptions.ErrorInstallingLivepatch(error_msg=str(e))

        configure_livepatch_proxy(http_proxy, https_proxy)

        return self.setup_livepatch_config(
            process_directives=True, process_token=True
        )
Example #13
0
 def test_lines_are_split(self, m_subp):
     assert ['a', 'b'] == get_installed_packages()
def is_installed() -> bool:
    """Returns whether or not snap is installed"""
    return "snapd" in apt.get_installed_packages()