Merged from trunk -r13346:13350
authorFabian Groffen <grobian@gentoo.org>
Sun, 19 Apr 2009 07:05:16 +0000 (07:05 -0000)
committerFabian Groffen <grobian@gentoo.org>
Sun, 19 Apr 2009 07:05:16 +0000 (07:05 -0000)
   | 13347   | Bug #266211 - Handle ESTALE like ENOENT in fetch and locking |
   | zmedico | code. Thanks to Krzysztof Olędzki <ole+gentoo@ans.pl> for   |
   |         | the initial patch.                                           |

   | 13348   | Bug #265909 - Make emerge display a warning message if any   |
   | zmedico | overlays are ignored due to duplicate profiles/repo_name     |
   |         | entries. The warning can be disabled by setting              |
   |         | PORTAGE_REPO_DUPLICATE_WARN=0 in /etc/make.conf.             |

   | 13349   | Call realpath(repodir) so it's conistent with the value that |
   | zmedico | pordbapi uses. Thanks to Fabian Groffen <grobian@g.o> for    |
   |         | reporting.                                                   |

   | 13350   | Add support in repos.conf to override the "masters" setting  |
   | zmedico | from layout.conf.                                            |

svn path=/main/branches/prefix/; revision=13367

bin/repoman
man/portage.5
pym/_emerge/__init__.py
pym/portage/__init__.py
pym/portage/dbapi/porttree.py
pym/portage/locks.py

index a0f8c62a03a0b6a8458b1c65aa254250c8958a88..5fb6182fc418405224efb503d7700d98c020e07f 100755 (executable)
@@ -535,6 +535,7 @@ startdir = normalize_path(mydir)
 repodir = startdir
 for x in range(0, repolevel - 1):
        repodir = os.path.dirname(repodir)
+repodir = os.path.realpath(repodir)
 
 def caterror(mycat):
        err(mycat+" is not an official category.  Skipping QA checks in this directory.\nPlease ensure that you add "+catdir+" to "+repodir+"/profiles/categories\nif it is a new category.")
index 593410265278c9b0f48236a9c4352abe90e42724..35cfdd77776e5ad69553f11130cb19630b25833f 100644 (file)
@@ -552,8 +552,9 @@ x11\-libs/qt \-mysql
 Specifies \fIsite\-specific\fR repository configuration information. Note that
 configuration settings which are specified here do not apply to tools
 such as \fBrepoman\fR(1) and \fBegencache\fR(1) since their operations
