Example #1
0
	def _aux_get_return(self, future, mycpv, mylist, myebuild, ebuild_hash,
		mydata, mylocation, cache_me, proc):
		if future.cancelled():
			return
		if proc is not None:
			if proc.returncode != os.EX_OK:
				self._broken_ebuilds.add(myebuild)
				future.set_exception(PortageKeyError(mycpv))
				return
			mydata = proc.metadata
		mydata["repository"] = self.repositories.get_name_for_location(mylocation)
		mydata["_mtime_"] = ebuild_hash.mtime
		eapi = mydata.get("EAPI")
		if not eapi:
			eapi = "0"
			mydata["EAPI"] = eapi
		if eapi_is_supported(eapi):
			mydata["INHERITED"] = " ".join(mydata.get("_eclasses_", []))

		#finally, we look at our internal cache entry and return the requested data.
		returnme = [mydata.get(x, "") for x in mylist]

		if cache_me and self.frozen:
			aux_cache = {}
			for x in self._aux_cache_keys:
				aux_cache[x] = mydata.get(x, "")
			self._aux_cache[mycpv] = aux_cache

		future.set_result(returnme)
Example #2
0
    def _pull_valid_cache(self, cpv, ebuild_path, repo_path):
        try:
            ebuild_hash = eclass_cache.hashed_path(ebuild_path)
            # snag mtime since we use it later, and to trigger stat failure
            # if it doesn't exist
            ebuild_hash.mtime
        except FileNotFound:
            writemsg(_("!!! aux_get(): ebuild for " \
             "'%s' does not exist at:\n") % (cpv,), noiselevel=-1)
            writemsg("!!!            %s\n" % ebuild_path, noiselevel=-1)
            raise PortageKeyError(cpv)

        # Pull pre-generated metadata from the metadata/cache/
        # directory if it exists and is valid, otherwise fall
        # back to the normal writable cache.
        auxdbs = []
        pregen_auxdb = self._pregen_auxdb.get(repo_path)
        if pregen_auxdb is not None:
            auxdbs.append(pregen_auxdb)
        ro_auxdb = self._ro_auxdb.get(repo_path)
        if ro_auxdb is not None:
            auxdbs.append(ro_auxdb)
        auxdbs.append(self.auxdb[repo_path])
        eclass_db = self.repositories.get_repo_for_location(
            repo_path).eclass_db

        for auxdb in auxdbs:
            try:
                metadata = auxdb[cpv]
            except KeyError:
                continue
            except CacheError:
                if not auxdb.readonly:
                    try:
                        del auxdb[cpv]
                    except (KeyError, CacheError):
                        pass
                continue
            eapi = metadata.get('EAPI', '').strip()
            if not eapi:
                eapi = '0'
                metadata['EAPI'] = eapi
            if not eapi_is_supported(eapi):
                # Since we're supposed to be able to efficiently obtain the
                # EAPI from _parse_eapi_ebuild_head, we disregard cache entries
                # for unsupported EAPIs.
                continue
            if auxdb.validate_entry(metadata, ebuild_hash, eclass_db):
                break
        else:
            metadata = None

        return (metadata, ebuild_hash)
