示例#1
0
	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)
示例#2
0
	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)
示例#3
0
		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
示例#4
0
    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]
示例#5
0
	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]