So while on my way to FOSDEM I decided to do something useful with the
time and wrote a new manifest2 implementation. This has nothing to do
with the original prototype I posted a while ago, it's been written
completely from scratch.
Basically all functionality (creation, parsing, validation) is
encapsulated in the new portage_manifest.Manifest class, including
compability code to read/write old style digests.
The changes to portage.py only change the digest*() functions to use
this new class instead of handling the task themselves (exception:
digestCheckFiles() which apparently was only used internally by other
digest* functions), they should more or less behave like with the old
code. Any new code however should use the Manifest() class directly
however.
While this patch implements the basic functionality some extra stuff
that was in the old code isn't included yet:
- gpg verification
- FEATURES=autoaddcvs
- FEATURES=cvs (probably obsolete anyway)
- emerge --digest / FEATURES=digest (may or may not work)
The first should be delayed until there is some consensus how the gpg
stuff should work in the future, the others I don't see the use for.
Also I only checked portage.py for changes, so emerge/repoman/... might
still have to be fixed.
Last but not least: I did some basic testing with this and the
important stuff seems to work, but I'm quite sure the code still has a
lot of bugs/issues, and this being a core functionality it needs a
*lot* of testing, so I'd really appreciate if you could all give it a
spin (but do not commit anything to the tree without manually checking
it first).
Marius
--
Public Key at http://www.genone.de/info/gpg-key.pub
In the beginning, there was nothing. And God said, 'Let there be
Light.' And there was still nothing, but you could see a bit better.
diff -ru --exclude=CVS --exclude=.svn -N pym/portage.py.org pym/portage.py
--- pym/portage.py.org 2006-03-04 02:25:20.957635000 +
+++ pym/portage.py 2006-03-04 03:12:19.545785750 +
@@ -90,6 +90,7 @@
from portage_data import ostype, lchown, userland, secpass, uid, wheelgid, \
portage_uid, portage_gid
+ from portage_manifest import Manifest
import portage_util
from portage_util import atomic_ofstream, dump_traceback, getconfig, grabdict, \
@@ -2049,181 +2050,67 @@
return 0
return 1
-
-def digestCreate(myfiles,basedir,oldDigest={}):
- """Takes a list of files and the directory they are in and returns the
- dict of dict[filename][CHECKSUM_KEY] = hash
- returns None on error."""
- mydigests={}
- for x in myfiles:
- print "<<<",x
- myfile=os.path.normpath(basedir+"///"+x)
- if os.path.exists(myfile):
- if not os.access(myfile, os.R_OK):
-print "!!! Given file does not appear to be readable. Does it exist?"
-print "!!! File:",myfile
-return None
- mydigests[x] = portage_checksum.perform_multiple_checksums(myfile, hashes=portage_const.MANIFEST1_HASH_FUNCTIONS)
- mysize = os.stat(myfile)[stat.ST_SIZE]
- else:
- if x in oldDigest:
-# DeepCopy because we might not have a unique reference.
-mydigests[x] = copy.deepcopy(oldDigest[x])
-mysize = copy.deepcopy(oldDigest[x]["size"])
- else:
-print "!!! We have a source URI, but no file..."
-print "!!! File:",myfile
-return None
-
- if mydigests[x].has_key("size") and (mydigests[x]["size"] != mysize):
- raise portage_exception.DigestException, "Size mismatch during checksums"
- mydigests[x]["size"] = copy.deepcopy(mysize)
- return mydigests
-
-def digestCreateLines(filelist, mydict):
- mylines = []
- mydigests = copy.deepcopy(mydict)
- for myarchive in filelist:
- mysize = mydigests[myarchive]["size"]
- if len(mydigests[myarchive]) == 0:
- raise portage_exception.DigestException, "No generate digest for '%(file)s'" % {"file":myarchive}
- for sumName in mydigests[myarchive].keys():
- if sumName not in portage_checksum.get_valid_checksum_keys():
-continue
- mysum = mydigests[myarchive][sumName]
-
- myline = sumName[:]
- myline += " "+mysum
- myline += " "+myarchive
- myline += " "+str(mysize)
- mylines.append(myline)
- return mylines
-
-def digestgen(myarchives,mysettings,overwrite=1,manifestonly=0):
+def digestgen(myarchives,mysettings,db=None,overwrite=1,manifestonly=0):
"""generates digest file if missing. Assumes all files are available. If
- overwrite=0, the digest will only be created if it doesn't already exist."""
-
- # archive files
- basedir=mysettings["DISTDIR"]+"/"
- digestfn=mysettings["FILESDIR"]+"/digest-"+mysettings["PF"]
-
- # portage files -- p(ortagefiles)basedir
- pbasedir=mysettings["O"]+"/"
- manifestfn=pbasedir+"Manifest"
-
- if not manifestonly:
- if not os.path.isdir(mysettings["FILESDIR"]):
- os.makedirs(mysettings["FILESDIR"])
- mycvstree=cvstree.getentries(pbasedir, recursive=1)
-
- if ("cvs" in features) and os.path.exists(pbasedir+"/CVS"):
- if not cvstree.isadded(mycvstree,"files"):
-if "autoaddcvs" in features:
-