Example #3
0
	def async_aux_get(self, mycpv, mylist, mytree=None, myrepo=None, loop=None):
		"""
		Asynchronous form form of aux_get.

		@param mycpv: cpv for an ebuild
		@type mycpv: str
		@param mylist: list of metadata keys
		@type mylist: list
		@param mytree: The canonical path of the tree in which the ebuild
			is located, or None for automatic lookup
		@type mytree: str
		@param myrepo: name of the repo in which the ebuild is located,
			or None for automatic lookup
		@type myrepo: str
		@param loop: event loop (defaults to global event loop)
		@type loop: EventLoop
		@return: list of metadata values
		@rtype: asyncio.Future (or compatible)
		"""
		# Don't default to self._event_loop here, since that creates a
		# local event loop for thread safety, and that could easily lead
		# to simultaneous instantiation of multiple event loops here.
		# Callers of this method certainly want the same event loop to
		# be used for all calls.
		loop = asyncio._wrap_loop(loop)
		future = loop.create_future()
		cache_me = False
		if myrepo is not None:
			mytree = self.treemap.get(myrepo)
			if mytree is None:
				future.set_exception(PortageKeyError(myrepo))
				return future

		if mytree is not None and len(self.porttrees) == 1 \
			and mytree == self.porttrees[0]:
			# mytree matches our only tree, so it's safe to
			# ignore mytree and cache the result
			mytree = None
			myrepo = None

		if mytree is None:
			cache_me = True
		if mytree is None and not self._known_keys.intersection(
			mylist).difference(self._aux_cache_keys):
			aux_cache = self._aux_cache.get(mycpv)
			if aux_cache is not None:
				future.set_result([aux_cache.get(x, "") for x in mylist])
				return future
			cache_me = True

		try:
			cat, pkg = mycpv.split("/", 1)
		except ValueError:
			# Missing slash. Can't find ebuild so raise PortageKeyError.
			future.set_exception(PortageKeyError(mycpv))
			return future

		myebuild, mylocation = self.findname2(mycpv, mytree)

		if not myebuild:
			writemsg("!!! aux_get(): %s\n" % \
				_("ebuild not found for '%s'") % mycpv, noiselevel=1)
			future.set_exception(PortageKeyError(mycpv))
			return future

		mydata, ebuild_hash = self._pull_valid_cache(mycpv, myebuild, mylocation)

		if mydata is not None:
			self._aux_get_return(
				future, mycpv, mylist, myebuild, ebuild_hash,
				mydata, mylocation, cache_me, None)
			return future

		if myebuild in self._broken_ebuilds:
			future.set_exception(PortageKeyError(mycpv))
			return future

		proc = EbuildMetadataPhase(cpv=mycpv,
			ebuild_hash=ebuild_hash, portdb=self,
			repo_path=mylocation, scheduler=loop,
			settings=self.doebuild_settings)

		proc.addExitListener(functools.partial(self._aux_get_return,
			future, mycpv, mylist, myebuild, ebuild_hash, mydata, mylocation,
			cache_me))
		future.add_done_callback(functools.partial(self._aux_get_cancel, proc))
		proc.start()
		return future
Example #4
0
	def aux_get(self, mycpv, mylist, mytree=None, myrepo=None):
		"stub code for returning auxilliary db information, such as SLOT, DEPEND, etc."
		'input: "sys-apps/foo-1.0",["SLOT","DEPEND","HOMEPAGE"]'
		'return: ["0",">=sys-libs/bar-1.0","http://www.foo.com"] or raise PortageKeyError if error'
		cache_me = False
		if myrepo is not None:
			mytree = self.treemap.get(myrepo)
			if mytree is None:
				raise PortageKeyError(myrepo)

		if mytree is not None and len(self.porttrees) == 1 \
			and mytree == self.porttrees[0]:
			# mytree matches our only tree, so it's safe to
			# ignore mytree and cache the result
			mytree = None
			myrepo = None

		if mytree is None:
			cache_me = True
		if mytree is None and not self._known_keys.intersection(
			mylist).difference(self._aux_cache_keys):
			aux_cache = self._aux_cache.get(mycpv)
			if aux_cache is not None:
				return [aux_cache.get(x, "") for x in mylist]
			cache_me = True

		try:
			cat, pkg = mycpv.split("/", 1)
		except ValueError:
			# Missing slash. Can't find ebuild so raise PortageKeyError.
			raise PortageKeyError(mycpv)

		myebuild, mylocation = self.findname2(mycpv, mytree)

		if not myebuild:
			writemsg("!!! aux_get(): %s\n" % \
				_("ebuild not found for '%s'") % mycpv, noiselevel=1)
			raise PortageKeyError(mycpv)

		mydata, ebuild_hash = self._pull_valid_cache(mycpv, myebuild, mylocation)
		doregen = mydata is None

		if doregen:
			if myebuild in self._broken_ebuilds:
				raise PortageKeyError(mycpv)

			proc = EbuildMetadataPhase(cpv=mycpv,
				ebuild_hash=ebuild_hash, portdb=self,
				repo_path=mylocation, scheduler=self._event_loop,
				settings=self.doebuild_settings)

			proc.start()
			proc.wait()

			if proc.returncode != os.EX_OK:
				self._broken_ebuilds.add(myebuild)
				raise PortageKeyError(mycpv)

			mydata = proc.metadata

		mydata["repository"] = self.repositories.get_name_for_location(mylocation)
		mydata["_mtime_"] = ebuild_hash.mtime
		eapi = mydata.get("EAPI")
		if not eapi:
			eapi = "0"
			mydata["EAPI"] = eapi
		if eapi_is_supported(eapi):
			mydata["INHERITED"] = " ".join(mydata.get("_eclasses_", []))

		#finally, we look at our internal cache entry and return the requested data.
		returnme = [mydata.get(x, "") for x in mylist]

		if cache_me and self.frozen:
			aux_cache = {}
			for x in self._aux_cache_keys:
				aux_cache[x] = mydata.get(x, "")
			self._aux_cache[mycpv] = aux_cache

		return returnme