def load_repository(self, repo_id): """Download repo metadata. If the repo is enabled, load its metadata to verify that the repo is valid. An invalid repo will be disabled. This method will by default not try to refresh already loaded data if called repeatedly. :param str repo_id: an identifier of a repository :raise: MetadataError if the metadata cannot be loaded """ log.debug("Load metadata for the '%s' repository.", repo_id) repo = self._get_repository(repo_id) url = repo.baseurl or repo.mirrorlist or repo.metalink if not repo.enabled: log.debug("Don't load metadata from a disabled repository.") return try: repo.load() except dnf.exceptions.RepoError as e: log.debug("Failed to load metadata from '%s': %s", url, str(e)) repo.disable() raise MetadataError(str(e)) from None log.info("Loaded metadata from '%s'.", url)
def _create_repository(self, data: RepoConfigurationData): """Create a DNF repository. :param RepoConfigurationData data: a repo configuration return dnf.repo.Repo: a DNF repository """ repo = dnf.repo.Repo(data.name, self._base.conf) # Disable the repo if requested. if not data.enabled: repo.disable() # Set up the repo location. url = self.substitute(data.url) if data.type == URL_TYPE_BASEURL: repo.baseurl = [url] if data.type == URL_TYPE_MIRRORLIST: repo.mirrorlist = url if data.type == URL_TYPE_METALINK: repo.metalink = url # Set the proxy configuration. proxy = self._parse_proxy(data.proxy) if proxy: repo.proxy = proxy.noauth_url repo.proxy_username = proxy.username or "" repo.proxy_password = proxy.password or "" # Set the repo configuration. if data.cost != DNF_DEFAULT_REPO_COST: repo.cost = data.cost if data.included_packages: repo.includepkgs = data.included_packages if data.excluded_packages: repo.excludepkgs = data.excluded_packages # Set up the SSL configuration. repo.sslverify = conf.payload.verify_ssl and data.ssl_verification_enabled if data.ssl_configuration.ca_cert_path: repo.sslcacert = data.ssl_configuration.ca_cert_path if data.ssl_configuration.client_cert_path: repo.sslclientcert = data.ssl_configuration.client_cert_path if data.ssl_configuration.client_key_path: repo.sslclientkey = data.ssl_configuration.client_key_path return repo
def set_repository_enabled(self, repo_id, enabled): """Enable or disable the specified repository. :param repo_id: an identifier of a repository :param enabled: True to enable, False to disable :raise: UnknownRepositoryError if no repo is found """ repo = self._get_repository(repo_id) if enabled: repo.enable() log.info("The '%s' repository is enabled.", repo_id) else: repo.disable() log.info("The '%s' repository is disabled.", repo_id)
def _fetch_md(self, repo_name): """Download repo metadata :param repo_name: name/id of repo to fetch :type repo_name: str :returns: None """ repo = self._base.repos[repo_name] repo.enable() try: # Load the metadata to verify that the repo is valid repo.load() except dnf.exceptions.RepoError as e: repo.disable() log.debug("repo: '%s' - %s failed to load repomd", repo.id, repo.baseurl or repo.mirrorlist or repo.metalink) raise MetadataError(e) from e log.info("enabled repo: '%s' - %s and got repomd", repo.id, repo.baseurl or repo.mirrorlist or repo.metalink)
def setUp(self): cli = mock.MagicMock() self.cmd = download.DownloadCommand(cli) self.cmd.cli.base = dnf.cli.cli.BaseCli() self.cmd.cli.base.add_remote_rpms = mock.MagicMock() self.cmd.cli.base.download_packages = mock.Mock() # point the Sack and Subject to out stubs # b/c these are used in the _get_query methods self.orig_sack = self.cmd.cli.base.sack self.cmd.cli.base._sack = SackStub() self.orig_subject = dnf.subject.Subject dnf.subject.Subject = SubjectStub self.cmd.opts = mock.Mock() self.cmd.opts.resolve = False self.cmd.opts.arches = [] repo = dnf.repo.Repo(name='foo') repo.enable() self.cmd.base.repos.add(repo) repo = dnf.repo.Repo(name='foo-source') repo.disable() self.cmd.base.repos.add(repo) repo = dnf.repo.Repo(name='bar') repo.enable() self.cmd.base.repos.add(repo) repo = dnf.repo.Repo(name='foobar-source') repo.disable() self.cmd.base.repos.add(repo) repo = dnf.repo.Repo(name='foo-debuginfo') repo.disable() self.cmd.base.repos.add(repo)
def load_repository(self, repo_id): """Download repo metadata. Enable the repo and load its metadata to verify that the repo is valid. An invalid repo will be disabled. :param str repo_id: an identifier of a repository :raise: MetadataError if the metadata cannot be loaded """ log.debug("Load metadata for the '%s' repository.", repo_id) repo = self._get_repository(repo_id) url = repo.baseurl or repo.mirrorlist or repo.metalink try: repo.enable() repo.load() except dnf.exceptions.RepoError as e: log.debug("Failed to load metadata from '%s': %s", url, str(e)) repo.disable() raise MetadataError(str(e)) from None log.info("Loaded metadata from '%s'.", url)
def build_dnf(self, config): dnf_base = dnf.Base() for repo in dnf_base.repos.all(): repo.disable() for repo_id, repo_opts in config['repos'].items(): repo = dnf.repo.Repo(repo_id, self.dnf_temp_cache) repo.enable() for opt, val in repo_opts.items(): # Inject is a custom option and DNF won't recognize it if opt == "inject": continue setattr(repo, opt, val) repo.load() dnf_base.repos.add(repo) log.debug("Defined repo %s" % repo.id) # Do not consider *anything* to be installed dnf_base.fill_sack(load_system_repo=False, load_available_repos=True) return dnf_base
def setUp(self): cli = mock.MagicMock() self.cmd = download.DownloadCommand(cli) self.cmd.cli.base = dnf.cli.cli.BaseCli() self.cmd.cli.base.add_remote_rpms = mock.MagicMock() self.cmd.cli.base.download_packages = mock.Mock() # point the Sack and Subject to out stubs # b/c these are used in the _get_query methods self.orig_sack = self.cmd.cli.base.sack self.cmd.cli.base._sack = SackStub() self.orig_subject = dnf.subject.Subject dnf.subject.Subject = SubjectStub self.cmd.opts = mock.Mock() self.cmd.opts.resolve = False self.cmd.opts.arches = [] repo = dnf.repo.Repo(name='foo') repo.baseurl = ["file:///dev/null"] repo.enable() self.cmd.base.repos.add(repo) repo = dnf.repo.Repo(name='foo-source') repo.baseurl = ["file:///dev/null"] repo.disable() self.cmd.base.repos.add(repo) repo = dnf.repo.Repo(name='bar') repo.baseurl = ["file:///dev/null"] repo.enable() self.cmd.base.repos.add(repo) repo = dnf.repo.Repo(name='foobar-source') repo.baseurl = ["file:///dev/null"] repo.disable() self.cmd.base.repos.add(repo) repo = dnf.repo.Repo(name='foo-debuginfo') repo.baseurl = ["file:///dev/null"] repo.disable() self.cmd.base.repos.add(repo)
def updateBaseRepo(self, fallback=True, checkmount=True): log.info('configuring base repo') self.reset() url, mirrorlist, metalink = self._setupInstallDevice( self.storage, checkmount) method = self.data.method sslverify = True if method.method == "url": sslverify = not (method.noverifyssl or flags.noverifyssl) # Read in all the repos from the installation environment, make a note of which # are enabled, and then disable them all. If the user gave us a method, we want # to use that instead of the default repos. self._base.read_all_repos() # Repos on disk are always enabled. When reloaded their state needs to # be synchronized with the user selection. self.setUpdatesEnabled(self._updates_enabled) enabled = [] with self._repos_lock: for repo in self._base.repos.iter_enabled(): enabled.append(repo.id) repo.disable() # If askmethod was specified on the command-line, leave all the repos # disabled and return if flags.askmethod: return if method.method: try: self._base.conf.releasever = self._getReleaseVersion(url) log.debug("releasever from %s is %s", url, self._base.conf.releasever) except configparser.MissingSectionHeaderError as e: log.error("couldn't set releasever from base repo (%s): %s", method.method, e) try: proxy = getattr(method, "proxy", None) base_ksrepo = self.data.RepoData(name=constants.BASE_REPO_NAME, baseurl=url, mirrorlist=mirrorlist, metalink=metalink, noverifyssl=not sslverify, proxy=proxy) self._add_repo(base_ksrepo) except (payload.MetadataError, payload.PayloadError) as e: log.error("base repo (%s/%s) not valid -- removing it", method.method, url) log.error("reason for repo removal: %s", e) with self._repos_lock: self._base.repos.pop(constants.BASE_REPO_NAME, None) if not fallback: with self._repos_lock: for repo in self._base.repos.iter_enabled(): self.disableRepo(repo.id) return # this preserves the method details while disabling it method.method = None self.install_device = None # We need to check this again separately in case method.method was unset above. if not method.method: # If this is a kickstart install, just return now if flags.automatedInstall: return # Otherwise, fall back to the default repos that we disabled above with self._repos_lock: for (id_, repo) in self._base.repos.items(): if id_ in enabled: repo.enable() for ksrepo in self.data.repo.dataList(): log.debug("repo %s: mirrorlist %s, baseurl %s, metalink %s", ksrepo.name, ksrepo.mirrorlist, ksrepo.baseurl, ksrepo.metalink) # one of these must be set to create new repo if not (ksrepo.mirrorlist or ksrepo.baseurl or ksrepo.metalink or ksrepo.name in self._base.repos): raise payload.PayloadSetupError( "Repository %s has no mirror, baseurl or metalink set " "and is not one of the pre-defined repositories" % ksrepo.name) self._add_repo(ksrepo) ksnames = [r.name for r in self.data.repo.dataList()] ksnames.append(constants.BASE_REPO_NAME) with self._repos_lock: for repo in self._base.repos.iter_enabled(): id_ = repo.id if 'source' in id_ or 'debuginfo' in id_: self.disableRepo(id_) elif constants.isFinal and 'rawhide' in id_: self.disableRepo(id_)
def updateBaseRepo(self, fallback=True, checkmount=True): log.info('configuring base repo') self.reset() url, mirrorlist, sslverify = self._setupInstallDevice(self.storage, checkmount) method = self.data.method # Read in all the repos from the installation environment, make a note of which # are enabled, and then disable them all. If the user gave us a method, we want # to use that instead of the default repos. self._base.read_all_repos() enabled = [] with self._repos_lock: for repo in self._base.repos.iter_enabled(): enabled.append(repo.id) repo.disable() # If askmethod was specified on the command-line, leave all the repos # disabled and return if flags.askmethod: return if method.method: try: self._base.conf.releasever = self._getReleaseVersion(url) log.debug("releasever from %s is %s", url, self._base.conf.releasever) except configparser.MissingSectionHeaderError as e: log.error("couldn't set releasever from base repo (%s): %s", method.method, e) try: proxy = getattr(method, "proxy", None) base_ksrepo = self.data.RepoData( name=constants.BASE_REPO_NAME, baseurl=url, mirrorlist=mirrorlist, noverifyssl=not sslverify, proxy=proxy) self._add_repo(base_ksrepo) except (packaging.MetadataError, packaging.PayloadError) as e: log.error("base repo (%s/%s) not valid -- removing it", method.method, url) with self._repos_lock: self._base.repos.pop(constants.BASE_REPO_NAME, None) if not fallback: with self._repos_lock: for repo in self._base.repos.iter_enabled(): self.disableRepo(repo.id) return # this preserves the method details while disabling it method.method = None self.install_device = None # We need to check this again separately in case method.method was unset above. if not method.method: # If this is a kickstart install, just return now if flags.automatedInstall: return # Otherwise, fall back to the default repos that we disabled above with self._repos_lock: for (id_, repo) in self._base.repos.items(): if id_ in enabled: repo.enable() for ksrepo in self.data.repo.dataList(): log.debug("repo %s: mirrorlist %s, baseurl %s", ksrepo.name, ksrepo.mirrorlist, ksrepo.baseurl) # one of these must be set to create new repo if not (ksrepo.mirrorlist or ksrepo.baseurl or ksrepo.name in self._base.repos): raise packaging.PayloadSetupError("Repository %s has no mirror or baseurl set " "and is not one of the pre-defined repositories" % ksrepo.name) self._add_repo(ksrepo) ksnames = [r.name for r in self.data.repo.dataList()] ksnames.append(constants.BASE_REPO_NAME) with self._repos_lock: for repo in self._base.repos.iter_enabled(): id_ = repo.id if 'source' in id_ or 'debuginfo' in id_: self.disableRepo(id_) elif constants.isFinal and 'rawhide' in id_: self.disableRepo(id_)
def updateBaseRepo(self, fallback=True, checkmount=True): log.info('configuring base repo') self.reset() url, mirrorlist, sslverify = self._setupInstallDevice(self.storage, checkmount) method = self.data.method # Read in all the repos from the installation environment, make a note of which # are enabled, and then disable them all. If the user gave us a method, we want # to use that instead of the default repos. self._base.read_all_repos() enabled = [] for repo in self._base.repos.iter_enabled(): enabled.append(repo.id) repo.disable() # If askmethod was specified on the command-line, leave all the repos # disabled and return if flags.askmethod: return if method.method: try: self._base.conf.releasever = self._getReleaseVersion(url) log.debug("releasever from %s is %s", url, self._base.conf.releasever) except configparser.MissingSectionHeaderError as e: log.error("couldn't set releasever from base repo (%s): %s", method.method, e) try: proxy = getattr(method, "proxy", None) base_ksrepo = self.data.RepoData( name=constants.BASE_REPO_NAME, baseurl=url, mirrorlist=mirrorlist, noverifyssl=not sslverify, proxy=proxy) self._add_repo(base_ksrepo) except (packaging.MetadataError, packaging.PayloadError) as e: log.error("base repo (%s/%s) not valid -- removing it", method.method, url) self._base.repos.pop(constants.BASE_REPO_NAME, None) if not fallback: for repo in self._base.repos.iter_enabled(): self.disableRepo(repo.id) return # this preserves the method details while disabling it method.method = None self.install_device = None # We need to check this again separately in case method.method was unset above. if not method.method: # If this is a kickstart install, just return now if flags.automatedInstall: return # Otherwise, fall back to the default repos that we disabled above for (id_, repo) in self._base.repos.items(): if id_ in enabled: repo.enable() for ksrepo in self.data.repo.dataList(): self._add_repo(ksrepo) ksnames = [r.name for r in self.data.repo.dataList()] ksnames.append(constants.BASE_REPO_NAME) for repo in self._base.repos.iter_enabled(): id_ = repo.id if 'source' in id_ or 'debuginfo' in id_: self.disableRepo(id_) elif constants.isFinal and 'rawhide' in id_: self.disableRepo(id_)
def update_base_repo(self, fallback=True, checkmount=True): """Update the base repository from the DBus source.""" log.info("Configuring the base repo") self._reset_configuration() disabled_treeinfo_repo_names = self._cleanup_old_treeinfo_repositories() # Find the source and its type. source_proxy = self.get_source_proxy() source_type = source_proxy.Type # Change the default source to CDROM if there is a valid install media. # FIXME: Set up the default source earlier. if checkmount and self._is_source_default() and find_optical_install_media(): source_type = SOURCE_TYPE_CDROM source_proxy = create_source(source_type) set_source(self.proxy, source_proxy) # Set up the source. set_up_sources(self.proxy) # Read in all the repos from the installation environment, make a note of which # are enabled, and then disable them all. If the user gave us a method, we want # to use that instead of the default repos. self._base.read_all_repos() # Enable or disable updates. self.set_updates_enabled(self._updates_enabled) # Repo files are always loaded from the system. # When reloaded their state needs to be synchronized with the user configuration. # So we disable them now and enable them later if required. enabled = [] with self._repos_lock: for repo in self._base.repos.iter_enabled(): enabled.append(repo.id) repo.disable() # Add a new repo. if source_type not in SOURCE_REPO_FILE_TYPES: # Get the repo configuration of the first source. data = RepoConfigurationData.from_structure( self.proxy.GetRepoConfigurations()[0] ) log.debug("Using the repo configuration: %s", data) # Get the URL. install_tree_url = data.url if data.type == URL_TYPE_BASEURL else "" mirrorlist = data.url if data.type == URL_TYPE_MIRRORLIST else "" metalink = data.url if data.type == URL_TYPE_METALINK else "" # Fallback to the installation root. base_repo_url = install_tree_url try: self._refresh_install_tree(data) self._base.conf.releasever = self._get_release_version(install_tree_url) base_repo_url = self._get_base_repo_location(install_tree_url) log.debug("releasever from %s is %s", base_repo_url, self._base.conf.releasever) self._load_treeinfo_repositories(base_repo_url, disabled_treeinfo_repo_names, data) except configparser.MissingSectionHeaderError as e: log.error("couldn't set releasever from base repo (%s): %s", source_type, e) try: base_ksrepo = self.data.RepoData( name=constants.BASE_REPO_NAME, baseurl=base_repo_url, mirrorlist=mirrorlist, metalink=metalink, noverifyssl=not data.ssl_verification_enabled, proxy=data.proxy, sslcacert=data.ssl_configuration.ca_cert_path, sslclientcert=data.ssl_configuration.client_cert_path, sslclientkey=data.ssl_configuration.client_key_path ) self._add_repo_to_dnf(base_ksrepo) self._fetch_md(base_ksrepo.name) except (MetadataError, PayloadError) as e: log.error("base repo (%s/%s) not valid -- removing it", source_type, base_repo_url) log.error("reason for repo removal: %s", e) with self._repos_lock: self._base.repos.pop(constants.BASE_REPO_NAME, None) if not fallback: with self._repos_lock: for repo in self._base.repos.iter_enabled(): self._disable_repo(repo.id) return # Fallback to the default source # # This is at the moment CDN on RHEL # and closest mirror everywhere else. tear_down_sources(self.proxy) source_type = conf.payload.default_source source_proxy = create_source(source_type) set_source(self.proxy, source_proxy) set_up_sources(self.proxy) # We need to check this again separately in case REPO_FILES were set above. if source_type in SOURCE_REPO_FILE_TYPES: # If this is a kickstart install, just return now as we normally do not # want to read the on media repo files in such a case. On the other hand, # the local repo files are a valid use case if the system is subscribed # and the CDN is selected as the installation source. if self.source_type == SOURCE_TYPE_CDN and is_module_available(SUBSCRIPTION): # only check if the Subscription module is available & CDN is the # installation source subscription_proxy = SUBSCRIPTION.get_proxy() load_cdn_repos = subscription_proxy.IsSubscriptionAttached else: # if the Subscription module is not available, we simply can't use # the CDN repos, making our decision here simple load_cdn_repos = False if flags.automatedInstall and not load_cdn_repos: return # Otherwise, fall back to the default repos that we disabled above with self._repos_lock: for (id_, repo) in self._base.repos.items(): if id_ in enabled: log.debug("repo %s: fall back enabled from default repos", id_) repo.enable() for repo in self.addons: ksrepo = self.get_addon_repo(repo) if ksrepo.is_harddrive_based(): ksrepo.baseurl = self._setup_harddrive_addon_repo(ksrepo) log.debug("repo %s: mirrorlist %s, baseurl %s, metalink %s", ksrepo.name, ksrepo.mirrorlist, ksrepo.baseurl, ksrepo.metalink) # one of these must be set to create new repo if not (ksrepo.mirrorlist or ksrepo.baseurl or ksrepo.metalink or ksrepo.name in self._base.repos): raise PayloadSetupError("Repository %s has no mirror, baseurl or " "metalink set and is not one of " "the pre-defined repositories" % ksrepo.name) self._add_repo_to_dnf(ksrepo) with self._repos_lock: # disable unnecessary repos for repo in self._base.repos.iter_enabled(): id_ = repo.id if 'source' in id_ or 'debuginfo' in id_: self._disable_repo(id_) elif constants.isFinal and 'rawhide' in id_: self._disable_repo(id_) # fetch md for enabled repos enabled_repos = self._enabled_repos for repo_name in self.addons: if repo_name in enabled_repos: self._fetch_md(repo_name)
def test_disable(self): # dnf.repo.Repo.disable repo = dnf.repo.Repo() self.assertHasAttr(repo, "disable") repo.disable()