* [gentoo-commits] proj/portage:master commit in: pym/portage/, pym/portage/util/, pym/portage/package/ebuild/
@ 2014-11-17 15:03 Zac Medico
0 siblings, 0 replies; only message in thread
From: Zac Medico @ 2014-11-17 15:03 UTC (permalink / raw
To: gentoo-commits
commit: acf5d6bee0c99dd50d13a963243933fca1d8120c
Author: Zac Medico <zmedico <AT> gentoo <DOT> org>
AuthorDate: Sat Nov 15 06:22:15 2014 +0000
Commit: Zac Medico <zmedico <AT> gentoo <DOT> org>
CommitDate: Mon Nov 17 14:56:24 2014 +0000
URL: http://sources.gentoo.org/gitweb/?p=proj/portage.git;a=commit;h=acf5d6be
unprivileged mode: use first_existing helper func
Split out a first_existing function, in order to improve logic related
to the _unprivileged_mode function so that it checks whether it's
possible to create the specified target root (instead of requiring that
the target root already exists).
Acked-by: Alexander Berntsen <bernalex <AT> gentoo.org>
---
pym/portage/data.py | 20 +++++++++------
pym/portage/package/ebuild/config.py | 23 ++++++-----------
pym/portage/util/path.py | 48 ++++++++++++++++++++++++++++++++++++
3 files changed, 67 insertions(+), 24 deletions(-)
diff --git a/pym/portage/data.py b/pym/portage/data.py
index 3e03eef..d9b36ee 100644
--- a/pym/portage/data.py
+++ b/pym/portage/data.py
@@ -8,6 +8,7 @@ import portage
portage.proxy.lazyimport.lazyimport(globals(),
'portage.output:colorize',
'portage.util:writemsg',
+ 'portage.util.path:first_existing',
'subprocess'
)
from portage.localization import _
@@ -94,14 +95,16 @@ def _get_global(k):
else:
# The config class has equivalent code, but we also need to
# do it here if _disable_legacy_globals() has been called.
- eroot = os.path.join(os.environ.get('ROOT', os.sep),
- portage.const.EPREFIX.lstrip(os.sep))
+ eroot_or_parent = first_existing(os.path.join(
+ os.environ.get('ROOT', os.sep),
+ portage.const.EPREFIX.lstrip(os.sep)))
try:
- eroot_st = os.stat(eroot)
+ eroot_st = os.stat(eroot_or_parent)
except OSError:
pass
else:
- unprivileged = _unprivileged_mode(eroot, eroot_st)
+ unprivileged = _unprivileged_mode(
+ eroot_or_parent, eroot_st)
v = 0
if uid == 0:
@@ -206,14 +209,15 @@ def _get_global(k):
else:
# The config class has equivalent code, but we also need to
# do it here if _disable_legacy_globals() has been called.
- eroot = os.path.join(os.environ.get('ROOT', os.sep),
- portage.const.EPREFIX.lstrip(os.sep))
+ eroot_or_parent = first_existing(os.path.join(
+ os.environ.get('ROOT', os.sep),
+ portage.const.EPREFIX.lstrip(os.sep)))
try:
- eroot_st = os.stat(eroot)
+ eroot_st = os.stat(eroot_or_parent)
except OSError:
pass
else:
- if _unprivileged_mode(eroot, eroot_st):
+ if _unprivileged_mode(eroot_or_parent, eroot_st):
if k == '_portage_grpname':
try:
grp_struct = grp.getgrgid(eroot_st.st_gid)
diff --git a/pym/portage/package/ebuild/config.py b/pym/portage/package/ebuild/config.py
index c7308a4..bf39487 100644
--- a/pym/portage/package/ebuild/config.py
+++ b/pym/portage/package/ebuild/config.py
@@ -48,6 +48,7 @@ from portage.util import ensure_dirs, getconfig, grabdict, \
grabdict_package, grabfile, grabfile_package, LazyItemsDict, \
normalize_path, shlex_split, stack_dictlist, stack_dicts, stack_lists, \
writemsg, writemsg_level, _eapi_cache
+from portage.util.path import first_existing
from portage.util._path import exists_raise_eaccess, isdir_raise_eaccess
from portage.versions import catpkgsplit, catsplit, cpv_getkey, _pkg_str
@@ -848,14 +849,16 @@ class config(object):
"PORTAGE_INST_UID": "0",
}
+ eroot_or_parent = first_existing(eroot)
unprivileged = False
try:
- eroot_st = os.stat(eroot)
+ eroot_st = os.stat(eroot_or_parent)
except OSError:
pass
else:
- if portage.data._unprivileged_mode(eroot, eroot_st):
+ if portage.data._unprivileged_mode(
+ eroot_or_parent, eroot_st):
unprivileged = True
default_inst_ids["PORTAGE_INST_GID"] = str(eroot_st.st_gid)
@@ -897,20 +900,8 @@ class config(object):
# In unprivileged mode, automatically make
# depcachedir relative to target_root if the
# default depcachedir is not writable.
- current_dir = self.depcachedir
- found_dir = False
- while current_dir != os.sep and not found_dir:
- try:
- os.stat(current_dir)
- found_dir = True
- except OSError as e:
- if e.errno == errno.ENOENT:
- current_dir = os.path.dirname(
- current_dir)
- else:
- found_dir = True
-
- if not os.access(current_dir, os.W_OK):
+ if not os.access(first_existing(self.depcachedir),
+ os.W_OK):
self.depcachedir = os.path.join(eroot,
DEPCACHE_PATH.lstrip(os.sep))
diff --git a/pym/portage/util/path.py b/pym/portage/util/path.py
new file mode 100644
index 0000000..a0b96c7
--- /dev/null
+++ b/pym/portage/util/path.py
@@ -0,0 +1,48 @@
+# Copyright 2014 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+import errno
+
+from portage import os
+
+def first_existing(path):
+ """
+ Returns the first existing path element, traversing from the given
+ path to the root directory. A path is considered to exist if lstat
+ either succeeds or raises an error other than ENOENT or ESTALE.
+
+ This can be particularly useful to check if there is permission to
+ create a particular file or directory, without actually creating
+ anything.
+
+ @param path: a filesystem path
+ @type path: str
+ @rtype: str
+ @return: the element that exists
+ """
+ existing = False
+ for path in iter_parents(path):
+ try:
+ os.lstat(path)
+ existing = True
+ except OSError as e:
+ if e.errno not in (errno.ENOENT, errno.ESTALE):
+ existing = True
+
+ if existing:
+ return path
+
+ return os.sep
+
+def iter_parents(path):
+ """
+ @param path: a filesystem path
+ @type path: str
+ @rtype: iterator
+ @return: an iterator which yields path and all parents of path,
+ ending with the root directory
+ """
+ yield path
+ while path != os.sep:
+ path = os.path.dirname(path)
+ yield path
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2014-11-17 15:03 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-11-17 15:03 [gentoo-commits] proj/portage:master commit in: pym/portage/, pym/portage/util/, pym/portage/package/ebuild/ Zac Medico
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox