From 8faa4b5b938a1f630f0aa9481679791ccbb8dd32 Mon Sep 17 00:00:00 2001 From: Fabian Groffen Date: Sun, 19 Apr 2009 07:05:16 +0000 Subject: [PATCH] Merged from trunk -r13346:13350 MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit | 13347 | Bug #266211 - Handle ESTALE like ENOENT in fetch and locking | | zmedico | code. Thanks to Krzysztof Olędzki 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 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 | 1 + man/portage.5 | 13 ++++++++++--- pym/_emerge/__init__.py | 32 +++++++++++++++++++++++++++++++ pym/portage/__init__.py | 32 ++++++++++++++++++++----------- pym/portage/dbapi/porttree.py | 36 +++++++++++++++++++++++++---------- pym/portage/locks.py | 4 ++-- 6 files changed, 92 insertions(+), 26 deletions(-) diff --git a/bin/repoman b/bin/repoman index a0f8c62a0..5fb6182fc 100755 --- a/bin/repoman +++ b/bin/repoman @@ -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.") diff --git a/man/portage.5 b/man/portage.5 index 593410265..35cfdd777 100644 --- a/man/portage.5 +++ b/man/portage.5 @@ -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 diff --git a/pym/_emerge/__init__.py b/pym/_emerge/__init__.py index fe2209064..6ea7897f2 100644 --- a/pym/_emerge/__init__.py +++ b/pym/_emerge/__init__.py @@ -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(): diff --git a/pym/portage/__init__.py b/pym/portage/__init__.py index 2c0c6b55d..1576cefa9 100644 --- a/pym/portage/__init__.py +++ b/pym/portage/__init__.py @@ -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 diff --git a/pym/portage/dbapi/porttree.py b/pym/portage/dbapi/porttree.py index ed9ed99a4..246a0d6f1 100644 --- a/pym/portage/dbapi/porttree.py +++ b/pym/portage/dbapi/porttree.py @@ -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: diff --git a/pym/portage/locks.py b/pym/portage/locks.py index ddd39323f..b3138af46 100644 --- a/pym/portage/locks.py +++ b/pym/portage/locks.py @@ -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 -- 2.26.2