Implement GLEP 59 with control via layout.conf.
authorZac Medico <zmedico@gentoo.org>
Mon, 3 Oct 2011 00:05:30 +0000 (17:05 -0700)
committerZac Medico <zmedico@gentoo.org>
Mon, 3 Oct 2011 00:05:30 +0000 (17:05 -0700)
The portage.const changes are derived from an earlier patch that was
submitted by Robin H. Johnson <robbat2@gentoo.org>:

http://archives.gentoo.org/gentoo-portage-dev/msg_911574e7cb615f67e4c21fc75c043f65.xml

This patch has no affect on a repository unless it contains a
metadata/layout.conf file which contains boolean flags that enable or
disable manifest hash types. The plan is to deploy portage with this
patch, and once it has been stabilized, add the following
metadata/layout.conf settings to gentoo-x86:

  manifest-rmd160 = false
  manifest-sha1 = false
  manifest-whirlpool = true

The above settings will become the default settings in a future portage
release, making them redundant and eligible for removal from
layout.conf (in order to avoid cluttering layout.conf with obsolete
information).

Future events:

After WHIRLPOOL is supported in stable portage:
- Add WHIRLPOOL to MANIFEST2_HASH_DEFAULTS.
- Remove SHA1 and RMD160 from MANIFEST2_HASH_*.
- Toggle gentoo-x86/metadata/layout.conf settings to match.

After WHIRLPOOL is supported in stable portage for at least 1 year:
- Change MANIFEST2_REQUIRED_HASH to WHIRLPOOL.
- Remove SHA256 from MANIFEST2_HASH_*.
- Toggle gentoo-x86/metadata/layout.conf settings to match.

After SHA-3 is approved:
- Add new hashes to MANIFEST2_HASH_*.

After SHA-3 is supported in stable portage:
- Toggle gentoo-x86/metadata/layout.conf settings to match.

After layout.conf settings correspond to defaults in stable portage:
- Remove redundant settings from gentoo-x86/metadata/layout.conf.

pym/portage/const.py
pym/portage/manifest.py
pym/portage/repository/config.py

index 8b5f4acabbb79f8fafc390473232ff0e769ae6d3..e7eac62fbd929d0b2435a25941c54f41224d2a77 100644 (file)
@@ -109,10 +109,32 @@ EAPI                     = 4
 
 HASHING_BLOCKSIZE        = 32768
 MANIFEST1_HASH_FUNCTIONS = ("MD5", "SHA256", "RMD160")
-MANIFEST2_HASH_FUNCTIONS = ("SHA1", "SHA256", "RMD160")
-
 MANIFEST1_REQUIRED_HASH  = "MD5"
-MANIFEST2_REQUIRED_HASH  = "SHA1"
+
+# Future events:
+#
+# After WHIRLPOOL is supported in stable portage:
+# - Add WHIRLPOOL to MANIFEST2_HASH_DEFAULTS.
+# - Remove SHA1 and RMD160 from MANIFEST2_HASH_*.
+# - Toggle gentoo-x86/metadata/layout.conf settings to match.
+#
+# After WHIRLPOOL is supported in stable portage for at least 1 year:
+# - Change MANIFEST2_REQUIRED_HASH to WHIRLPOOL.
+# - Remove SHA256 from MANIFEST2_HASH_*.
+# - Toggle gentoo-x86/metadata/layout.conf settings to match.
+#
+# After SHA-3 is approved:
+# - Add new hashes to MANIFEST2_HASH_*.
+#
+# After SHA-3 is supported in stable portage:
+# - Toggle gentoo-x86/metadata/layout.conf settings to match.
+#
+# After layout.conf settings correspond to defaults in stable portage:
+# - Remove redundant settings from gentoo-x86/metadata/layout.conf.
+
+MANIFEST2_HASH_FUNCTIONS = ("RMD160", "SHA1", "SHA256", "SHA512", "WHIRLPOOL")
+MANIFEST2_HASH_DEFAULTS = frozenset(["SHA1", "SHA256", "RMD160"])
+MANIFEST2_REQUIRED_HASH  = "SHA256"
 
 MANIFEST2_IDENTIFIERS    = ("AUX", "MISC", "DIST", "EBUILD")
 # ===========================================================================
index d09de260699ec21379c9efb0f4ddfa4ccb64c057..eaea0bdf6bd30eb3a773362894e857e3b9bae11c 100644 (file)
@@ -18,6 +18,8 @@ from portage import _unicode_encode
 from portage.exception import DigestException, FileNotFound, \
        InvalidDataType, MissingParameter, PermissionDenied, \
        PortageException, PortagePackageException
+from portage.const import (MANIFEST2_HASH_DEFAULTS,
+       MANIFEST2_HASH_FUNCTIONS, MANIFEST2_REQUIRED_HASH)
 from portage.localization import _
 
 class FileNotInManifestException(PortageException):
