diff options
-rw-r--r-- | pym/dbapi/__init__.py | 55 | ||||
-rw-r--r-- | pym/dbapi/binpkg.py | 65 | ||||
-rw-r--r-- | pym/dbapi/ebuild.py | 667 | ||||
-rw-r--r-- | pym/dbapi/fake.py | 99 | ||||
-rw-r--r-- | pym/dbapi/vardb.py | 394 |
5 files changed, 0 insertions, 1280 deletions
diff --git a/pym/dbapi/__init__.py b/pym/dbapi/__init__.py deleted file mode 100644 index 7358393e0..000000000 --- a/pym/dbapi/__init__.py +++ /dev/null @@ -1,55 +0,0 @@ -from portage import dep_expand, writemsg -from portage_dep import dep_getkey, dep_getslot, match_from_list -from output import red -import portage_locks -import os, re - -class dbapi: - def __init__(self): - pass - - def close_caches(self): - pass - - def cp_list(self,cp,use_cache=1): - return - - def cpv_all(self): - cpv_list = [] - for cp in self.cp_all(): - cpv_list.extend(self.cp_list(cp)) - return cpv_list - - def aux_get(self,mycpv,mylist): - "stub code for returning auxiliary 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 [] if mycpv not found' - raise NotImplementedError - - def match(self,origdep,use_cache=1): - mydep = dep_expand(origdep, mydb=self, settings=self.settings) - mykey=dep_getkey(mydep) - mylist = match_from_list(mydep,self.cp_list(mykey,use_cache=use_cache)) - myslot = dep_getslot(mydep) - if myslot is not None: - mylist = [cpv for cpv in mylist \ - if self.aux_get(cpv, ["SLOT"])[0] == myslot] - return mylist - - def match2(self,mydep,mykey,mylist): - writemsg("DEPRECATED: dbapi.match2\n") - match_from_list(mydep,mylist) - - def invalidentry(self, mypath): - if re.search("portage_lockfile$",mypath): - if not os.environ.has_key("PORTAGE_MASTER_PID"): - writemsg("Lockfile removed: %s\n" % mypath, 1) - portage_locks.unlockfile((mypath,None,None)) - else: - # Nothing we can do about it. We're probably sandboxed. - pass - elif re.search(".*/-MERGING-(.*)",mypath): - if os.path.exists(mypath): - writemsg(red("INCOMPLETE MERGE:")+" "+mypath+"\n", noiselevel=-1) - else: - writemsg("!!! Invalid db entry: %s\n" % mypath, noiselevel=-1) diff --git a/pym/dbapi/binpkg.py b/pym/dbapi/binpkg.py deleted file mode 100644 index f3ee215be..000000000 --- a/pym/dbapi/binpkg.py +++ /dev/null @@ -1,65 +0,0 @@ -from dbapi.fake import fakedbapi -from portage import settings -import xpak, os - -class bindbapi(fakedbapi): - def __init__(self, mybintree=None, settings=None): - self.bintree = mybintree - self.cpvdict={} - self.cpdict={} - if settings is None: - settings = globals()["settings"] - self.settings = settings - self._match_cache = {} - - def match(self, *pargs, **kwargs): - if self.bintree and not self.bintree.populated: - self.bintree.populate() - return fakedbapi.match(self, *pargs, **kwargs) - - def aux_get(self,mycpv,wants): - if self.bintree and not self.bintree.populated: - self.bintree.populate() - mysplit = mycpv.split("/") - mylist = [] - tbz2name = mysplit[1]+".tbz2" - if self.bintree and not self.bintree.isremote(mycpv): - tbz2 = xpak.tbz2(self.bintree.getname(mycpv)) - for x in wants: - if self.bintree and self.bintree.isremote(mycpv): - # We use the cache for remote packages - mylist.append(" ".join( - self.bintree.remotepkgs[tbz2name].get(x,"").split())) - else: - myval = tbz2.getfile(x) - if myval is None: - myval = "" - else: - myval = " ".join(myval.split()) - mylist.append(myval) - if "EAPI" in wants: - idx = wants.index("EAPI") - if not mylist[idx]: - mylist[idx] = "0" - return mylist - - def aux_update(self, cpv, values): - if not self.bintree.populated: - self.bintree.populate() - tbz2path = self.bintree.getname(cpv) - if not os.path.exists(tbz2path): - raise KeyError(cpv) - mytbz2 = xpak.tbz2(tbz2path) - mydata = mytbz2.get_data() - mydata.update(values) - mytbz2.recompose_mem(xpak.xpak_mem(mydata)) - - def cp_list(self, *pargs, **kwargs): - if not self.bintree.populated: - self.bintree.populate() - return fakedbapi.cp_list(self, *pargs, **kwargs) - - def cpv_all(self): - if not self.bintree.populated: - self.bintree.populate() - return fakedbapi.cpv_all(self) diff --git a/pym/dbapi/ebuild.py b/pym/dbapi/ebuild.py deleted file mode 100644 index d96d6a120..000000000 --- a/pym/dbapi/ebuild.py +++ /dev/null @@ -1,667 +0,0 @@ -from dbapi import dbapi -from portage import settings, config, auxdbkeys, auxdbkeylen, doebuild, eapi_is_supported, flatten, listdir -from portage_data import portage_gid -from portage_util import ensure_dirs, apply_recursive_permissions, writemsg -from portage_versions import pkgsplit, catpksplit, best -from portage_dep import use_reduce, paren_reduce, dep_expand, dep_getkey, dep_getslot, match_from_list, match_to_list -from portage_manifest import Manifest -from output import red - -import eclass_cache, portage_exception, portage_gpg, portage_locks, portage_checksum -import os, sys - -def close_portdbapi_caches(): - for i in portdbapi.portdbapi_instances: - i.close_caches() - - -class portdbapi(dbapi): - """this tree will scan a portage directory located at root (passed to init)""" - portdbapi_instances = [] - - def __init__(self,porttree_root,mysettings=None): - portdbapi.portdbapi_instances.append(self) - - if mysettings: - self.mysettings = mysettings - else: - global settings - self.mysettings = config(clone=settings) - - # This is strictly for use in aux_get() doebuild calls when metadata - # is generated by the depend phase. It's safest to use a clone for - # this purpose because doebuild makes many changes to the config - # instance that is passed in. - self.doebuild_settings = config(clone=self.mysettings) - - self.manifestVerifyLevel = None - self.manifestVerifier = None - self.manifestCache = {} # {location: [stat, md5]} - self.manifestMissingCache = [] - - if "gpg" in self.mysettings.features: - self.manifestVerifyLevel = portage_gpg.EXISTS - if "strict" in self.mysettings.features: - self.manifestVerifyLevel = portage_gpg.MARGINAL - self.manifestVerifier = portage_gpg.FileChecker(self.mysettings["PORTAGE_GPG_DIR"], "gentoo.gpg", minimumTrust=self.manifestVerifyLevel) - elif "severe" in self.mysettings.features: - self.manifestVerifyLevel = portage_gpg.TRUSTED - self.manifestVerifier = portage_gpg.FileChecker(self.mysettings["PORTAGE_GPG_DIR"], "gentoo.gpg", requireSignedRing=True, minimumTrust=self.manifestVerifyLevel) - else: - self.manifestVerifier = portage_gpg.FileChecker(self.mysettings["PORTAGE_GPG_DIR"], "gentoo.gpg", minimumTrust=self.manifestVerifyLevel) - - #self.root=settings["PORTDIR"] - self.porttree_root = os.path.realpath(porttree_root) - - self.depcachedir = self.mysettings.depcachedir[:] - - self.tmpfs = self.mysettings["PORTAGE_TMPFS"] - if self.tmpfs and not os.path.exists(self.tmpfs): - self.tmpfs = None - if self.tmpfs and not os.access(self.tmpfs, os.W_OK): - self.tmpfs = None - if self.tmpfs and not os.access(self.tmpfs, os.R_OK): - self.tmpfs = None - - self.eclassdb = eclass_cache.cache(self.porttree_root, - overlays=self.mysettings["PORTDIR_OVERLAY"].split()) - - self.metadb = {} - self.metadbmodule = self.mysettings.load_best_module("portdbapi.metadbmodule") - - #if the portdbapi is "frozen", then we assume that we can cache everything (that no updates to it are happening) - self.xcache={} - self.frozen=0 - - self.porttrees = [self.porttree_root] + \ - [os.path.realpath(t) for t in self.mysettings["PORTDIR_OVERLAY"].split()] - self.auxdbmodule = self.mysettings.load_best_module("portdbapi.auxdbmodule") - self.auxdb = {} - self._init_cache_dirs() - # XXX: REMOVE THIS ONCE UNUSED_0 IS YANKED FROM auxdbkeys - # ~harring - filtered_auxdbkeys = filter(lambda x: not x.startswith("UNUSED_0"), auxdbkeys) - for x in self.porttrees: - # location, label, auxdbkeys - self.auxdb[x] = self.auxdbmodule(self.depcachedir, x, filtered_auxdbkeys, gid=portage_gid) - self._gvisible_aux_cache = {} - - def _init_cache_dirs(self): - """Create /var/cache/edb/dep and adjust permissions for the portage - group.""" - - dirmode = 02070 - filemode = 060 - modemask = 02 - - try: - for mydir in (self.depcachedir,): - if ensure_dirs(mydir, gid=portage_gid, mode=dirmode, mask=modemask): - writemsg("Adjusting permissions recursively: '%s'\n" % mydir, - noiselevel=-1) - def onerror(e): - raise # bail out on the first error that occurs during recursion - if not apply_recursive_permissions(mydir, - gid=portage_gid, dirmode=dirmode, dirmask=modemask, - filemode=filemode, filemask=modemask, onerror=onerror): - raise portage_exception.OperationNotPermitted( - "Failed to apply recursive permissions for the portage group.") - except portage_exception.PortageException, e: - pass - - def close_caches(self): - for x in self.auxdb.keys(): - self.auxdb[x].sync() - self.auxdb.clear() - - def flush_cache(self): - self.metadb = {} - self.auxdb = {} - - def finddigest(self,mycpv): - try: - mydig = self.findname2(mycpv)[0] - mydigs = mydig.split("/")[:-1] - mydig = "/".join(mydigs) - - mysplit = mycpv.split("/") - except SystemExit, e: - raise - except: - return "" - return mydig+"/files/digest-"+mysplit[-1] - - def findname(self,mycpv): - return self.findname2(mycpv)[0] - - def findname2(self, mycpv, mytree=None): - """ - Returns the location of the CPV, and what overlay it was in. - Searches overlays first, then PORTDIR; this allows us to return the first - matching file. As opposed to starting in portdir and then doing overlays - second, we would have to exhaustively search the overlays until we found - the file we wanted. - """ - if not mycpv: - return "",0 - mysplit=mycpv.split("/") - psplit=pkgsplit(mysplit[1]) - - if mytree: - mytrees = [mytree] - else: - mytrees = self.porttrees[:] - mytrees.reverse() - if psplit: - for x in mytrees: - file=x+"/"+mysplit[0]+"/"+psplit[0]+"/"+mysplit[1]+".ebuild" - if os.access(file, os.R_OK): - return[file, x] - return None, 0 - - def aux_get(self, mycpv, mylist, mytree=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 KeyError if error' - global auxdbkeys,auxdbkeylen - cat,pkg = mycpv.split("/", 1) - - myebuild, mylocation = self.findname2(mycpv, mytree) - - if not myebuild: - writemsg("!!! aux_get(): ebuild path for '%(cpv)s' not specified:\n" % {"cpv":mycpv}, - noiselevel=1) - writemsg("!!! %s\n" % myebuild, noiselevel=1) - raise KeyError(mycpv) - - myManifestPath = "/".join(myebuild.split("/")[:-1])+"/Manifest" - if "gpg" in self.mysettings.features: - try: - mys = portage_gpg.fileStats(myManifestPath) - if (myManifestPath in self.manifestCache) and \ - (self.manifestCache[myManifestPath] == mys): - pass - elif self.manifestVerifier: - if not self.manifestVerifier.verify(myManifestPath): - # Verification failed the desired level. - raise portage_exception.UntrustedSignature, "Untrusted Manifest: %(manifest)s" % {"manifest":myManifestPath} - - if ("severe" in self.mysettings.features) and \ - (mys != portage_gpg.fileStats(myManifestPath)): - raise portage_exception.SecurityViolation, "Manifest changed: %(manifest)s" % {"manifest":myManifestPath} - - except portage_exception.InvalidSignature, e: - if ("strict" in self.mysettings.features) or \ - ("severe" in self.mysettings.features): - raise - writemsg("!!! INVALID MANIFEST SIGNATURE DETECTED: %(manifest)s\n" % {"manifest":myManifestPath}) - except portage_exception.MissingSignature, e: - if ("severe" in self.mysettings.features): - raise - if ("strict" in self.mysettings.features): - if myManifestPath not in self.manifestMissingCache: - writemsg("!!! WARNING: Missing signature in: %(manifest)s\n" % {"manifest":myManifestPath}) - self.manifestMissingCache.insert(0,myManifestPath) - except (OSError,portage_exception.FileNotFound), e: - if ("strict" in self.mysettings.features) or \ - ("severe" in self.mysettings.features): - raise portage_exception.SecurityViolation, "Error in verification of signatures: %(errormsg)s" % {"errormsg":str(e)} - writemsg("!!! Manifest is missing or inaccessable: %(manifest)s\n" % {"manifest":myManifestPath}, - noiselevel=-1) - - - if os.access(myebuild, os.R_OK): - emtime=os.stat(myebuild)[stat.ST_MTIME] - else: - writemsg("!!! aux_get(): ebuild for '%(cpv)s' does not exist at:\n" % {"cpv":mycpv}, - noiselevel=-1) - writemsg("!!! %s\n" % myebuild, - noiselevel=-1) - raise KeyError - - try: - mydata = self.auxdb[mylocation][mycpv] - if emtime != long(mydata.get("_mtime_", 0)): - doregen = True - elif len(mydata.get("_eclasses_", [])) > 0: - doregen = not self.eclassdb.is_eclass_data_valid(mydata["_eclasses_"]) - else: - doregen = False - - except KeyError: - doregen = True - except CacheError: - doregen = True - try: del self.auxdb[mylocation][mycpv] - except KeyError: pass - - writemsg("auxdb is valid: "+str(not doregen)+" "+str(pkg)+"\n", 2) - - if doregen: - writemsg("doregen: %s %s\n" % (doregen,mycpv), 2) - writemsg("Generating cache entry(0) for: "+str(myebuild)+"\n",1) - - if self.tmpfs: - mydbkey = self.tmpfs+"/aux_db_key_temp" - else: - mydbkey = self.depcachedir+"/aux_db_key_temp" - - mylock = None - try: - mylock = portage_locks.lockfile(mydbkey, wantnewlockfile=1) - try: - os.unlink(mydbkey) - except (IOError, OSError), e: - if e.errno != errno.ENOENT: - raise - del e - - self.doebuild_settings.reset() - myret = doebuild(myebuild, "depend", "/", - self.doebuild_settings, dbkey=mydbkey, tree="porttree", - mydbapi=self) - if myret != os.EX_OK: - #depend returned non-zero exit code... - writemsg((red("\naux_get():") + \ - " (0) Error in '%s'. (%s)\n" + \ - " Check for syntax error or " + \ - "corruption in the ebuild. (--debug)\n\n") % \ - (myebuild, myret), noiselevel=-1) - raise KeyError(mycpv) - - try: - mycent = open(mydbkey, "r") - os.unlink(mydbkey) - mylines = mycent.readlines() - mycent.close() - except (IOError, OSError): - writemsg((red("\naux_get():") + \ - " (1) Error in '%s' ebuild.\n" + \ - " Check for syntax error or " + \ - "corruption in the ebuild. (--debug)\n\n") % myebuild, - noiselevel=-1) - raise KeyError(mycpv) - finally: - if mylock: - portage_locks.unlockfile(mylock) - - mydata = {} - for x in range(0,len(mylines)): - if mylines[x][-1] == '\n': - mylines[x] = mylines[x][:-1] - mydata[auxdbkeys[x]] = mylines[x] - - if "EAPI" not in mydata or not mydata["EAPI"].strip(): - mydata["EAPI"] = "0" - - if not eapi_is_supported(mydata["EAPI"]): - # if newer version, wipe everything and negate eapi - eapi = mydata["EAPI"] - mydata = {} - map(lambda x:mydata.setdefault(x, ""), auxdbkeys) - mydata["EAPI"] = "-"+eapi - - if mydata.get("INHERITED", False): - mydata["_eclasses_"] = self.eclassdb.get_eclass_data(mydata["INHERITED"].split()) - else: - mydata["_eclasses_"] = {} - - del mydata["INHERITED"] - - mydata["_mtime_"] = emtime - - self.auxdb[mylocation][mycpv] = mydata - - #finally, we look at our internal cache entry and return the requested data. - returnme = [] - for x in mylist: - if x == "INHERITED": - returnme.append(' '.join(mydata.get("_eclasses_", {}).keys())) - else: - returnme.append(mydata.get(x,"")) - - if "EAPI" in mylist: - idx = mylist.index("EAPI") - if not returnme[idx]: - returnme[idx] = "0" - - return returnme - - def getfetchlist(self, mypkg, useflags=None, mysettings=None, all=0, mytree=None): - if mysettings is None: - mysettings = self.mysettings - try: - myuris = self.aux_get(mypkg, ["SRC_URI"], mytree=mytree)[0] - except (IOError,KeyError): - print red("getfetchlist():")+" aux_get() error reading "+mypkg+"; aborting." - sys.exit(1) - - if useflags is None: - useflags = mysettings["USE"].split() - - myurilist = paren_reduce(myuris) - myurilist = use_reduce(myurilist,uselist=useflags,matchall=all) - newuris = flatten(myurilist) - - myfiles = [] - for x in newuris: - mya = os.path.basename(x) - if not mya in myfiles: - myfiles.append(mya) - return [newuris, myfiles] - - def getfetchsizes(self,mypkg,useflags=None,debug=0): - # returns a filename:size dictionnary of remaining downloads - myebuild = self.findname(mypkg) - pkgdir = os.path.dirname(myebuild) - mf = Manifest(pkgdir, self.mysettings["DISTDIR"]) - checksums = mf.getDigests() - if not checksums: - if debug: print "[empty/missing/bad digest]: "+mypkg - return None - filesdict={} - if useflags is None: - myuris, myfiles = self.getfetchlist(mypkg,all=1) - else: - myuris, myfiles = self.getfetchlist(mypkg,useflags=useflags) - #XXX: maybe this should be improved: take partial downloads - # into account? check checksums? - for myfile in myfiles: - if myfile not in checksums: - if debug: - writemsg("[bad digest]: missing %s for %s\n" % (myfile, mypkg)) - continue - file_path = os.path.join(self.mysettings["DISTDIR"], myfile) - mystat = None - try: - mystat = os.stat(file_path) - except OSError, e: - pass - if mystat is None: - existing_size = 0 - else: - existing_size = mystat.st_size - remaining_size = int(checksums[myfile]["size"]) - existing_size - if remaining_size > 0: - # Assume the download is resumable. - filesdict[myfile] = remaining_size - elif remaining_size < 0: - # The existing file is too large and therefore corrupt. - filesdict[myfile] = int(checksums[myfile]["size"]) - return filesdict - - def fetch_check(self, mypkg, useflags=None, mysettings=None, all=False): - if not useflags: - if mysettings: - useflags = mysettings["USE"].split() - myuri, myfiles = self.getfetchlist(mypkg, useflags=useflags, mysettings=mysettings, all=all) - myebuild = self.findname(mypkg) - pkgdir = os.path.dirname(myebuild) - mf = Manifest(pkgdir, self.mysettings["DISTDIR"]) - mysums = mf.getDigests() - - failures = {} - for x in myfiles: - if not mysums or x not in mysums: - ok = False - reason = "digest missing" - else: - try: - ok, reason = portage_checksum.verify_all( - os.path.join(self.mysettings["DISTDIR"], x), mysums[x]) - except portage_exception.FileNotFound, e: - ok = False - reason = "File Not Found: '%s'" % str(e) - if not ok: - failures[x] = reason - if failures: - return False - return True - - def getsize(self,mypkg,useflags=None,debug=0): - # returns the total size of remaining downloads - # - # we use getfetchsizes() now, so this function would be obsoleted - # - filesdict=self.getfetchsizes(mypkg,useflags=useflags,debug=debug) - if filesdict is None: - return "[empty/missing/bad digest]" - mysize=0 - for myfile in filesdict.keys(): - mysum+=filesdict[myfile] - return mysum - - def cpv_exists(self,mykey): - "Tells us whether an actual ebuild exists on disk (no masking)" - cps2=mykey.split("/") - cps=catpkgsplit(mykey,silent=0) - if not cps: - #invalid cat/pkg-v - return 0 - if self.findname(cps[0]+"/"+cps2[1]): - return 1 - else: - return 0 - - def cp_all(self): - "returns a list of all keys in our tree" - d={} - for x in self.mysettings.categories: - for oroot in self.porttrees: - for y in listdir(oroot+"/"+x,EmptyOnError=1,ignorecvs=1,dirsonly=1): - d[x+"/"+y] = None - l = d.keys() - l.sort() - return l - - def p_list(self,mycp): - d={} - for oroot in self.porttrees: - for x in listdir(oroot+"/"+mycp,EmptyOnError=1,ignorecvs=1): - if x[-7:]==".ebuild": - d[x[:-7]] = None - return d.keys() - - def cp_list(self, mycp, use_cache=1, mytree=None): - mysplit=mycp.split("/") - d={} - if mytree: - mytrees = [mytree] - else: - mytrees = self.porttrees - for oroot in mytrees: - for x in listdir(oroot+"/"+mycp,EmptyOnError=1,ignorecvs=1): - if x[-7:]==".ebuild": - d[mysplit[0]+"/"+x[:-7]] = None - return d.keys() - - def freeze(self): - for x in ["list-visible","bestmatch-visible","match-visible","match-all"]: - self.xcache[x]={} - self.frozen=1 - - def melt(self): - self.xcache={} - self.frozen=0 - - def xmatch(self,level,origdep,mydep=None,mykey=None,mylist=None): - "caching match function; very trick stuff" - #if no updates are being made to the tree, we can consult our xcache... - if self.frozen: - try: - return self.xcache[level][origdep] - except KeyError: - pass - - if not mydep: - #this stuff only runs on first call of xmatch() - #create mydep, mykey from origdep - mydep = dep_expand(origdep, mydb=self, settings=self.mysettings) - mykey=dep_getkey(mydep) - - if level=="list-visible": - #a list of all visible packages, not called directly (just by xmatch()) - #myval=self.visible(self.cp_list(mykey)) - myval=self.gvisible(self.visible(self.cp_list(mykey))) - elif level=="bestmatch-visible": - #dep match -- best match of all visible packages - myval=best(self.xmatch("match-visible",None,mydep=mydep,mykey=mykey)) - #get all visible matches (from xmatch()), then choose the best one - elif level=="bestmatch-list": - #dep match -- find best match but restrict search to sublist - myval=best(match_from_list(mydep,mylist)) - #no point is calling xmatch again since we're not caching list deps - elif level=="match-list": - #dep match -- find all matches but restrict search to sublist (used in 2nd half of visible()) - myval=match_from_list(mydep,mylist) - elif level=="match-visible": - #dep match -- find all visible matches - myval=match_from_list(mydep,self.xmatch("list-visible",None,mydep=mydep,mykey=mykey)) - #get all visible packages, then get the matching ones - elif level=="match-all": - #match *all* visible *and* masked packages - myval=match_from_list(mydep,self.cp_list(mykey)) - else: - print "ERROR: xmatch doesn't handle",level,"query!" - raise KeyError - myslot = dep_getslot(mydep) - if myslot is not None: - myval = [cpv for cpv in myval \ - if self.aux_get(cpv, ["SLOT"])[0] == myslot] - if self.frozen and (level not in ["match-list","bestmatch-list"]): - self.xcache[level][mydep]=myval - return myval - - def match(self,mydep,use_cache=1): - return self.xmatch("match-visible",mydep) - - def visible(self,mylist): - """two functions in one. Accepts a list of cpv values and uses the package.mask *and* - packages file to remove invisible entries, returning remaining items. This function assumes - that all entries in mylist have the same category and package name.""" - if (mylist is None) or (len(mylist)==0): - return [] - newlist=mylist[:] - #first, we mask out packages in the package.mask file - mykey=newlist[0] - cpv=catpkgsplit(mykey) - if not cpv: - #invalid cat/pkg-v - print "visible(): invalid cat/pkg-v:",mykey - return [] - mycp=cpv[0]+"/"+cpv[1] - maskdict=self.mysettings.pmaskdict - unmaskdict=self.mysettings.punmaskdict - if maskdict.has_key(mycp): - for x in maskdict[mycp]: - mymatches=self.xmatch("match-all",x) - if mymatches is None: - #error in package.mask file; print warning and continue: - print "visible(): package.mask entry \""+x+"\" is invalid, ignoring..." - continue - for y in mymatches: - unmask=0 - if unmaskdict.has_key(mycp): - for z in unmaskdict[mycp]: - mymatches_unmask=self.xmatch("match-all",z) - if y in mymatches_unmask: - unmask=1 - break - if unmask==0: - try: - newlist.remove(y) - except ValueError: - pass - - revmaskdict=self.mysettings.prevmaskdict - if revmaskdict.has_key(mycp): - for x in revmaskdict[mycp]: - #important: only match against the still-unmasked entries... - #notice how we pass "newlist" to the xmatch() call below.... - #Without this, ~ deps in the packages files are broken. - mymatches=self.xmatch("match-list",x,mylist=newlist) - if mymatches is None: - #error in packages file; print warning and continue: - print "emerge: visible(): profile packages entry \""+x+"\" is invalid, ignoring..." - continue - pos=0 - while pos<len(newlist): - if newlist[pos] not in mymatches: - del newlist[pos] - else: - pos += 1 - return newlist - - def gvisible(self,mylist): - "strip out group-masked (not in current group) entries" - - if mylist is None: - return [] - newlist=[] - - accept_keywords = self.mysettings["ACCEPT_KEYWORDS"].split() - pkgdict = self.mysettings.pkeywordsdict - for mycpv in mylist: - #we need to update this next line when we have fully integrated the new db api - auxerr=0 - keys = None - eapi = None - aux_cache = self._gvisible_aux_cache.get(mycpv) - if aux_cache is not None: - keys, eapi = aux_cache - else: - try: - keys, eapi = self.aux_get(mycpv, ["KEYWORDS", "EAPI"]) - except KeyError: - pass - except portage_exception.PortageException, e: - writemsg("!!! Error: aux_get('%s', ['KEYWORDS', 'EAPI'])\n" % mycpv, - noiselevel=-1) - writemsg("!!! %s\n" % str(e), - noiselevel=-1) - self._gvisible_aux_cache[mycpv] = (keys, eapi) - if not keys: - # KEYWORDS="" - #print "!!! No KEYWORDS for "+str(mycpv)+" -- Untested Status" - continue - mygroups=keys.split() - # Repoman may modify this attribute as necessary. - pgroups = accept_keywords[:] - match=0 - cp = dep_getkey(mycpv) - if pkgdict.has_key(cp): - matches = match_to_list(mycpv, pkgdict[cp].keys()) - for atom in matches: - pgroups.extend(pkgdict[cp][atom]) - if matches: - inc_pgroups = [] - for x in pgroups: - if x != "-*" and x.startswith("-"): - try: - inc_pgroups.remove(x[1:]) - except ValueError: - pass - if x not in inc_pgroups: - inc_pgroups.append(x) - pgroups = inc_pgroups - del inc_pgroups - hasstable = False - hastesting = False - for gp in mygroups: - if gp=="*": - writemsg("--- WARNING: Package '%s' uses '*' keyword.\n" % mycpv, - noiselevel=-1) - match=1 - break - elif gp in pgroups: - match=1 - break - elif gp[0] == "~": - hastesting = True - elif gp[0] != "-": - hasstable = True - if not match and ((hastesting and "~*" in pgroups) or (hasstable and "*" in pgroups)): - match=1 - if match and eapi_is_supported(eapi): - newlist.append(mycpv) - return newlist diff --git a/pym/dbapi/fake.py b/pym/dbapi/fake.py deleted file mode 100644 index aceb2052e..000000000 --- a/pym/dbapi/fake.py +++ /dev/null @@ -1,99 +0,0 @@ -from portage import settings, cpv_getkey -from dbapi import dbapi - -class fakedbapi(dbapi): - "This is a dbapi to use for the emptytree function. It's empty, but things can be added to it." - def __init__(self, settings=None): - self.cpvdict={} - self.cpdict={} - if settings is None: - settings = globals()["settings"] - self.settings = settings - self._match_cache = {} - - def _clear_cache(self): - if self._match_cache: - self._match_cache = {} - - def match(self, origdep, use_cache=1): - result = self._match_cache.get(origdep, None) - if result is not None: - return result[:] - result = dbapi.match(self, origdep, use_cache=use_cache) - self._match_cache[origdep] = result - return result[:] - - def cpv_exists(self,mycpv): - return self.cpvdict.has_key(mycpv) - - def cp_list(self,mycp,use_cache=1): - if not self.cpdict.has_key(mycp): - return [] - else: - return self.cpdict[mycp] - - def cp_all(self): - returnme=[] - for x in self.cpdict.keys(): - returnme.extend(self.cpdict[x]) - return returnme - - def cpv_all(self): - return self.cpvdict.keys() - - def cpv_inject(self, mycpv, metadata=None): - """Adds a cpv from the list of available packages.""" - self._clear_cache() - mycp=cpv_getkey(mycpv) - self.cpvdict[mycpv] = metadata - myslot = None - if metadata: - myslot = metadata.get("SLOT", None) - if myslot and mycp in self.cpdict: - # If necessary, remove another package in the same SLOT. - for cpv in self.cpdict[mycp]: - if mycpv != cpv: - other_metadata = self.cpvdict[cpv] - if other_metadata: - if myslot == other_metadata.get("SLOT", None): - self.cpv_remove(cpv) - break - if mycp not in self.cpdict: - self.cpdict[mycp] = [] - if not mycpv in self.cpdict[mycp]: - self.cpdict[mycp].append(mycpv) - - #def cpv_virtual(self,oldcpv,newcpv): - # """Maps a cpv to the list of available packages.""" - # mycp=cpv_getkey(newcpv) - # self.cpvdict[newcpv]=1 - # if not self.virtdict.has_key(mycp): - # self.virtdict[mycp]=[] - # if not mycpv in self.virtdict[mycp]: - # self.virtdict[mycp].append(oldcpv) - # cpv_remove(oldcpv) - - def cpv_remove(self,mycpv): - """Removes a cpv from the list of available packages.""" - self._clear_cache() - mycp=cpv_getkey(mycpv) - if self.cpvdict.has_key(mycpv): - del self.cpvdict[mycpv] - if not self.cpdict.has_key(mycp): - return - while mycpv in self.cpdict[mycp]: - del self.cpdict[mycp][self.cpdict[mycp].index(mycpv)] - if not len(self.cpdict[mycp]): - del self.cpdict[mycp] - - def aux_get(self, mycpv, wants): - if not self.cpv_exists(mycpv): - raise KeyError(mycpv) - metadata = self.cpvdict[mycpv] - if not metadata: - return ["" for x in wants] - return [metadata.get(x, "") for x in wants] - - def aux_update(self, cpv, values): - self._clear_cache() - self.cpvdict[cpv].update(values) diff --git a/pym/dbapi/vardb.py b/pym/dbapi/vardb.py deleted file mode 100644 index 352f78077..000000000 --- a/pym/dbapi/vardb.py +++ /dev/null @@ -1,394 +0,0 @@ -from dbapi import dbapi -from portage import settings, db, listdir, dblink -from portage_const import VDB_PATH -from portage_versions import pkgsplit, catpkgsplit -from portage_util import write_atomic, writemsg, writems_stdout, grabfile -from portage_dep import isjustname, isvalidatom, dep_getkey, dep_getslot, \ - match_from_list, dep_expand -from portage_update import fixdbentries - -import portage_exception -import os, sys - -cptot=0 -class vardbapi(dbapi): - def __init__(self, root, categories=None, settings=None, vartree=None): - self.root = root[:] - #cache for category directory mtimes - self.mtdircache = {} - #cache for dependency checks - self.matchcache = {} - #cache for cp_list results - self.cpcache = {} - self.blockers = None - if settings is None: - settings = globals()["settings"] - self.settings = settings - if categories is None: - categories = settings.categories - self.categories = categories[:] - if vartree is None: - vartree = globals()["db"][root]["vartree"] - self.vartree = vartree - - def cpv_exists(self,mykey): - "Tells us whether an actual ebuild exists on disk (no masking)" - return os.path.exists(self.root+VDB_PATH+"/"+mykey) - - def cpv_counter(self,mycpv): - "This method will grab the COUNTER. Returns a counter value." - cdir=self.root+VDB_PATH+"/"+mycpv - cpath=self.root+VDB_PATH+"/"+mycpv+"/COUNTER" - - # We write our new counter value to a new file that gets moved into - # place to avoid filesystem corruption on XFS (unexpected reboot.) - corrupted=0 - if os.path.exists(cpath): - cfile=open(cpath, "r") - try: - counter=long(cfile.readline()) - except ValueError: - print "portage: COUNTER for",mycpv,"was corrupted; resetting to value of 0" - counter=long(0) - corrupted=1 - cfile.close() - elif os.path.exists(cdir): - mys = pkgsplit(mycpv) - myl = self.match(mys[0],use_cache=0) - print mys,myl - if len(myl) == 1: - try: - # Only one package... Counter doesn't matter. - write_atomic(cpath, "1") - counter = 1 - except SystemExit, e: - raise - except Exception, e: - writemsg("!!! COUNTER file is missing for "+str(mycpv)+" in /var/db.\n", - noiselevel=-1) - writemsg("!!! Please run /usr/lib/portage/bin/fix-db.py or\n", - noiselevel=-1) - writemsg("!!! unmerge this exact version.\n", noiselevel=-1) - writemsg("!!! %s\n" % e, noiselevel=-1) - sys.exit(1) - else: - writemsg("!!! COUNTER file is missing for "+str(mycpv)+" in /var/db.\n", - noiselevel=-1) - writemsg("!!! Please run /usr/lib/portage/bin/fix-db.py or\n", - noiselevel=-1) - writemsg("!!! remerge the package.\n", noiselevel=-1) - sys.exit(1) - else: - counter=long(0) - if corrupted: - # update new global counter file - write_atomic(cpath, str(counter)) - return counter - - def cpv_inject(self,mycpv): - "injects a real package into our on-disk database; assumes mycpv is valid and doesn't already exist" - os.makedirs(self.root+VDB_PATH+"/"+mycpv) - counter = self.counter_tick(self.root, mycpv=mycpv) - # write local package counter so that emerge clean does the right thing - write_atomic(os.path.join(self.root, VDB_PATH, mycpv, "COUNTER"), str(counter)) - - def isInjected(self,mycpv): - if self.cpv_exists(mycpv): - if os.path.exists(self.root+VDB_PATH+"/"+mycpv+"/INJECTED"): - return True - if not os.path.exists(self.root+VDB_PATH+"/"+mycpv+"/CONTENTS"): - return True - return False - - def move_ent(self,mylist): - origcp=mylist[1] - newcp=mylist[2] - - # sanity check - for cp in [origcp,newcp]: - if not (isvalidatom(cp) and isjustname(cp)): - raise portage_exception.InvalidPackageName(cp) - origmatches=self.match(origcp,use_cache=0) - if not origmatches: - return - for mycpv in origmatches: - mycpsplit=catpkgsplit(mycpv) - mynewcpv=newcp+"-"+mycpsplit[2] - mynewcat=newcp.split("/")[0] - if mycpsplit[3]!="r0": - mynewcpv += "-"+mycpsplit[3] - mycpsplit_new = catpkgsplit(mynewcpv) - origpath=self.root+VDB_PATH+"/"+mycpv - if not os.path.exists(origpath): - continue - writemsg_stdout("@") - if not os.path.exists(self.root+VDB_PATH+"/"+mynewcat): - #create the directory - os.makedirs(self.root+VDB_PATH+"/"+mynewcat) - newpath=self.root+VDB_PATH+"/"+mynewcpv - if os.path.exists(newpath): - #dest already exists; keep this puppy where it is. - continue - os.rename(origpath, newpath) - - # We need to rename the ebuild now. - old_eb_path = newpath+"/"+mycpsplit[1] +"-"+mycpsplit[2] - new_eb_path = newpath+"/"+mycpsplit_new[1]+"-"+mycpsplit[2] - if mycpsplit[3] != "r0": - old_eb_path += "-"+mycpsplit[3] - new_eb_path += "-"+mycpsplit[3] - if os.path.exists(old_eb_path+".ebuild"): - os.rename(old_eb_path+".ebuild", new_eb_path+".ebuild") - - write_atomic(os.path.join(newpath, "CATEGORY"), mynewcat+"\n") - fixdbentries([mylist], newpath) - - def update_ents(self, update_iter): - """Run fixdbentries on all installed packages (time consuming). Like - fixpackages, this should be run from a helper script and display - a progress indicator.""" - dbdir = os.path.join(self.root, VDB_PATH) - for catdir in listdir(dbdir): - catdir = dbdir+"/"+catdir - if os.path.isdir(catdir): - for pkgdir in listdir(catdir): - pkgdir = catdir+"/"+pkgdir - if os.path.isdir(pkgdir): - fixdbentries(update_iter, pkgdir) - - def move_slot_ent(self,mylist): - pkg=mylist[1] - origslot=mylist[2] - newslot=mylist[3] - - if not isvalidatom(pkg): - raise portage_exception.InvalidAtom(pkg) - - origmatches=self.match(pkg,use_cache=0) - - if not origmatches: - return - for mycpv in origmatches: - origpath=self.root+VDB_PATH+"/"+mycpv - if not os.path.exists(origpath): - continue - - slot=grabfile(origpath+"/SLOT"); - if (not slot): - continue - - if (slot[0]!=origslot): - continue - - writemsg_stdout("s") - write_atomic(os.path.join(origpath, "SLOT"), newslot+"\n") - - def cp_list(self,mycp,use_cache=1): - mysplit=mycp.split("/") - if mysplit[0] == '*': - mysplit[0] = mysplit[0][1:] - try: - mystat=os.stat(self.root+VDB_PATH+"/"+mysplit[0])[stat.ST_MTIME] - except OSError: - mystat=0 - if use_cache and self.cpcache.has_key(mycp): - cpc=self.cpcache[mycp] - if cpc[0]==mystat: - return cpc[1] - list=listdir(self.root+VDB_PATH+"/"+mysplit[0],EmptyOnError=1) - - if (list is None): - return [] - returnme=[] - for x in list: - if x.startswith("."): - continue - if x[0] == '-': - #writemsg(red("INCOMPLETE MERGE:")+str(x[len("-MERGING-"):])+"\n") - continue - ps=pkgsplit(x) - if not ps: - self.invalidentry(self.root+VDB_PATH+"/"+mysplit[0]+"/"+x) - continue - if len(mysplit) > 1: - if ps[0]==mysplit[1]: - returnme.append(mysplit[0]+"/"+x) - if use_cache: - self.cpcache[mycp]=[mystat,returnme] - elif self.cpcache.has_key(mycp): - del self.cpcache[mycp] - return returnme - - def cpv_all(self,use_cache=1): - returnme=[] - basepath = self.root+VDB_PATH+"/" - - for x in self.categories: - for y in listdir(basepath+x,EmptyOnError=1): - if y.startswith("."): - continue - subpath = x+"/"+y - # -MERGING- should never be a cpv, nor should files. - if os.path.isdir(basepath+subpath) and (pkgsplit(y) is not None): - returnme += [subpath] - return returnme - - def cp_all(self,use_cache=1): - mylist = self.cpv_all(use_cache=use_cache) - d={} - for y in mylist: - if y[0] == '*': - y = y[1:] - mysplit=catpkgsplit(y) - if not mysplit: - self.invalidentry(self.root+VDB_PATH+"/"+y) - continue - d[mysplit[0]+"/"+mysplit[1]] = None - return d.keys() - - def checkblockers(self,origdep): - pass - - def match(self,origdep,use_cache=1): - "caching match function" - mydep = dep_expand( - origdep, mydb=self, use_cache=use_cache, settings=self.settings) - mykey=dep_getkey(mydep) - mycat=mykey.split("/")[0] - if not use_cache: - if self.matchcache.has_key(mycat): - del self.mtdircache[mycat] - del self.matchcache[mycat] - mymatch = match_from_list(mydep, - self.cp_list(mykey, use_cache=use_cache)) - myslot = dep_getslot(mydep) - if myslot is not None: - mymatch = [cpv for cpv in mymatch \ - if self.aux_get(cpv, ["SLOT"])[0] == myslot] - return mymatch - try: - curmtime=os.stat(self.root+VDB_PATH+"/"+mycat)[stat.ST_MTIME] - except SystemExit, e: - raise - except: - curmtime=0 - - if not self.matchcache.has_key(mycat) or not self.mtdircache[mycat]==curmtime: - # clear cache entry - self.mtdircache[mycat]=curmtime - self.matchcache[mycat]={} - if not self.matchcache[mycat].has_key(mydep): - mymatch=match_from_list(mydep,self.cp_list(mykey,use_cache=use_cache)) - myslot = dep_getslot(mydep) - if myslot is not None: - mymatch = [cpv for cpv in mymatch \ - if self.aux_get(cpv, ["SLOT"])[0] == myslot] - self.matchcache[mycat][mydep]=mymatch - return self.matchcache[mycat][mydep][:] - - def findname(self, mycpv): - return self.root+VDB_PATH+"/"+str(mycpv)+"/"+mycpv.split("/")[1]+".ebuild" - - def aux_get(self, mycpv, wants): - mydir = os.path.join(self.root, VDB_PATH, mycpv) - if not os.path.isdir(mydir): - raise KeyError(mycpv) - results = [] - for x in wants: - try: - myf = open(os.path.join(mydir, x), "r") - try: - myd = myf.read() - finally: - myf.close() - myd = " ".join(myd.split()) - except IOError: - myd = "" - if x == "EAPI" and not myd: - results.append("0") - else: - results.append(myd) - return results - - def aux_update(self, cpv, values): - cat, pkg = cpv.split("/") - mylink = dblink(cat, pkg, self.root, self.settings, - treetype="vartree", vartree=self.vartree) - if not mylink.exists(): - raise KeyError(cpv) - for k, v in values.iteritems(): - mylink.setfile(k, v) - - def counter_tick(self,myroot,mycpv=None): - return self.counter_tick_core(myroot,incrementing=1,mycpv=mycpv) - - def get_counter_tick_core(self,myroot,mycpv=None): - return self.counter_tick_core(myroot,incrementing=0,mycpv=mycpv)+1 - - def counter_tick_core(self,myroot,incrementing=1,mycpv=None): - "This method will grab the next COUNTER value and record it back to the global file. Returns new counter value." - cpath=myroot+"var/cache/edb/counter" - changed=0 - min_counter = 0 - if mycpv: - mysplit = pkgsplit(mycpv) - for x in self.match(mysplit[0],use_cache=0): - if x==mycpv: - continue - try: - old_counter = long(self.aux_get(x,["COUNTER"])[0]) - writemsg("COUNTER '%d' '%s'\n" % (old_counter, x),1) - except SystemExit, e: - raise - except: - old_counter = 0 - writemsg("!!! BAD COUNTER in '%s'\n" % (x), noiselevel=-1) - if old_counter > min_counter: - min_counter = old_counter - - # We write our new counter value to a new file that gets moved into - # place to avoid filesystem corruption. - find_counter = ("find '%s' -type f -name COUNTER | " + \ - "while read f; do echo $(<\"${f}\"); done | " + \ - "sort -n | tail -n1") % os.path.join(self.root, VDB_PATH) - if os.path.exists(cpath): - cfile=open(cpath, "r") - try: - counter=long(cfile.readline()) - except (ValueError,OverflowError): - try: - counter = long(commands.getoutput(find_counter).strip()) - writemsg("!!! COUNTER was corrupted; resetting to value of %d\n" % counter, - noiselevel=-1) - changed=1 - except (ValueError,OverflowError): - writemsg("!!! COUNTER data is corrupt in pkg db. The values need to be\n", - noiselevel=-1) - writemsg("!!! corrected/normalized so that portage can operate properly.\n", - noiselevel=-1) - writemsg("!!! A simple solution is not yet available so try #gentoo on IRC.\n") - sys.exit(2) - cfile.close() - else: - try: - counter = long(commands.getoutput(find_counter).strip()) - writemsg("!!! Global counter missing. Regenerated from counter files to: %s\n" % counter, - noiselevel=-1) - except SystemExit, e: - raise - except: - writemsg("!!! Initializing global counter.\n", noiselevel=-1) - counter=long(0) - changed=1 - - if counter < min_counter: - counter = min_counter+1000 - changed = 1 - - if incrementing or changed: - - #increment counter - counter += 1 - # update new global counter file - write_atomic(cpath, str(counter)) - return counter |