Added support for generating CONTENTS files automatically. Patch by Robin Johnson...
authorChris Gianelloni <wolf31o2@gentoo.org>
Fri, 8 Feb 2008 01:56:54 +0000 (01:56 +0000)
committerChris Gianelloni <wolf31o2@gentoo.org>
Fri, 8 Feb 2008 01:56:54 +0000 (01:56 +0000)
git-svn-id: svn+ssh://svn.gentoo.org/var/svnroot/catalyst/trunk@1289 d1e1f19c-881f-0410-ab34-b69fee027534

AUTHORS
ChangeLog
catalyst
files/catalyst.conf
modules/catalyst_support.py
modules/generic_stage_target.py
modules/grp_target.py
modules/snapshot_target.py

diff --git a/AUTHORS b/AUTHORS
index 0679cc4df01a3e6b12ebb90dedd1a6d1613d9847..5199ba78e0a596e7416d0de92daff80b635fa09d 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -19,3 +19,4 @@ Joshua Kinard <kumba@gentoo.org>
 Lars Weiler <pylon@gentoo.org>
 Andrew Gaffney <agaffney@gentoo.org>
 Diego Pettenò <flameeyes@gentoo.org>
+Robin H. Johnson <robbat2@gentoo.org>
index 557c36efcdf8bf1cd0b3ba55e75ddf6ed90d443a..a769daf2eec13c4abf22f2261c3566e4b74a124d 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,13 @@
 # Copyright 2002-2008 Gentoo Foundation; Distributed under the GPL v2
 # $Id: $
 
+  08 Feb 2008; Chris Gianelloni <wolf31o2@gentoo.org> AUTHORS, catalyst,
+  files/catalyst.conf, modules/catalyst_support.py,
+  modules/generic_stage_target.py, modules/grp_target.py,
+  modules/snapshot_target.py:
+  Added support for generating CONTENTS files automatically. Patch by Robin
+  Johnson <robbat2@gentoo.org> for bug #207862.
+
   08 Feb 2008; Chris Gianelloni <wolf31o2@gentoo.org>
   modules/snapshot_target.py:
   Add a patch from Robin Johnson <robbat2@gentoo.org> from bug #207860 to
index 99efdd51c3de1e42044d7693984987a65f3b1b41..522713e073f86cbeaf95bd5887533effd1898535 100755 (executable)
--- a/catalyst
+++ b/catalyst
@@ -147,6 +147,8 @@ def parse_config(myconfig):
 
        if myconf.has_key("digests"):
                conf_values["digests"]=myconf["digests"]
+       if myconf.has_key("contents"):
+               conf_values["contents"]=myconf["contents"]
 
        if myconf.has_key("envscript"):
                print "Envscript support enabled."
index 452ac643fad2b91d6a12569773ee7b58bf5b3dca..b4e2385f401f5e349b3d8e2ed5c4859028360e30 100644 (file)
@@ -9,6 +9,18 @@
 #      ripemd256, sha256, sha512, ripemd160, md5
 digests="md5 sha1"
 
+# Creates a .CONTENTS file listing the contents of the file. Pick from any of
+# the supported options below:
+# auto         - strongly recommended
+# tar-tv       - does 'tar tvf FILE'
+# tar-tvz      - does 'tar tvzf FILE'
+# tar-tvy      - does 'tar tvyf FILE'
+# isoinfo-l    - does 'isoinfo -l -i FILE'
+# isoinfo-f    - does 'isoinfo -f -i FILE'
+# 'isoinfo-f' is the only option not chosen by the automatic algorithm.
+# If this variable is empty, no .CONTENTS will be generated at all.
+contents="auto"
+
 # distdir specifies where your distfiles are located. This setting should
 # work fine for most default installations.
 distdir="/usr/portage/distfiles"
index a676fd19d7bc1cf6423a68ab01e7237a4f44676f..a79e9dfd8f85b832007bc77892af8fa10e65c026 100644 (file)
@@ -62,6 +62,54 @@ def hexify(str):
        return r
 # hexify()
 
