예제 #1
0
    def remove_apt_config(self,
                          run_apt_update: bool = True,
                          silent: bool = False):
        """Remove any repository apt configuration files.

        :param run_apt_update: If after removing the apt update
            command after removing the apt files.
        """
        series = util.get_platform_info()["series"]
        repo_filename = self.repo_list_file_tmpl.format(name=self.name)
        entitlement = self.cfg.entitlements[self.name].get("entitlement", {})
        access_directives = entitlement.get("directives", {})
        repo_url = access_directives.get("aptURL")
        if not repo_url:
            raise exceptions.MissingAptURLDirective(self.name)
        if self.disable_apt_auth_only:
            # We only remove the repo from the apt auth file, because
            # UA Infra: ESM is a special-case: we want to be able to report on
            # the available UA Infra: ESM updates even when it's disabled
            apt.remove_repo_from_apt_auth_file(repo_url)
            apt.restore_commented_apt_list_file(repo_filename)
        else:
            apt.remove_auth_apt_repo(repo_filename, repo_url,
                                     self.repo_key_file)
            apt.remove_apt_list_files(repo_url, series)
        if self.repo_pin_priority:
            repo_pref_file = self.repo_pref_file_tmpl.format(name=self.name)
            if self.repo_pin_priority == "never":
                # Disable the repo with a pinning file
                apt.add_ppa_pinning(
                    repo_pref_file,
                    repo_url,
                    self.origin,
                    self.repo_pin_priority,
                )
            elif os.path.exists(repo_pref_file):
                os.unlink(repo_pref_file)

        if run_apt_update:
            if not silent:
                event.info(messages.APT_UPDATING_LISTS)
            apt.run_apt_update_command()
예제 #2
0
 def remove_apt_config(self):
     """Remove any repository apt configuration files."""
     series = util.get_platform_info()["series"]
     repo_filename = self.repo_list_file_tmpl.format(
         name=self.name, series=series
     )
     entitlement = self.cfg.entitlements[self.name].get("entitlement", {})
     access_directives = entitlement.get("directives", {})
     repo_url = access_directives.get("aptURL")
     if not repo_url:
         raise exceptions.MissingAptURLDirective(self.name)
     if self.disable_apt_auth_only:
         # We only remove the repo from the apt auth file, because ESM Infra
         # is a special-case: we want to be able to report on the
         # available ESM Infra updates even when it's disabled
         apt.remove_repo_from_apt_auth_file(repo_url)
         apt.restore_commented_apt_list_file(repo_filename)
     else:
         apt.remove_auth_apt_repo(
             repo_filename, repo_url, self.repo_key_file
         )
         apt.remove_apt_list_files(repo_url, series)
     if self.repo_pin_priority:
         repo_pref_file = self.repo_pref_file_tmpl.format(
             name=self.name, series=series
         )
         if self.repo_pin_priority == "never":
             # Disable the repo with a pinning file
             apt.add_ppa_pinning(
                 repo_pref_file,
                 repo_url,
                 self.origin,
                 self.repo_pin_priority,
             )
         elif os.path.exists(repo_pref_file):
             os.unlink(repo_pref_file)
     print(status.MESSAGE_APT_UPDATING_LISTS)
     apt.run_apt_command(
         ["apt-get", "update"], status.MESSAGE_APT_UPDATE_FAILED
     )
