public inbox for gentoo-commits@lists.gentoo.org
 help / color / mirror / Atom feed
* [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