+def generate_contents(file,contents_function="auto",verbose=False):
+       try:
+               _ = contents_function
+               if _ is 'auto' and file.endswith('.iso'):
+                       _ = 'isoinfo-l'
+               if (_ in ['tar-tv','auto']):
+                       if file.endswith('.tgz') or file.endswith('.tar.gz'):
+                               _ = 'tar-tvz'
+                       elif file.endswith('.tbz2') or file.endswith('.tar.bz2'):
+                               _ = 'tar-tvj'
+                       elif file.endswith('.tar'):
+                               _ = 'tar-tv'
+               
+               contents_function = _
+               _ = contents_map[contents_function]
+               return _[0](file,_[1],verbose)
+       except:
+               raise CatalystError,\
+                       "Error generating contents, is appropriate utility (%s) installed on your system?" \
+                       % (contents_function, )
+
+def calc_contents(file,cmd,verbose):
+       args={ 'file': file }
+       cmd=cmd % dict(args)
+       a=os.popen(cmd)
+       mylines=a.readlines()
+       a.close()
+       result="".join(mylines)
+       if verbose:
+               print result
+       return result
+
+# This has map must be defined after the function calc_content
+# It is possible to call different functions from this but they must be defined
+# before hash_map
+# Key,function,cmd
+contents_map={
+       # 'find' is disabled because it requires the source path, which is not
+       # always available
+       #"find"         :[calc_content,"find %(path)s"],
+       "tar-tv":[calc_content,"tar tvf %(file)s"],
+       "tar-tvz":[calc_content,"tar tvzf %(file)s"],
+       "tar-tvj":[calc_content,"tar tvjf %(file)s"],
+       "isoinfo-l":[calc_content,"isoinfo -l -i %(file)s"],
+       # isoinfo-f should be a last resort only
+       "isoinfo-f":[calc_content,"isoinfo -f -i %(file)s"],
+}
+
 def generate_hash(file,hash_function="crc32",verbose=False):
        try:
                return hash_map[hash_function][0](file,hash_map[hash_function][1],hash_map[hash_function][2],\
@@ -167,6 +215,7 @@ valid_config_file_values.append("SNAPCACHE")
 valid_config_file_values.append("snapshot_cache")
 valid_config_file_values.append("hash_function")
 valid_config_file_values.append("digests")
+valid_config_file_values.append("contents")
 valid_config_file_values.append("SEEDCACHE")
 
 verbosity=1
index a51abde4ebe4afa7aa308a44aae1f74530da1d32..f34009636f26a1a5028765678bfd3b172b114010 100644 (file)
@@ -25,8 +25,8 @@ class generic_stage_target(generic_target):
 
                # The semantics of subarchmap and machinemap changed a bit in 2.0.3 to
                # work better with vapier's CBUILD stuff. I've removed the "monolithic"
-               # machinemap from this file and split up its contents amongst the various
-               # arch/foo.py files.
+               # machinemap from this file and split up its contents amongst the
+               # various arch/foo.py files.
                #
                # When register() is called on each module in the arch/ dir, it now
                # returns a tuple instead of acting on the subarchmap dict that is
@@ -1051,6 +1051,7 @@ class generic_stage_target(generic_target):
                cmd("tar cjpf "+self.settings["target_path"]+" -C "+self.settings["stage_path"]+\
                        " .","Couldn't create stage tarball",env=self.env)
 
+               self.gen_contents_file(self.settings["target_path"])
                self.gen_digest_file(self.settings["target_path"])
 
                touch(self.settings["autoresume_path"]+"capture")
@@ -1178,6 +1179,7 @@ class generic_stage_target(generic_target):
                if self.settings.has_key("iso"):
                        cmd("/bin/bash "+self.settings["controller_file"]+" iso "+\
                                self.settings["iso"],"ISO creation script failed.",env=self.env)
+                       self.gen_contents_file(self.settings["iso"])
                        self.gen_digest_file(self.settings["iso"])
                        touch(self.settings["autoresume_path"]+"create_iso")
                
@@ -1387,6 +1389,23 @@ class generic_stage_target(generic_target):
                                os.chown(myemp,mystat[ST_UID],mystat[ST_GID])
                                os.chmod(myemp,mystat[ST_MODE])
 
+
+       def gen_contents_file(self,file):
+               if os.path.exists(file+".CONTENTS"):
+                       os.remove(file+".CONTENTS")
+               if self.settings.has_key("contents"):
+                       if os.path.exists(file):
+                               myf=open(file+".CONTENTS","w")
+                               keys={}
+                               for i in self.settings["contents"].split():
+                                       keys[i]=1
+                                       array=keys.keys()
+                                       array.sort()
+                               for j in array:
+                                       contents=generate_contents(file,contents_function=j,verbose=self.settings.has_key("VERBOSE"))
+                                       myf.write(contents)
+                               myf.close()
+
        def gen_digest_file(self,file):
                if os.path.exists(file+".DIGESTS"):
                        os.remove(file+".DIGESTS")
@@ -1398,12 +1417,11 @@ class generic_stage_target(generic_target):
                                        keys[i]=1
                                        array=keys.keys()
                                        array.sort()
-                               for j in array:
-                                       if self.settings.has_key("VERBOSE"):
-                                               hash=generate_hash(file,hash_function=j,verbose=True)
-                                       else:
-                                               hash=generate_hash(file,hash_function=j)
-                                       myf.write(hash)
+                               for f in [file, file+'.CONTENTS']:
+                                       if os.path.exists(f):
+                                               for j in array:
+                                                       hash=generate_hash(f,hash_function=j,verbose=self.settings.has_key("VERBOSE"))
+                                                       myf.write(hash)
                                myf.close()
 
        def purge(self):
index b7a0770b10d052307eaa4346de334cb5a7b7285e..ebaee604148073c1a5148e7684a4dc4283b1bde1 100644 (file)
@@ -84,6 +84,7 @@ class grp_target(generic_stage_target):
                                files=[filename for filename in files if filename[0] != '.']
                                for i in files:
                                        if os.path.isfile(normpath(destdir+"/"+i)):
+                                               self.gen_contents_file(normpath(destdir+"/"+i))
                                                self.gen_digest_file(normpath(destdir+"/"+i))
                        else:
                                destdir=normpath(self.settings["target_path"]+"/"+pkgset)
@@ -99,6 +100,7 @@ class grp_target(generic_stage_target):
                                files=[filename for filename in files if filename[0] != '.']
                                for i in files:
                                        if os.path.isfile(normpath(destdir+"/"+i)):
+                                               self.gen_contents_file(normpath(destdir+"/"+i))
                                                self.gen_digest_file(normpath(destdir+"/"+i))
 
        def set_action_sequence(self):
index a99e9b58a94f08727613c4e4b856364543d646f2..94e402655b63fb73e3153202a809e296e577b19c 100644 (file)
@@ -51,6 +51,7 @@ class snapshot_target(generic_stage_target):
                cmd("tar cjf "+self.settings["snapshot_path"]+" -C "+mytmp+" portage",\
                        "Snapshot creation failure",env=self.env)
                
+               self.gen_contents_file(self.settings["snapshot_path"])
                self.gen_digest_file(self.settings["snapshot_path"])
 
                self.cleanup()