def test_add_auth_apt_repo_writes_bearer_resource_token_to_auth_file( self, m_platform, m_valid_creds, m_get_apt_auth_file, m_subp, m_gpg_export, tmpdir, ): """Write apt authentication file when credentials are bearer token.""" repo_file = tmpdir.join("repo.conf").strpath auth_file = tmpdir.join("auth.conf").strpath m_get_apt_auth_file.return_value = auth_file m_subp.return_value = "500 esm.canonical.com...", "" # apt policy add_auth_apt_repo( repo_filename=repo_file, repo_url="http://fakerepo/", credentials="SOMELONGTOKEN", suites=("xenia", ), key_id="1", keyring_file="keyring", ) expected_content = ("machine fakerepo/ login bearer password" " SOMELONGTOKEN{}\n".format(APT_AUTH_COMMENT)) assert expected_content == util.load_file(auth_file)
def test_add_auth_apt_repo_comments_updates_suites_on_non_update_machine( self, m_platform, m_valid_creds, m_get_apt_auth_file, m_subp, m_gpg_export, tmpdir, ): """Skip any apt suites that don't match the current series.""" repo_file = tmpdir.join("repo.conf").strpath auth_file = tmpdir.join("auth.conf").strpath m_get_apt_auth_file.return_value = auth_file # apt policy without xenial-updates enabled origin = "test-origin" m_subp.return_value = ( POST_INSTALL_APT_CACHE_NO_UPDATES.format("xenial", origin), "", ) add_auth_apt_repo( repo_filename=repo_file, repo_url="http://fakerepo", credentials="mycreds", suites=("xenial-one", "xenial-updates", "trusty-gone"), keyring_file="keyring", ) expected_content = dedent("""\ deb http://fakerepo/ubuntu xenial-one main # deb-src http://fakerepo/ubuntu xenial-one main # deb http://fakerepo/ubuntu xenial-updates main # deb-src http://fakerepo/ubuntu xenial-updates main """) assert expected_content == util.load_file(repo_file)
def test_add_auth_apt_repo_writes_sources_file( self, m_platform, m_valid_creds, m_get_apt_auth_file, m_subp, m_gpg_export, tmpdir, ): """Write a properly configured sources file to repo_filename.""" repo_file = tmpdir.join("repo.conf").strpath auth_file = tmpdir.join("auth.conf").strpath m_get_apt_auth_file.return_value = auth_file m_subp.return_value = "500 esm.canonical.com...", "" # apt policy add_auth_apt_repo( repo_filename=repo_file, repo_url="http://fakerepo", credentials="mycreds", suites=("xenial", ), key_id="1", keyring_file="keyring", ) expected_content = ("deb http://fakerepo/ubuntu xenial main\n" "# deb-src http://fakerepo/ubuntu xenial main\n") assert expected_content == util.load_file(repo_file) gpg_export_calls = [mock.call("1", apt.UA_KEYRING_FILE, "keyring")] assert gpg_export_calls == m_gpg_export.call_args_list
def enable(self): """Enable specific entitlement. @return: True on success, False otherwise. """ if not self.can_enable(): return False 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['machineSecret'] ppa_fingerprint = directives.get('aptKey') if ppa_fingerprint: keyring_file = None else: keyring_file = os.path.join(apt.KEYRINGS_DIR, self.repo_key_file) repo_url = directives.get('aptURL') if not repo_url: repo_url = self.repo_url try: apt.add_auth_apt_repo(repo_filename, repo_url, token, keyring_file, ppa_fingerprint) except apt.InvalidAPTCredentialsError as e: logging.error(str(e)) return False if self.repo_pin_priority: repo_pref_file = self.repo_pref_file_tmpl.format(name=self.name, series=series) apt.add_ppa_pinning(repo_pref_file, repo_url, self.repo_pin_priority) if not os.path.exists(apt.APT_METHOD_HTTPS_FILE): util.subp(['apt-get', 'install', 'apt-transport-https'], capture=True) if not os.path.exists(apt.CA_CERTIFICATES_FILE): util.subp(['apt-get', 'install', 'ca-certificates'], capture=True) try: util.subp(['apt-get', 'update'], capture=True) if self.packages: print('Installing {title} packages' ' (this may take a while)'.format(title=self.title)) util.subp(['apt-get', 'install'] + self.packages) except util.ProcessExecutionError: self.disable(silent=True, force=True) logging.error( status.MESSAGE_ENABLED_FAILED_TMPL.format(title=self.title)) return False print(status.MESSAGE_ENABLED_TMPL.format(title=self.title)) return True
def test_add_auth_apt_repo_writes_bearer_resource_token_to_auth_file( self, m_platform, m_valid_creds, m_get_apt_auth_file, m_subp, tmpdir): """Write apt authentication file when credentials are bearer token.""" repo_file = tmpdir.join('repo.conf').strpath auth_file = tmpdir.join('auth.conf').strpath m_get_apt_auth_file.return_value = auth_file add_auth_apt_repo(repo_filename=repo_file, repo_url='http://fakerepo/', credentials='SOMELONGTOKEN', fingerprint='APTKEY') expected_content = ( 'machine fakerepo/ login bearer password SOMELONGTOKEN%s' % APT_AUTH_COMMENT) assert expected_content == util.load_file(auth_file)
def test_add_auth_apt_repo_writes_sources_file( self, m_platform, m_valid_creds, m_get_apt_auth_file, m_subp, tmpdir): """Write a properly configured sources file to repo_filename.""" repo_file = tmpdir.join('repo.conf').strpath auth_file = tmpdir.join('auth.conf').strpath m_get_apt_auth_file.return_value = auth_file m_subp.return_value = '500 esm.canonical.com...', '' # apt policy add_auth_apt_repo( repo_filename=repo_file, repo_url='http://fakerepo', credentials='mycreds', suites=('xenial',)) expected_content = ( 'deb http://fakerepo/ubuntu xenial main\n' '# deb-src http://fakerepo/ubuntu xenial main\n') assert expected_content == util.load_file(repo_file)
def test_add_auth_apt_repo_writes_sources_file(self, m_platform, m_valid_creds, m_get_apt_auth_file, m_subp, tmpdir): """Write a properly configured sources file to repo_filename.""" repo_file = tmpdir.join('repo.conf').strpath auth_file = tmpdir.join('auth.conf').strpath m_get_apt_auth_file.return_value = auth_file add_auth_apt_repo(repo_filename=repo_file, repo_url='http://fakerepo', credentials='mycreds', fingerprint='APTKEY') expected_content = ('deb http://fakerepo/ubuntu xenial main\n' '# deb-src http://fakerepo/ubuntu xenial main\n') assert expected_content == util.load_file(repo_file)
def test_add_auth_apt_repo_writes_bearer_resource_token_to_auth_file( self, m_platform, m_valid_creds, m_get_apt_auth_file, m_subp, tmpdir): """Write apt authentication file when credentials are bearer token.""" repo_file = tmpdir.join('repo.conf').strpath auth_file = tmpdir.join('auth.conf').strpath m_get_apt_auth_file.return_value = auth_file m_subp.return_value = '500 esm.canonical.com...', '' # apt policy add_auth_apt_repo( repo_filename=repo_file, repo_url='http://fakerepo/', credentials='SOMELONGTOKEN', suites=('xenia',)) expected_content = ( 'machine fakerepo/ login bearer password SOMELONGTOKEN%s\n' % APT_AUTH_COMMENT) assert expected_content == util.load_file(auth_file)
def test_add_auth_apt_repo_writes_username_password_to_auth_file( self, m_platform, m_valid_creds, m_get_apt_auth_file, m_subp, tmpdir): """Write apt authentication file when credentials are user:pwd.""" repo_file = tmpdir.join('repo.conf').strpath auth_file = tmpdir.join('auth.conf').strpath m_get_apt_auth_file.return_value = auth_file add_auth_apt_repo(repo_filename=repo_file, repo_url='http://fakerepo', credentials='user:password', fingerprint='APTKEY') expected_content = ( 'machine fakerepo/ login user password password%s' % APT_AUTH_COMMENT) assert expected_content == util.load_file(auth_file)
def test_add_auth_apt_repo_writes_username_password_to_auth_file( self, m_platform, m_valid_creds, m_get_apt_auth_file, m_subp): """Write apt authentication file when credentials are user:pwd.""" tmp_dir = self.tmp_dir() repo_file = self.tmp_path('repo.conf', tmp_dir) auth_file = self.tmp_path('auth.conf', tmp_dir) m_get_apt_auth_file.return_value = auth_file add_auth_apt_repo(repo_filename=repo_file, repo_url='http://fakerepo', credentials='user:password', fingerprint='APTKEY') expected_content = ( '\n# This file is created by ubuntu-advantage-tools and will be' ' updated\n# by subsequent calls to ua attach|detach [entitlement]' '\nmachine fakerepo/ubuntu/ login user password password\n') assert expected_content == util.load_file(auth_file)
def test_add_auth_apt_repo_ignores_updates_suites_on_non_update_machine( self, m_platform, m_valid_creds, m_get_apt_auth_file, m_subp, tmpdir): """Skip any apt suites that don't match the current series.""" repo_file = tmpdir.join('repo.conf').strpath auth_file = tmpdir.join('auth.conf').strpath m_get_apt_auth_file.return_value = auth_file # apt policy without xenial-updates enabled m_subp.return_value = '500 esm.canonical.com xenial/main', '' add_auth_apt_repo( repo_filename=repo_file, repo_url='http://fakerepo', credentials='mycreds', suites=('xenial-one', 'xenial-updates', 'trusty-gone')) expected_content = dedent("""\ deb http://fakerepo/ubuntu xenial-one main # deb-src http://fakerepo/ubuntu xenial-one main """) assert expected_content == util.load_file(repo_file)
def test_add_auth_apt_repo_ignores_suites_not_matching_series( self, m_platform, m_valid_creds, m_get_apt_auth_file, m_subp, m_gpg_export, tmpdir, ): """Skip any apt suites that don't match the current series.""" repo_file = tmpdir.join("repo.conf").strpath auth_file = tmpdir.join("auth.conf").strpath m_get_apt_auth_file.return_value = auth_file # apt policy with xenial-updates enabled stdout = dedent( """\ 500 http://archive.ubuntu.com/ubuntu/ xenial-updates/main amd64 \ Packages release v=16.04,o=Ubuntu,a=xenial-updates,n=xenial,l=Ubuntu\ ,c=main""" ) m_subp.return_value = stdout, "" add_auth_apt_repo( repo_filename=repo_file, repo_url="http://fakerepo", credentials="mycreds", suites=("xenial-one", "xenial-updates", "trusty-gone"), keyring_file="keyring", ) expected_content = dedent( """\ deb http://fakerepo/ubuntu xenial-one main # deb-src http://fakerepo/ubuntu xenial-one main deb http://fakerepo/ubuntu xenial-updates main # deb-src http://fakerepo/ubuntu xenial-updates main """ ) assert expected_content == util.load_file(repo_file)
def test_add_auth_apt_repo_adds_apt_fingerprint(self, m_platform, m_valid_creds, m_get_apt_auth_file, m_subp, tmpdir): """Call apt-key to add the specified fingerprint.""" repo_file = tmpdir.join('repo.conf').strpath auth_file = tmpdir.join('auth.conf').strpath m_get_apt_auth_file.return_value = auth_file add_auth_apt_repo(repo_filename=repo_file, repo_url='http://fakerepo', credentials='mycreds', fingerprint='APTKEY') apt_cmds = [ mock.call([ 'apt-key', 'adv', '--keyserver', 'keyserver.ubuntu.com', '--recv-keys', 'APTKEY' ], capture=True) ] assert apt_cmds == m_subp.call_args_list
def enable(self): """Enable specific entitlement. @return: True on success, False otherwise. """ if not self.can_enable(): return False 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'] ppa_fingerprint = directives.get('aptKey') if ppa_fingerprint: keyring_file = None else: keyring_file = os.path.join(apt.KEYRINGS_DIR, self.repo_key_file) repo_url = directives.get('aptURL') if not repo_url: repo_url = self.repo_url if self.repo_pin_priority: if not self.origin: logging.error( "Cannot setup apt pin. Empty apt repo origin value '%s'." % self.origin) logging.error( status.MESSAGE_ENABLED_FAILED_TMPL.format( title=self.title)) return False repo_pref_file = self.repo_pref_file_tmpl.format( name=self.name, series=series) apt.add_ppa_pinning( repo_pref_file, repo_url, self.origin, self.repo_pin_priority) 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: util.subp( ['apt-get', 'install', '--assume-yes'] + prerequisite_pkgs, capture=True) except util.ProcessExecutionError as e: logging.error(str(e)) return False try: apt.add_auth_apt_repo( repo_filename, repo_url, token, keyring_file, ppa_fingerprint, pockets=self.repo_pockets) except apt.InvalidAPTCredentialsError as e: logging.error(str(e)) return False if self.packages: try: print('Updating package lists ...') util.subp(['apt-get', 'update'], capture=True) print( 'Installing {title} packages ...'.format(title=self.title)) util.subp( ['apt-get', 'install', '--assume-yes'] + self.packages, capture=True) except util.ProcessExecutionError: self.disable(silent=True, force=True) logging.error( status.MESSAGE_ENABLED_FAILED_TMPL.format( title=self.title)) return False print(status.MESSAGE_ENABLED_TMPL.format(title=self.title)) for msg in self.messaging.get('post_enable', []): print(msg) return True
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
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'] if directives.get('aptKey'): logging.debug( "Ignoring aptKey directive '%s'", directives.get('aptKey')) keyring_file = os.path.join(apt.KEYRINGS_DIR, self.repo_key_file) repo_url = directives.get('aptURL') if not repo_url: repo_url = self.repo_url repo_suites = directives.get('suites') if not repo_suites: raise exceptions.UserFacingError( 'Empty %s apt suites directive from %s' % (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 '%s'.\n" "%s" % (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, keyring_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('Updating package lists') try: apt.run_apt_command( ['apt-get', 'update'], status.MESSAGE_APT_UPDATE_FAILED) except exceptions.UserFacingError: self.remove_apt_config() raise
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
def setup_apt_config(self): 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'] if directives.get('aptKey'): logging.debug("Ignoring aptKey directive '%s'", directives.get('aptKey')) keyring_file = os.path.join(apt.KEYRINGS_DIR, self.repo_key_file) repo_url = directives.get('aptURL') if not repo_url: repo_url = self.repo_url repo_suites = directives.get('suites') if not repo_suites: logging.error('Empty %s apt suites directive from %s', self.name, self.cfg.contract_url) return False if self.repo_pin_priority: if not self.origin: logging.error( "Cannot setup apt pin. Empty apt repo origin value '%s'." % self.origin) logging.error( status.MESSAGE_ENABLED_FAILED_TMPL.format( title=self.title)) return False repo_pref_file = self.repo_pref_file_tmpl.format(name=self.name, series=series) apt.add_ppa_pinning(repo_pref_file, repo_url, self.origin, self.repo_pin_priority) 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: util.subp(['apt-get', 'install', '--assume-yes'] + prerequisite_pkgs, capture=True) except util.ProcessExecutionError as e: logging.error(str(e)) return False try: apt.add_auth_apt_repo(repo_filename, repo_url, token, repo_suites, keyring_file) except apt.InvalidAPTCredentialsError as e: logging.error(str(e)) return False # 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 new report the repo as accessible # which allows ua status to report correct info print('Updating package lists ...') util.subp(['apt-get', 'update'], capture=True) return True