-are inherently \fBnot\fR \fIsite\-specific\fR. Beware that use of
-\fBeclass\-overrides\fR is generally not recommended and that it may trigger
+are inherently \fBnot\fR \fIsite\-specific\fR. \fBWARNING:\fR Use of
+\fBrepos.conf\fR is generally not recommended since resulting changes in
+eclass inheritance (especially due ot \fBeclass\-overrides\fR) may trigger
 performance issues under some circumstances (see \fBbug #124041\fR).
 
 .I Example:
@@ -567,6 +568,10 @@ eclass\-overrides = java\-overlay java\-experimental
 # disable all eclass overrides for ebuilds from the gentoo repository
 [gentoo]
 eclass\-overrides =
+
+# override the metadata/layout.conf masters setting from the kde-testing repo
+[kde-testing]
+masters = gentoo kde
 .fi
 .RE
 .TP
@@ -579,7 +584,9 @@ Specifies information about the repository layout. Currently, only a single
 repositories which satisfy dependencies on eclasses and/or ebuilds. Each
 repository name should correspond the value of a \fBrepo_name\fR entry
 from one of the repositories that is configured via the \fBPORTDIR\fR or
-\fBPORTDIR_OVERLAY\fR variables (see \fBmake.conf\fR(5)).
+\fBPORTDIR_OVERLAY\fR variables (see \fBmake.conf\fR(5)). Site-specific
+overrides to \fBlayout.conf\fR settings may be specified in
+\fB/etc/portage/repos.conf\fR.
 
 .I Example:
 .nf
index fe2209064512828e15a89d9c95d54acb59ee9c8e..6ea7897f2e900291644e3825df77007c1090ef70 100644 (file)
@@ -15658,6 +15658,37 @@ def repo_name_check(trees):
 
        return bool(missing_repo_names)
 
+def repo_name_duplicate_check(trees):
+       ignored_repos = {}
+       for root, root_trees in trees.iteritems():
+               if 'porttree' in root_trees:
+                       portdb = root_trees['porttree'].dbapi
+                       if portdb.mysettings.get('PORTAGE_REPO_DUPLICATE_WARN') != '0':
+                               for repo_name, paths in portdb._ignored_repos:
+                                       k = (root, repo_name, portdb.getRepositoryPath(repo_name))
+                                       ignored_repos.setdefault(k, []).extend(paths)
+
+       if ignored_repos:
+               msg = []
+               msg.append('WARNING: One or more repositories ' + \
+                       'have been ignored due to duplicate')
+               msg.append('  profiles/repo_name entries:')
+               msg.append('')
+               for k in sorted(ignored_repos):
+                       msg.append('  %s overrides' % (k,))
+                       for path in ignored_repos[k]:
+                               msg.append('    %s' % (path,))
+                       msg.append('')
+               msg.extend('  ' + x for x in textwrap.wrap(
+                       "All profiles/repo_name entries must be unique in order " + \
+                       "to avoid having duplicates ignored. " + \
+                       "Set PORTAGE_REPO_DUPLICATE_WARN=\"0\" in " + \
+                       "/etc/make.conf if you would like to disable this warning."))
+               writemsg_level(''.join('%s\n' % l for l in msg),
+                       level=logging.WARNING, noiselevel=-1)
+
+       return bool(ignored_repos)
+
 def config_protect_check(trees):
        for root, root_trees in trees.iteritems():
                if not root_trees["root_config"].settings.get("CONFIG_PROTECT"):
@@ -15775,6 +15806,7 @@ def emerge_main():
        if "--quiet" not in myopts:
                portage.deprecated_profile_check(settings=settings)
                repo_name_check(trees)
+               repo_name_duplicate_check(trees)
                config_protect_check(trees)
 
        for mytrees in trees.itervalues():
index 2c0c6b55dbd004a81ec1e33585d9d17ce891024e..1576cefa98f151ae6a025199785393ce28098301 100644 (file)
@@ -1002,11 +1002,19 @@ def _lazy_iuse_regex(iuse_implicit):
        return regex
 
 class _local_repo_config(object):
-       __slots__ = ('eclass_overrides', 'name',)
+       __slots__ = ('eclass_overrides', 'masters', 'name',)
        def __init__(self, name, repo_opts):
                self.name = name
-               self.eclass_overrides = \
-                       tuple(repo_opts.get('eclass-overrides', '').split())
+
+               eclass_overrides = repo_opts.get('eclass-overrides')
+               if eclass_overrides is not None:
+                       eclass_overrides = tuple(eclass_overrides.split())
+               self.eclass_overrides = eclass_overrides
+
+               masters = repo_opts.get('masters')
+               if masters is not None:
+                       masters = tuple(masters.split())
+               self.masters = masters
 
 class config(object):
        """
@@ -1139,6 +1147,7 @@ class config(object):
                "PORTAGE_GPG_DIR",
                "PORTAGE_GPG_KEY", "PORTAGE_IONICE_COMMAND",
                "PORTAGE_PACKAGE_EMPTY_ABORT",
+               "PORTAGE_REPO_DUPLICATE_WARN",
                "PORTAGE_RO_DISTDIRS",
                "PORTAGE_RSYNC_EXTRA_OPTS", "PORTAGE_RSYNC_OPTS",
                "PORTAGE_RSYNC_RETRIES", "PORTAGE_USE", "PORT_LOGDIR",
@@ -3946,7 +3955,7 @@ def fetch(myuris, mysettings, listonly=0, fetchonly=0, locks_in_subdir=".locks",
                                try:
                                        mysize = os.stat(myfile_path).st_size
                                except OSError, e:
-                                       if e.errno != errno.ENOENT:
+                                       if e.errno not in (errno.ENOENT, errno.ESTALE):
                                                raise
                                        del e
                                        mysize = 0
@@ -4058,7 +4067,7 @@ def fetch(myuris, mysettings, listonly=0, fetchonly=0, locks_in_subdir=".locks",
                                                try:
                                                        os.unlink(myfile_path)
                                                except OSError, e:
-                                                       if e.errno != errno.ENOENT:
+                                                       if e.errno not in (errno.ENOENT, errno.ESTALE):
                                                                raise
                                                        del e
                                                os.symlink(readonly_file, myfile_path)
@@ -4073,14 +4082,14 @@ def fetch(myuris, mysettings, listonly=0, fetchonly=0, locks_in_subdir=".locks",
                                                                " %(file)s\n" % {"file":myfile}))
                                                        break
                                                except (IOError, OSError), e:
-                                                       if e.errno != errno.ENOENT:
+                                                       if e.errno not in (errno.ENOENT, errno.ESTALE):
                                                                raise
                                                        del e
 
                                try:
                                        mystat = os.stat(myfile_path)
                                except OSError, e:
-                                       if e.errno != errno.ENOENT:
+                                       if e.errno not in (errno.ENOENT, errno.ESTALE):
                                                raise
                                        del e
                                else:
@@ -4224,7 +4233,7 @@ def fetch(myuris, mysettings, listonly=0, fetchonly=0, locks_in_subdir=".locks",
                                                try:
                                                        mysize = os.stat(myfile_path).st_size
                                                except OSError, e:
-                                                       if e.errno != errno.ENOENT:
+                                                       if e.errno not in (errno.ENOENT, errno.ESTALE):
                                                                raise
                                                        del e
                                                        mysize = 0
@@ -4248,7 +4257,7 @@ def fetch(myuris, mysettings, listonly=0, fetchonly=0, locks_in_subdir=".locks",
                                                try:
                                                        mystat = os.stat(myfile_path)
                                                except OSError, e:
-                                                       if e.errno != errno.ENOENT:
+                                                       if e.errno not in (errno.ENOENT, errno.ESTALE):
                                                                raise
                                                        del e
                                                        fetched = 0
@@ -4260,7 +4269,8 @@ def fetch(myuris, mysettings, listonly=0, fetchonly=0, locks_in_subdir=".locks",
                                                                try:
                                                                        os.unlink(myfile_path)
                                                                except OSError, e:
-                                                                       if e.errno != errno.ENOENT:
+                                                                       if e.errno not in \
+                                                                               (errno.ENOENT, errno.ESTALE):
                                                                                raise
                                                                        del e
                                                                fetched = 0
@@ -4314,7 +4324,7 @@ def fetch(myuris, mysettings, listonly=0, fetchonly=0, locks_in_subdir=".locks",
                                                try:
                                                        mystat = os.stat(myfile_path)
                                                except OSError, e:
-                                                       if e.errno != errno.ENOENT:
+                                                       if e.errno not in (errno.ENOENT, errno.ESTALE):
                                                                raise
                                                        del e
                                                        fetched = 0
index ed9ed99a43db248f0bac5294c1e9590a440b79d5..246a0d6f1ddbfe3654e08b100c73f91446e47b5f 100644 (file)
@@ -143,7 +143,7 @@ class portdbapi(dbapi):
                repository_map = {}
                self.treemap = treemap
                self._repository_map = repository_map
-               identically_named_paths = set()
+               identically_named_paths = {}
                for path in porttrees:
                        if path in repository_map:
                                continue
@@ -160,7 +160,7 @@ class portdbapi(dbapi):
                                if identically_named_path is not None:
                                        # The earlier one is discarded.
                                        del repository_map[identically_named_path]
-                                       identically_named_paths.add(identically_named_path)
+                                       identically_named_paths[identically_named_path] = repo_name
                                        if identically_named_path == porttrees[0]:
                                                # Found another repo with the same name as
                                                # $PORTDIR, so update porttrees[0] to match.
@@ -171,6 +171,11 @@ class portdbapi(dbapi):
                # Ensure that each repo_name is unique. Later paths override
                # earlier ones that correspond to the same name.
                porttrees = [x for x in porttrees if x not in identically_named_paths]
+               ignored_map = {}
+               for path, repo_name in identically_named_paths.iteritems():
+                       ignored_map.setdefault(repo_name, []).append(path)
+               self._ignored_repos = tuple((repo_name, tuple(paths)) \
+                       for repo_name, paths in ignored_map.iteritems())
 
                self.porttrees = porttrees
                porttree_root = porttrees[0]
@@ -202,11 +207,27 @@ class portdbapi(dbapi):
                                continue
 
                        repo_name = self._repository_map.get(path)
+
+                       loc_repo_conf = None
+                       if local_repo_configs is not None:
+                               if repo_name is not None:
+                                       loc_repo_conf = local_repo_configs.get(repo_name)
+                               else:
+                                       loc_repo_conf = default_loc_repo_config
+
                        layout_filename = os.path.join(path, "metadata/layout.conf")
                        layout_file = KeyValuePairFileLoader(layout_filename, None, None)
                        layout_data, layout_errors = layout_file.load()
                        porttrees = []
-                       for master_name in layout_data.get('masters', '').split():
+
+                       masters = None
+                       if loc_repo_conf is not None and \
+                               loc_repo_conf.masters is not None:
+                               masters = loc_repo_conf.masters
+                       else:
+                               masters = layout_data.get('masters', '').split()
+
+                       for master_name in masters:
                                master_path = self.treemap.get(master_name)
                                if master_path is None:
                                        writemsg_level(("Unavailable repository '%s' " + \
@@ -225,13 +246,8 @@ class portdbapi(dbapi):
 
                        porttrees.append(path)
 
-                       if local_repo_configs is not None:
-                               loc_repo_conf = None
-                               if repo_name is not None:
-                                       loc_repo_conf = local_repo_configs.get(repo_name)
-                               if loc_repo_conf is None:
-                                       loc_repo_conf = default_loc_repo_config
-                               if loc_repo_conf is not None:
+                       if loc_repo_conf is not None and \
+                                       loc_repo_conf.eclass_overrides is not None:
                                        for other_name in loc_repo_conf.eclass_overrides:
                                                other_path = self.treemap.get(other_name)
                                                if other_path is None:
index ddd39323fbd110b918321d82700d25affcd1f18c..b3138af4656414e10800fa164a0e9d4e75891c4e 100644 (file)
@@ -75,7 +75,7 @@ def lockfile(mypath, wantnewlockfile=0, unlinkfile=0,
                                        if os.stat(lockfilename).st_gid != portage_gid:
                                                os.chown(lockfilename, -1, portage_gid)
                                except OSError, e:
-                                       if e.errno == errno.ENOENT: # No such file or directory
+                                       if e.errno in (errno.ENOENT, errno.ESTALE):
                                                return lockfile(mypath,
                                                        wantnewlockfile=wantnewlockfile,
                                                        unlinkfile=unlinkfile, waiting_msg=waiting_msg,
@@ -165,7 +165,7 @@ def _fstat_nlink(fd):
        try:
                return os.fstat(fd).st_nlink
        except EnvironmentError, e:
-               if e.errno == errno.ENOENT:
+               if e.errno in (errno.ENOENT, errno.ESTALE):
                        # Some filesystems such as CIFS return
                        # ENOENT which means st_nlink == 0.
                        return 0