예제 #3
0
    def setup_apt_config(self) -> None:
        """Setup apt config based on the resourceToken and  directives.

        :raise UserFacingError: on failure to setup any aspect of this apt
           configuration
        """
        series = util.get_platform_info()["series"]
        repo_filename = self.repo_list_file_tmpl.format(
            name=self.name, series=series
        )
        resource_cfg = self.cfg.entitlements.get(self.name)
        directives = resource_cfg["entitlement"].get("directives", {})
        token = resource_cfg.get("resourceToken")
        if not token:
            logging.debug(
                "No specific resourceToken present. Using machine token"
                " as %s credentials",
                self.title,
            )
            token = self.cfg.machine_token["machineToken"]
        aptKey = directives.get("aptKey")
        if not aptKey:
            raise exceptions.UserFacingError(
                "Ubuntu Advantage server provided no aptKey directive for"
                " {}.".format(self.name)
            )
        repo_url = directives.get("aptURL")
        if not repo_url:
            raise exceptions.MissingAptURLDirective(self.name)
        repo_suites = directives.get("suites")
        if not repo_suites:
            raise exceptions.UserFacingError(
                "Empty {} apt suites directive from {}".format(
                    self.name, self.cfg.contract_url
                )
            )
        if self.repo_pin_priority:
            if not self.origin:
                raise exceptions.UserFacingError(
                    "Cannot setup apt pin. Empty apt repo origin value '{}'.\n"
                    "{}".format(
                        self.origin,
                        status.MESSAGE_ENABLED_FAILED_TMPL.format(
                            title=self.title
                        ),
                    )
                )
            repo_pref_file = self.repo_pref_file_tmpl.format(
                name=self.name, series=series
            )
            if self.repo_pin_priority != "never":
                apt.add_ppa_pinning(
                    repo_pref_file,
                    repo_url,
                    self.origin,
                    self.repo_pin_priority,
                )
            elif os.path.exists(repo_pref_file):
                os.unlink(repo_pref_file)  # Remove disabling apt pref file

        prerequisite_pkgs = []
        if not os.path.exists(apt.APT_METHOD_HTTPS_FILE):
            prerequisite_pkgs.append("apt-transport-https")
        if not os.path.exists(apt.CA_CERTIFICATES_FILE):
            prerequisite_pkgs.append("ca-certificates")

        if prerequisite_pkgs:
            print(
                "Installing prerequisites: {}".format(
                    ", ".join(prerequisite_pkgs)
                )
            )
            try:
                apt.run_apt_command(
                    ["apt-get", "install", "--assume-yes"] + prerequisite_pkgs,
                    status.MESSAGE_APT_INSTALL_FAILED,
                )
            except exceptions.UserFacingError:
                self.remove_apt_config()
                raise
        apt.add_auth_apt_repo(
            repo_filename, repo_url, token, repo_suites, self.repo_key_file
        )
        # Run apt-update on any repo-entitlement enable because the machine
        # probably wants access to the repo that was just enabled.
        # Side-effect is that apt policy will now report the repo as accessible
        # which allows ua status to report correct info
        print(status.MESSAGE_APT_UPDATING_LISTS)
        try:
            apt.run_apt_command(
                ["apt-get", "update"], status.MESSAGE_APT_UPDATE_FAILED
            )
        except exceptions.UserFacingError:
            self.remove_apt_config()
            raise