@@ -101,7 +103,7 @@ class Manifest(object):
        parsers = (parseManifest2,)
        def __init__(self, pkgdir, distdir, fetchlist_dict=None,
                manifest1_compat=DeprecationWarning, from_scratch=False, thin=False,
-                       allow_missing=False, allow_create=True):
+                       allow_missing=False, allow_create=True, hash_flags=None):
                """ Create new Manifest instance for package in pkgdir.
                    Do not parse Manifest file if from_scratch == True (only for internal use)
                        The fetchlist_dict parameter is required only for generation of
@@ -117,7 +119,15 @@ class Manifest(object):
                self.pkgdir = _unicode_decode(pkgdir).rstrip(os.sep) + os.sep
                self.fhashdict = {}
                self.hashes = set()
-               self.hashes.update(portage.const.MANIFEST2_HASH_FUNCTIONS)
+
+               if hash_flags is None:
+                       hash_flags = {}
+               self.hash_flags = hash_flags
+               for hash_type in MANIFEST2_HASH_FUNCTIONS:
+                       default_state = hash_type in MANIFEST2_HASH_DEFAULTS
+                       if hash_flags.get(hash_type, default_state):
+                               self.hashes.add(hash_type)
+
                self.hashes.difference_update(hashname for hashname in \
                        list(self.hashes) if hashname not in hashfunc_map)
                self.hashes.add("size")
@@ -350,7 +360,7 @@ class Manifest(object):
                self.__init__(self.pkgdir, self.distdir,
                        fetchlist_dict=self.fetchlist_dict, from_scratch=True,
                        thin=self.thin, allow_missing=self.allow_missing,
-                       allow_create=self.allow_create)
+                       allow_create=self.allow_create, hash_flags=self.hash_flags)
                pn = os.path.basename(self.pkgdir.rstrip(os.path.sep))
                cat = self._pkgdir_category()
 
index 846de3908b544f2d494c2a5ec86be4f26045af6d..c201fe751490272e7e2ad059ea121fd24885b6f1 100644 (file)
@@ -44,7 +44,7 @@ class RepoConfig(object):
        __slots__ = ['aliases', 'eclass_overrides', 'eclass_locations', 'location', 'user_location', 'masters', 'main_repo',
                'missing_repo_name', 'name', 'priority', 'sync', 'format', 'sign_manifest', 'thin_manifest',
                'allow_missing_manifest', 'create_manifest', 'disable_manifest', 'cache_is_authoritative',
-               'trust_authoritative_cache']
+               'trust_authoritative_cache', 'manifest_hash_flags']
 
        def __init__(self, name, repo_opts):
                """Build a RepoConfig with options in repo_opts
@@ -118,6 +118,8 @@ class RepoConfig(object):
                self.allow_missing_manifest = False
                self.create_manifest = True
                self.disable_manifest = False
+               self.manifest_hash_flags = {}
+
                self.cache_is_authoritative = False
 
                trust_authoritative_cache = repo_opts.get('trust-authoritative-cache')
@@ -129,6 +131,7 @@ class RepoConfig(object):
                kwds['thin'] = self.thin_manifest
                kwds['allow_missing'] = self.allow_missing_manifest
                kwds['allow_create'] = self.create_manifest
+               kwds['hash_flags'] = self.manifest_hash_flags
                if self.disable_manifest:
                        kwds['from_scratch'] = True
                return manifest.Manifest(*args, **kwds)
@@ -378,6 +381,23 @@ class RepoConfigLoader(object):
                        repo.allow_missing_manifest = manifest_policy != 'strict'
                        repo.create_manifest = manifest_policy != 'false'
                        repo.disable_manifest = manifest_policy == 'false'
+
+                       if 'manifest-rmd160' in layout_data:
+                               repo.manifest_hash_flags["RMD160"] = \
+                                       layout_data['manifest-rmd160'].lower() == 'true'
+
+                       if 'manifest-sha1' in layout_data:
+                               repo.manifest_hash_flags["SHA1"] = \
+                                       layout_data['manifest-sha1'].lower() == 'true'
+
+                       if 'manifest-sha256' in layout_data:
+                               repo.manifest_hash_flags["SHA256"] = \
+                                       layout_data['manifest-sha256'].lower() == 'true'
+
+                       if 'manifest-whirlpool' in layout_data:
+                               repo.manifest_hash_flags["WHIRLPOOL"] = \
+                                       layout_data['manifest-whirlpool'].lower() == 'true'
+
                        repo.cache_is_authoritative = layout_data.get('authoritative-cache', 'false').lower() == 'true'
                        if not repo.trust_authoritative_cache:
                                repo.cache_is_authoritative = False