def report_error(self, exception, tb = None): """Report an exception to the user. @param exception: the exception to report @type exception: L{SafeException} @param tb: optional traceback @since: 0.25""" import logging logger.warning("%s", str(exception) or type(exception), exc_info = (exception, exception, tb) if logger.isEnabledFor(logging.INFO) else None)
def add_iface(uri, arch): """Name implementations from feed and assert that only one can be selected.""" if uri in ifaces_processed: return ifaces_processed.add(uri) iface = iface_cache.get_interface(uri) main_feed = iface_cache.get_feed(uri) if main_feed: replacement = main_feed.get_replaced_by() if replacement is not None: replacement_for[iface] = iface_cache.get_interface(replacement) impls = [] for f in usable_feeds(iface, arch): self.feeds_used.add(f) logger.debug(_("Processing feed %s"), f) try: feed = iface_cache.get_feed(f) if feed is None: continue #if feed.name and iface.uri != feed.url and iface.uri not in feed.feed_for: # info(_("Missing <feed-for> for '%(uri)s' in '%(feed)s'"), {'uri': iface.uri, 'feed': f}) if feed.implementations: impls.extend(feed.implementations.values()) distro_feed_url = feed.get_distro_feed() if distro_feed_url: self.feeds_used.add(distro_feed_url) distro_feed = iface_cache.get_feed(distro_feed_url) if distro_feed.implementations: impls.extend(distro_feed.implementations.values()) except MissingLocalFeed as ex: logger.warning(_("Missing local feed; if it's no longer required, remove it with:") + '\n0install remove-feed ' + iface.uri + ' ' + f, {'feed': f, 'interface': iface, 'exception': ex}) except model.SafeException as ex: logger.warning(_("Failed to load feed %(feed)s for %(interface)s: %(exception)s"), {'feed': f, 'interface': iface, 'exception': ex}) #raise except Exception as ex: import logging logger.warning(_("Failed to load feed %(feed)s for %(interface)s: %(exception)s"), {'feed': f, 'interface': iface, 'exception': ex}, exc_info = True if logger.isEnabledFor(logging.INFO) else None) impls.sort(key = lambda impl: self.get_rating(iface, impl, arch), reverse = True) impls_for_iface[iface] = filtered_impls = [] my_extra_restrictions = self.extra_restrictions.get(iface, []) if self.details is not False: self.details[iface] = [(impl, get_unusable_reason(impl, my_extra_restrictions, arch)) for impl in impls] impl_to_var = iface_to_vars[iface] # Impl -> sat var var_names = [] for impl in impls: if is_unusable(impl, my_extra_restrictions, arch): continue filtered_impls.append(impl) assert impl not in impl_to_var, impl v = problem.add_variable(ImplInfo(iface, impl, arch)) impl_to_var[impl] = v var_names.append(v) if impl.machine and impl.machine != 'src': impls_for_machine_group[machine_groups.get(impl.machine, 0)].append(v) process_dependencies(v, impl, arch) if closest_match: dummy_impl = _DummyImpl() dummy_var = problem.add_variable(ImplInfo(iface, dummy_impl, arch, dummy = True)) var_names.append(dummy_var) impl_to_var[dummy_impl] = dummy_var filtered_impls.append(dummy_impl) # Only one implementation of this interface can be selected if uri == root_interface: if var_names: clause = problem.at_most_one(var_names) problem.add_clause(var_names) # at least one else: problem.impossible() clause = False elif var_names: clause = problem.at_most_one(var_names) else: # Don't need to add to group_clause_for because we should # never get a possible selection involving this. return assert clause is not True assert clause is not None if clause is not False: group_clause_for[uri] = clause
def solve_with_downloads(self, force=False, update_local=False): """Run the solver, then download any feeds that are missing or that need to be updated. Each time a new feed is imported into the cache, the solver is run again, possibly adding new downloads. @param force: whether to download even if we're already ready to run. @type force: bool @param update_local: fetch PackageKit feeds even if we're ready to run. @type update_local: bool""" downloads_finished = set() # Successful or otherwise downloads_in_progress = {} # URL -> Download # There are three cases: # 1. We want to run immediately if possible. If not, download all the information we can. # (force = False, update_local = False) # 2. We're in no hurry, but don't want to use the network unnecessarily. # We should still update local information (from PackageKit). # (force = False, update_local = True) # 3. The user explicitly asked us to refresh everything. # (force = True) try_quick_exit = not (force or update_local) while True: self.solver.solve_for(self.requirements) for w in self.watchers: w() if try_quick_exit and self.solver.ready: break try_quick_exit = False if not self.solver.ready: force = True for f in self.solver.feeds_used: if f in downloads_finished or f in downloads_in_progress: continue if os.path.isabs(f): if force: try: self.config.iface_cache.get_feed(f, force=True) except reader.MissingLocalFeed as ex: logger.warning( "Reloading %s: %s", f, ex, exc_info=True if logger.isEnabledFor(logging.INFO) else None) downloads_in_progress[f] = tasks.IdleBlocker( 'Refresh local feed') continue elif f.startswith('distribution:'): if force or update_local: downloads_in_progress[ f] = self.config.fetcher.download_and_import_feed( f, self.config.iface_cache) elif force and self.config.network_use != network_offline: downloads_in_progress[ f] = self.config.fetcher.download_and_import_feed( f, self.config.iface_cache) # Once we've starting downloading some things, # we might as well get them all. force = True if not downloads_in_progress: if self.config.network_use == network_offline: logger.info( _("Can't choose versions and in off-line mode, so aborting" )) break # Wait for at least one download to finish blockers = downloads_in_progress.values() yield blockers tasks.check(blockers, self.config.handler.report_error) for f in list(downloads_in_progress.keys()): if f in downloads_in_progress and downloads_in_progress[ f].happened: del downloads_in_progress[f] downloads_finished.add(f) # Need to refetch any "distribution" feed that # depends on this one distro_feed_url = 'distribution:' + f if distro_feed_url in downloads_finished: downloads_finished.remove(distro_feed_url) if distro_feed_url in downloads_in_progress: del downloads_in_progress[distro_feed_url]
def solve_with_downloads(self, force = False, update_local = False): """Run the solver, then download any feeds that are missing or that need to be updated. Each time a new feed is imported into the cache, the solver is run again, possibly adding new downloads. @param force: whether to download even if we're already ready to run. @type force: bool @param update_local: fetch PackageKit feeds even if we're ready to run. @type update_local: bool""" downloads_finished = set() # Successful or otherwise downloads_in_progress = {} # URL -> Download # There are three cases: # 1. We want to run immediately if possible. If not, download all the information we can. # (force = False, update_local = False) # 2. We're in no hurry, but don't want to use the network unnecessarily. # We should still update local information (from PackageKit). # (force = False, update_local = True) # 3. The user explicitly asked us to refresh everything. # (force = True) try_quick_exit = not (force or update_local) while True: self.solver.solve_for(self.requirements) for w in self.watchers: w() if try_quick_exit and self.solver.ready: break try_quick_exit = False if not self.solver.ready: force = True for f in self.solver.feeds_used: if f in downloads_finished or f in downloads_in_progress: continue if os.path.isabs(f): if force: try: self.config.iface_cache.get_feed(f, force = True) except reader.MissingLocalFeed as ex: logger.warning("Reloading %s: %s", f, ex, exc_info = True if logger.isEnabledFor(logging.INFO) else None) downloads_in_progress[f] = tasks.IdleBlocker('Refresh local feed') continue elif f.startswith('distribution:'): if force or update_local: downloads_in_progress[f] = self.config.fetcher.download_and_import_feed(f, self.config.iface_cache) elif force and self.config.network_use != network_offline: downloads_in_progress[f] = self.config.fetcher.download_and_import_feed(f, self.config.iface_cache) # Once we've starting downloading some things, # we might as well get them all. force = True if not downloads_in_progress: if self.config.network_use == network_offline: logger.info(_("Can't choose versions and in off-line mode, so aborting")) break # Wait for at least one download to finish blockers = downloads_in_progress.values() yield blockers tasks.check(blockers, self.config.handler.report_error) for f in list(downloads_in_progress.keys()): if f in downloads_in_progress and downloads_in_progress[f].happened: del downloads_in_progress[f] downloads_finished.add(f) # Need to refetch any "distribution" feed that # depends on this one distro_feed_url = 'distribution:' + f if distro_feed_url in downloads_finished: downloads_finished.remove(distro_feed_url) if distro_feed_url in downloads_in_progress: del downloads_in_progress[distro_feed_url]