예제 #4
0
    def setup_apt_config(self, silent: bool = False) -> None:
        """Setup apt config based on the resourceToken and directives.
        Also sets up apt proxy if necessary.

        :raise UserFacingError: on failure to setup any aspect of this apt
           configuration
        """
        http_proxy = None  # type: Optional[str]
        https_proxy = None  # type: Optional[str]
        scope = None  # type: Optional[apt.AptProxyScope]
        if self.cfg.global_apt_http_proxy or self.cfg.global_apt_https_proxy:
            http_proxy = util.validate_proxy(
                "http",
                self.cfg.global_apt_http_proxy,
                util.PROXY_VALIDATION_APT_HTTP_URL,
            )
            https_proxy = util.validate_proxy(
                "https",
                self.cfg.global_apt_https_proxy,
                util.PROXY_VALIDATION_APT_HTTPS_URL,
            )
            scope = apt.AptProxyScope.GLOBAL
        elif self.cfg.ua_apt_http_proxy or self.cfg.ua_apt_https_proxy:
            http_proxy = util.validate_proxy(
                "http",
                self.cfg.ua_apt_http_proxy,
                util.PROXY_VALIDATION_APT_HTTP_URL,
            )
            https_proxy = util.validate_proxy(
                "https",
                self.cfg.ua_apt_https_proxy,
                util.PROXY_VALIDATION_APT_HTTPS_URL,
            )
            scope = apt.AptProxyScope.UACLIENT

        apt.setup_apt_proxy(http_proxy=http_proxy,
                            https_proxy=https_proxy,
                            proxy_scope=scope)
        repo_filename = self.repo_list_file_tmpl.format(name=self.name)
        resource_cfg = self.cfg.entitlements.get(self.name)
        directives = resource_cfg["entitlement"].get("directives", {})
        obligations = resource_cfg["entitlement"].get("obligations", {})
        token = resource_cfg.get("resourceToken")
        if not token:
            machine_token = self.cfg.machine_token["machineToken"]
            if not obligations.get("enableByDefault"):
                # services that are not enableByDefault need to obtain specific
                # resource access for tokens. We want to refresh this every
                # enable call because it is not refreshed by `ua refresh`.
                client = contract.UAContractClient(self.cfg)
                machine_access = client.request_resource_machine_access(
                    machine_token, self.name)
                if machine_access:
                    token = machine_access.get("resourceToken")
            if not token:
                token = machine_token
                logging.warning(
                    "No resourceToken present in contract for service %s."
                    " Using machine token as credentials",
                    self.title,
                )
        aptKey = directives.get("aptKey")
        if not aptKey:
            raise exceptions.UserFacingError(
                "Ubuntu Advantage server provided no aptKey directive for"
                " {}.".format(self.name))
        repo_url = directives.get("aptURL")
        if not repo_url:
            raise exceptions.MissingAptURLDirective(self.name)
        repo_suites = directives.get("suites")
        if not repo_suites:
            raise exceptions.UserFacingError(
                "Empty {} apt suites directive from {}".format(
                    self.name, self.cfg.contract_url))
        if self.repo_pin_priority:
            if not self.origin:
                raise exceptions.UserFacingError(
                    "Cannot setup apt pin. Empty apt repo origin value '{}'.\n"
                    "{}".format(
                        self.origin,
                        messages.ENABLED_FAILED.format(title=self.title).msg,
                    ))
            repo_pref_file = self.repo_pref_file_tmpl.format(name=self.name)
            if self.repo_pin_priority != "never":
                apt.add_ppa_pinning(
                    repo_pref_file,
                    repo_url,
                    self.origin,
                    self.repo_pin_priority,
                )
            elif os.path.exists(repo_pref_file):
                os.unlink(repo_pref_file)  # Remove disabling apt pref file

        prerequisite_pkgs = []
        if not os.path.exists(apt.APT_METHOD_HTTPS_FILE):
            prerequisite_pkgs.append("apt-transport-https")
        if not os.path.exists(apt.CA_CERTIFICATES_FILE):
            prerequisite_pkgs.append("ca-certificates")

        if prerequisite_pkgs:
            if not silent:
                event.info("Installing prerequisites: {}".format(
                    ", ".join(prerequisite_pkgs)))
            try:
                apt.run_apt_install_command(packages=prerequisite_pkgs)
            except exceptions.UserFacingError:
                self.remove_apt_config()
                raise
        apt.add_auth_apt_repo(repo_filename, repo_url, token, repo_suites,
                              self.repo_key_file)
        # Run apt-update on any repo-entitlement enable because the machine
        # probably wants access to the repo that was just enabled.
        # Side-effect is that apt policy will now report the repo as accessible
        # which allows ua status to report correct info
        if not silent:
            event.info(messages.APT_UPDATING_LISTS)
        try:
            apt.run_apt_update_command()
        except exceptions.UserFacingError:
            self.remove_apt_config(run_apt_update=False)
            raise