From c5f74e995a71c15defc2ff3d402f6dcbea2c747d Mon Sep 17 00:00:00 2001 From: Fabian Groffen Date: Wed, 25 Jul 2007 20:19:58 +0000 Subject: [PATCH] Merged from trunk 7372:7396 +------------------------------------------------------------------------+ | 7373 | Drop privileges in the "depend" phase regardless of | | zmedico | FEATURES and RESTRICT since that phase should never need | | | special privileges. Thanks to swegener for the initial | | | patch. | |-----------+------------------------------------------------------------| | 7375 | Enable FEATURES=userfetch by default. | | zmedico | | |-----------+------------------------------------------------------------| | 7377 | Add sfperms and strict to the default FEATURES since | | zmedico | they're already in the base profile's make.defaults. | |-----------+------------------------------------------------------------| | 7379 | Add FEATURES=fakeroot support which causes install and | | zmedico | package phases to run inside fakeroot when a non-root user | | | runs the ebuild command. Thanks to swegener for the | | | initial patch. | |-----------+------------------------------------------------------------| | 7381 | For bug #186337, show an ewarn message if | | zmedico | FEATURES=installsources is enabled but debugedit is not | | | installed. Also document installsources and splitdebug in | | | make.conf.example. | |-----------+------------------------------------------------------------| | 7383 | Fix make.conf.example rejects. | | zmedico | | |-----------+------------------------------------------------------------| | 7385 | Add droppriv keyword for the depend phase. | | zmedico | | |-----------+------------------------------------------------------------| | 7387 | Add droppriv keyword for the depend phase (last one). | | zmedico | | |-----------+------------------------------------------------------------| | 7389 | Use a select loop for moving input and ouput when logging | | zmedico | is enabled in portage.spawn(). | |-----------+------------------------------------------------------------| | 7390 | Use the hardcoded variables from portage.const rather than | | WarnerBro | strings that are apt to change, fix spacing. | |-----------+------------------------------------------------------------| | 7391 | Use blocking mode for writes since we'd rather block than | | zmedico | trigger a EWOULDBLOCK error. | |-----------+------------------------------------------------------------| | 7392 | CACHE_PATH starts with / and therefore isn't compatible | | zmedico | with os.path.join(). | |-----------+------------------------------------------------------------| | 7393 | Set O_NONBLOCK just for read calls (uses fewer fcntl | | zmedico | calls). | |-----------+------------------------------------------------------------| | 7394 | For bug #186386, pass stdin directly to spawned processes | | zmedico | (even when their output goes through a pty) so that Ctrl+Z | | | works as on would expect.) | |-----------+------------------------------------------------------------| | 7396 | use ${MAKE:-make} rather than make in einstall() | | SpankMan | | +------------------------------------------------------------------------+ svn path=/main/branches/prefix/; revision=7398 --- bin/ebuild.sh | 8 +- bin/prepstrip | 5 + cnf/make.conf | 9 ++ cnf/make.conf.sparc-fbsd.diff | 8 +- cnf/make.conf.x86-fbsd.diff | 17 ++-- cnf/make.globals | 2 +- man/make.conf.5 | 4 + pym/portage/__init__.py | 175 ++++++++++++++++------------------ pym/portage/dbapi/porttree.py | 13 +-- pym/portage/process.py | 31 +++--- 10 files changed, 142 insertions(+), 130 deletions(-) diff --git a/bin/ebuild.sh b/bin/ebuild.sh index 483755aa1..6db4410ca 100755 --- a/bin/ebuild.sh +++ b/bin/ebuild.sh @@ -547,7 +547,7 @@ einstall() { if [ -f ./[mM]akefile -o -f ./GNUmakefile ] ; then if [ "${PORTAGE_DEBUG}" == "1" ]; then - make -n prefix="${ED}/usr" \ + ${MAKE:-make} -n prefix="${ED}/usr" \ datadir="${ED}/usr/share" \ infodir="${ED}/usr/share/info" \ localstatedir="${ED}/var/lib" \ @@ -556,7 +556,7 @@ einstall() { ${LOCAL_EXTRA_EINSTALL} \ "$@" install fi - make prefix="${ED}/usr" \ + ${MAKE:-make} prefix="${ED}/usr" \ datadir="${ED}/usr/share" \ infodir="${ED}/usr/share/info" \ localstatedir="${ED}/var/lib" \ @@ -1664,8 +1664,8 @@ if [ -n "${myarg}" ] && \ unset myarg # Save current environment and touch a success file. (echo for success) umask 002 - set | egrep -v "^SANDBOX_" > "${T}/environment" 2>/dev/null - export | egrep -v "^declare -x SANDBOX_" | \ + set | egrep -v -e "^SANDBOX_" -e "^LD_PRELOAD=" -e "^FAKEROOTKEY=" > "${T}/environment" 2>/dev/null + export | egrep -v -e "^declare -x SANDBOX_" -e "^declare -x LD_PRELOAD=" -e "^declare -x FAKEROOTKEY=" | \ sed 's:^declare -rx:declare -x:' >> "${T}/environment" 2>/dev/null chown ${PORTAGE_USER:-portage}:${PORTAGE_GROUP:-portage} "${T}/environment" &>/dev/null chmod g+w "${T}/environment" &>/dev/null diff --git a/bin/prepstrip b/bin/prepstrip index 8fce32b1c..86850cc87 100755 --- a/bin/prepstrip +++ b/bin/prepstrip @@ -25,6 +25,11 @@ type -P -- ${OBJCOPY} > /dev/null || OBJCOPY=objcopy export SAFE_STRIP_FLAGS="--strip-unneeded" export PORTAGE_STRIP_FLAGS=${PORTAGE_STRIP_FLAGS-${SAFE_STRIP_FLAGS} -R .comment} +if hasq installsources ${FEATURES} && ! type -P debugedit >/dev/null ; then + ewarn "FEATURES=installsources is enabled but the debugedit binary could not" + ewarn "be found. This feature will not work unless debugedit is installed!" +fi + save_elf_sources() { hasq installsources ${FEATURES} || return 0 type -P debugedit >/dev/null || return 0 diff --git a/cnf/make.conf b/cnf/make.conf index 73a441928..abe42f587 100644 --- a/cnf/make.conf +++ b/cnf/make.conf @@ -271,6 +271,11 @@ # 'distlocks' enables distfiles locking using fcntl or hardlinks. This # is enabled by default. Tools exist to help clean the locks # after crashes: /usr/lib/portage/bin/clean_locks. +# 'installsources' +# Install source code into /usr/src/debug/${CATEGORY}/${PF} +# (also see 'splitdebug'). This feature works only if debugedit +# is installed and CFLAGS is set to include debug information +# (such as with the -ggdb flag). # 'test' causes ebuilds to perform testing phases if they are capable # of it. Some packages support this automatically via makefiles. # 'metadata-transfer' @@ -284,6 +289,10 @@ # 'parallel-fetch' # do fetching in parallel to compilation # 'sandbox' enables sandboxing when running emerge and ebuild. +# 'splitdebug' Prior to stripping ELF etdyn and etexec files, the debugging +# info is stored for later use by various debuggers. This +# feature is disabled by 'nostrip'. For installation of source +# code, see 'installsources'. # 'strict' causes portage to react strongly to conditions that are # potentially dangerous, like missing/incorrect Manifest files. # 'stricter' causes portage to react strongly to conditions that may diff --git a/cnf/make.conf.sparc-fbsd.diff b/cnf/make.conf.sparc-fbsd.diff index b3413da9e..d71178abb 100644 --- a/cnf/make.conf.sparc-fbsd.diff +++ b/cnf/make.conf.sparc-fbsd.diff @@ -23,13 +23,13 @@ # Portage Directories # =================== -@@ -287,7 +294,8 @@ +@@ -279,7 +286,8 @@ # 'notitles' disables xterm titlebar updates (which contain status info). # 'parallel-fetch' # do fetching in parallel to compilation -# 'sandbox' enables sandboxing when running emerge and ebuild. +# 'sandbox' enables sandboxing when running emerge and ebuild. Doesn't +# work on *BSD-based systems. - # 'strict' causes portage to react strongly to conditions that are - # potentially dangerous, like missing/incorrect Manifest files. - # 'userfetch' when portage is run as root, drop privileges to + # 'splitdebug' Prior to stripping ELF etdyn and etexec files, the debugging + # info is stored for later use by various debuggers. This + # feature is disabled by 'nostrip'. For installation of source diff --git a/cnf/make.conf.x86-fbsd.diff b/cnf/make.conf.x86-fbsd.diff index 6ce2c8090..787bc3526 100644 --- a/cnf/make.conf.x86-fbsd.diff +++ b/cnf/make.conf.x86-fbsd.diff @@ -17,14 +17,15 @@ # Host and optimization settings # ============================== # -@@ -33,10 +42,34 @@ +@@ -33,10 +43,34 @@ # package (and in some cases the libraries it uses) at default optimizations # before reporting errors to developers. # -# Please refer to the GCC manual for a list of possible values. +# -mtune= means optimize code for the particular type of CPU without +# breaking compatibility with other CPUs. -+# + # +-#CFLAGS="-O2 -pipe" +# -march= means to take full advantage of the ABI and instructions +# for the particular CPU; this will break compatibility with older CPUs (for +# example, -march=athlon-xp code will not run on a regular Athlon, and @@ -45,16 +46,15 @@ +# Pentium-M CPU's should not enable sse2 until at least gcc-3.4. Bug 50616. # +# ************************************************************************* # # --#CFLAGS="-O2 -pipe" +# Decent examples: - # ++# +#CFLAGS="-mtune=athlon-xp -O3 -pipe" +#CFLAGS="-march=pentium3 -O3 -pipe" + # If you set a CFLAGS above, then this line will set your default C++ flags to # the same settings. #CXXFLAGS="${CFLAGS}" -@@ -61,7 +80,7 @@ +@@ -61,7 +95,7 @@ # DO NOT PUT ANYTHING BUT YOUR SPECIFIC ~ARCHITECTURE IN THE LIST. # IF YOU ARE UNSURE OF YOUR ARCH, OR THE IMPLICATIONS, DO NOT MODIFY THIS. # @@ -63,12 +63,13 @@ # Portage Directories # =================== -@@ -268,7 +289,8 @@ +@@ -279,7 +313,8 @@ # 'notitles' disables xterm titlebar updates (which contain status info). # 'parallel-fetch' # do fetching in parallel to compilation -# 'sandbox' enables sandboxing when running emerge and ebuild. +# 'sandbox' enables sandboxing when running emerge and ebuild. Doesn't +# work on *BSD-based systems. - # 'strict' causes portage to react strongly to conditions that are - # potentially dangerous, like missing/incorrect Manifest files. + # 'splitdebug' Prior to stripping ELF etdyn and etexec files, the debugging + # info is stored for later use by various debuggers. This + # feature is disabled by 'nostrip'. For installation of source diff --git a/cnf/make.globals b/cnf/make.globals index f3336c8fe..3997599bb 100644 --- a/cnf/make.globals +++ b/cnf/make.globals @@ -33,7 +33,7 @@ FETCHCOMMAND="wget -t 5 -T 60 --passive-ftp -O \${DISTDIR}/\${FILE} \${URI}" RESUMECOMMAND="wget -c -t 5 -T 60 --passive-ftp -O \${DISTDIR}/\${FILE} \${URI}" # Default user options -FEATURES="sandbox distlocks metadata-transfer unmerge-orphans" +FEATURES="distlocks metadata-transfer sandbox sfperms strict unmerge-orphans userfetch" # Default chunksize for binhost comms PORTAGE_BINHOST_CHUNKSIZE="3000" diff --git a/man/make.conf.5 b/man/make.conf.5 index 4cb5b8bad..e1e11dafb 100644 --- a/man/make.conf.5 +++ b/man/make.conf.5 @@ -169,6 +169,10 @@ strangely configured Samba server (oplocks off, NFS re\-export). A tool @PORTAGE_BASE@bin/clean_locks exists to help handle lock issues when a problem arises (normally due to a crash or disconnect). .TP +.B fakeroot +Enable fakeroot for the install and package phases when a non-root user runs +the \fBebuild\fR(1) command. +.TP .B fixpackages Runs the script that will fix the dependencies in all binary packages. This is run whenever packages are moved around in the portage tree. Please note that this diff --git a/pym/portage/__init__.py b/pym/portage/__init__.py index 6f1df54ee..4a3c66100 100644 --- a/pym/portage/__init__.py +++ b/pym/portage/__init__.py @@ -63,14 +63,14 @@ try: import portage.const from portage.const import VDB_PATH, PRIVATE_PATH, CACHE_PATH, DEPCACHE_PATH, \ - USER_CONFIG_PATH, MODULES_FILE_PATH, CUSTOM_PROFILE_PATH, PORTAGE_BASE_PATH, \ - PORTAGE_BIN_PATH, PORTAGE_PYM_PATH, PROFILE_PATH, LOCALE_DATA_PATH, \ - EBUILD_SH_BINARY, SANDBOX_BINARY, BASH_BINARY, \ - MOVE_BINARY, PRELINK_BINARY, WORLD_FILE, MAKE_CONF_FILE, MAKE_DEFAULTS_FILE, \ - DEPRECATED_PROFILE_FILE, USER_VIRTUALS_FILE, EBUILD_SH_ENV_FILE, \ - INVALID_ENV_FILE, CUSTOM_MIRRORS_FILE, CONFIG_MEMORY_FILE,\ - INCREMENTALS, EAPI, MISC_SH_BINARY, REPO_NAME_LOC, REPO_NAME_FILE, \ - EPREFIX + USER_CONFIG_PATH, MODULES_FILE_PATH, CUSTOM_PROFILE_PATH, PORTAGE_BASE_PATH, \ + PORTAGE_BIN_PATH, PORTAGE_PYM_PATH, PROFILE_PATH, LOCALE_DATA_PATH, \ + EBUILD_SH_BINARY, SANDBOX_BINARY, BASH_BINARY, \ + MOVE_BINARY, PRELINK_BINARY, WORLD_FILE, MAKE_CONF_FILE, MAKE_DEFAULTS_FILE, \ + DEPRECATED_PROFILE_FILE, USER_VIRTUALS_FILE, EBUILD_SH_ENV_FILE, \ + INVALID_ENV_FILE, CUSTOM_MIRRORS_FILE, CONFIG_MEMORY_FILE,\ + INCREMENTALS, EAPI, MISC_SH_BINARY, REPO_NAME_LOC, REPO_NAME_FILE, \ + EPREFIX from portage.data import ostype, lchown, userland, secpass, uid, wheelgid, \ portage_uid, portage_gid, userpriv_groups @@ -1506,10 +1506,10 @@ class config(object): return dir_mode_map = { - "tmp" :(-1, 01777, 0), - "var/tmp" :(-1, 01777, 0), - "var/lib/portage" :(portage_gid, 02750, 02), - "var/cache/edb" :(portage_gid, 0755, 02) + "tmp" : (-1, 01777, 0), + "var/tmp" : (-1, 01777, 0), + PRIVATE_PATH : (portage_gid, 02750, 02), + CACHE_PATH.lstrip(os.path.sep) : (portage_gid, 0755, 02) } for mypath, (gid, mode, modemask) in dir_mode_map.iteritems(): @@ -2335,7 +2335,7 @@ class config(object): # XXX This would be to replace getstatusoutput completely. # XXX Issue: cannot block execution. Deadlock condition. -def spawn(mystring, mysettings, debug=0, free=0, droppriv=0, sesandbox=0, **keywords): +def spawn(mystring, mysettings, debug=0, free=0, droppriv=0, sesandbox=0, fakeroot=0, **keywords): """ Spawn a subprocess with extra portage-specific options. Optiosn include: @@ -2363,6 +2363,8 @@ def spawn(mystring, mysettings, debug=0, free=0, droppriv=0, sesandbox=0, **keyw @type droppriv: Boolean @param sesandbox: Enable SELinux Sandboxing (toggles a context switch) @type sesandbox: Boolean + @param fakeroot: Run this command with faked root privileges + @type fakeroot: Boolean @param keywords: Extra options encoded as a dict, to be passed to spawn @type keywords: Dictionary @rtype: Integer @@ -2385,11 +2387,9 @@ def spawn(mystring, mysettings, debug=0, free=0, droppriv=0, sesandbox=0, **keyw # pseudo-terminal that connects two domains. logfile = keywords.get("logfile") mypids = [] + master_fd = None slave_fd = None - output_pid = None - input_pid = None - stdin_termios = None - stdin_fd = None + fd_pipes_orig = None if logfile: del keywords["logfile"] fd_pipes = keywords.get("fd_pipes") @@ -2400,61 +2400,22 @@ def spawn(mystring, mysettings, debug=0, free=0, droppriv=0, sesandbox=0, **keyw from pty import openpty master_fd, slave_fd = openpty() fd_pipes.setdefault(0, sys.stdin.fileno()) + fd_pipes_orig = fd_pipes.copy() stdin_fd = fd_pipes[0] if os.isatty(stdin_fd): - # Copy the termios attributes from stdin_fd to the slave_fd and put - # the stdin_fd into raw mode with ECHO disabled. The stdin - # termios attributes are reverted before returning, or via the - # atexit hook in portage.process when killed by a signal. - import termios, tty - stdin_termios = termios.tcgetattr(stdin_fd) - tty.setraw(stdin_fd) - term_attr = termios.tcgetattr(stdin_fd) - term_attr[3] &= ~termios.ECHO - termios.tcsetattr(stdin_fd, termios.TCSAFLUSH, term_attr) - termios.tcsetattr(slave_fd, termios.TCSAFLUSH, stdin_termios) from output import get_term_size, set_term_size rows, columns = get_term_size() set_term_size(rows, columns, slave_fd) - pre_exec = keywords.get("pre_exec") - def setup_ctty(): - os.setsid() - # Make it into the "controlling terminal". - import termios - if hasattr(termios, "TIOCSCTTY"): - # BSD 4.3 approach - import fcntl - fcntl.ioctl(0, termios.TIOCSCTTY) - else: - # SVR4 approach - fd = os.open(os.ttyname(0), os.O_RDWR) - for x in 0, 1, 2: - os.dup2(fd, x) - os.close(fd) - if pre_exec: - pre_exec() - keywords["pre_exec"] = setup_ctty - # tee will always exit with an IO error, so ignore it's stderr. - null_file = open('/dev/null', 'w') - mypids.extend(portage.process.spawn(['tee', '-i', '-a', logfile], - returnpid=True, fd_pipes={0:master_fd, 1:fd_pipes[1], - 2:null_file.fileno()})) - output_pid = mypids[-1] - mypids.extend(portage.process.spawn(['cat'], - returnpid=True, fd_pipes={0:fd_pipes[0], 1:master_fd, - 2:null_file.fileno()})) - input_pid = mypids[-1] - os.close(master_fd) - null_file.close() - fd_pipes[0] = slave_fd + fd_pipes[0] = fd_pipes_orig[0] fd_pipes[1] = slave_fd fd_pipes[2] = slave_fd keywords["fd_pipes"] = fd_pipes features = mysettings.features - restrict = mysettings.get("PORTAGE_RESTRICT","").split() - droppriv=(droppriv and "userpriv" in features and not \ - ("nouserpriv" in restrict or "userpriv" in restrict)) + # TODO: Enable fakeroot to be used together with droppriv. The + # fake ownership/permissions will have to be converted to real + # permissions in the merge phase. + fakeroot = fakeroot and uid != 0 and portage.process.fakeroot_capable if droppriv and not uid and portage_gid and portage_uid: keywords.update({"uid":portage_uid,"gid":portage_gid, "groups":userpriv_groups,"umask":002}) @@ -2466,6 +2427,10 @@ def spawn(mystring, mysettings, debug=0, free=0, droppriv=0, sesandbox=0, **keyw if free or "SANDBOX_ACTIVE" in os.environ: keywords["opt_name"] += " bash" spawn_func = portage.process.spawn_bash + elif fakeroot: + keywords["opt_name"] += " fakeroot" + keywords["fakeroot_state"] = os.path.join(mysettings["T"], "fakeroot.state") + spawn_func = portage.process.spawn_fakeroot else: keywords["opt_name"] += " sandbox" spawn_func = portage.process.spawn_sandbox @@ -2489,26 +2454,48 @@ def spawn(mystring, mysettings, debug=0, free=0, droppriv=0, sesandbox=0, **keyw if returnpid: return mypids - if output_pid: - # tee will exit when the other end of the pseudo-terminal is closed. - os.waitpid(output_pid, 0) - portage.process.spawned_pids.remove(output_pid) - if input_pid: - # cat is blocking on stdin, so it must be killed. - import signal - try: - os.kill(input_pid, signal.SIGTERM) - except OSError: - pass # it died by itself - os.waitpid(input_pid, 0) - portage.process.spawned_pids.remove(input_pid) + if logfile: + log_file = open(logfile, 'a') + stdout_file = os.fdopen(os.dup(fd_pipes_orig[1]), 'w') + master_file = os.fdopen(master_fd, 'w+') + iwtd = [master_file] + owtd = [] + ewtd = [] + import array, fcntl, select + fd_flags = {} + for f in iwtd: + fd_flags[f] = fcntl.fcntl(f.fileno(), fcntl.F_GETFL) + buffsize = 65536 + eof = False + while not eof: + events = select.select(iwtd, owtd, ewtd) + for f in events[0]: + # Use non-blocking mode to prevent read + # calls from blocking indefinitely. + fcntl.fcntl(f.fileno(), fcntl.F_SETFL, + fd_flags[f] | os.O_NONBLOCK) + buf = array.array('B') + try: + buf.fromfile(f, buffsize) + except EOFError: + pass + fcntl.fcntl(f.fileno(), fcntl.F_SETFL, fd_flags[f]) + if not buf: + eof = True + break + # Use blocking mode for writes since we'd rather block than + # trigger a EWOULDBLOCK error. + if f is master_file: + buf.tofile(stdout_file) + stdout_file.flush() + buf.tofile(log_file) + log_file.flush() + log_file.close() + stdout_file.close() + master_file.close() pid = mypids[-1] - try: - retval = os.waitpid(pid, 0)[1] - portage.process.spawned_pids.remove(pid) - finally: - if stdin_termios: - termios.tcsetattr(stdin_fd, termios.TCSAFLUSH, stdin_termios) + retval = os.waitpid(pid, 0)[1] + portage.process.spawned_pids.remove(pid) if retval != os.EX_OK: if retval & 0xff: return (retval & 0xff) << 8 @@ -3768,7 +3755,7 @@ def doebuild(myebuild, mydo, myroot, mysettings, debug=0, listonly=0, pr, pw = os.pipe() fd_pipes = {0:0, 1:1, 2:2, 9:pw} mypids = spawn(EBUILD_SH_BINARY + " depend", mysettings, - fd_pipes=fd_pipes, returnpid=True) + fd_pipes=fd_pipes, returnpid=True, droppriv=1) os.close(pw) # belongs exclusively to the child process now maxbytes = 1024 mybytes = [] @@ -3796,7 +3783,7 @@ def doebuild(myebuild, mydo, myroot, mysettings, debug=0, listonly=0, mysettings["dbkey"] = \ os.path.join(mysettings.depcachedir, "aux_db_key_temp") - return spawn(EBUILD_SH_BINARY + " depend", mysettings) + return spawn(EBUILD_SH_BINARY + " depend", mysettings, droppriv=1) # Validate dependency metadata here to ensure that ebuilds with invalid # data are never installed (even via the ebuild command). @@ -4032,19 +4019,25 @@ def doebuild(myebuild, mydo, myroot, mysettings, debug=0, listonly=0, sesandbox = mysettings.selinux_enabled() and \ "sesandbox" in mysettings.features + + droppriv = "userpriv" in mysettings.features and \ + "userpriv" not in restrict + + fakeroot = "fakeroot" in mysettings.features + ebuild_sh = EBUILD_SH_BINARY + " %s" misc_sh = MISC_SH_BINARY + " dyn_%s" # args are for the to spawn function actionmap = { -"depend": {"cmd":ebuild_sh, "args":{"droppriv":1, "free":0, "sesandbox":0}}, -"setup": {"cmd":ebuild_sh, "args":{"droppriv":0, "free":1, "sesandbox":0}}, -"unpack": {"cmd":ebuild_sh, "args":{"droppriv":1, "free":0, "sesandbox":sesandbox}}, -"compile":{"cmd":ebuild_sh, "args":{"droppriv":1, "free":nosandbox, "sesandbox":sesandbox}}, -"test": {"cmd":ebuild_sh, "args":{"droppriv":1, "free":nosandbox, "sesandbox":sesandbox}}, -"install":{"cmd":ebuild_sh, "args":{"droppriv":0, "free":0, "sesandbox":sesandbox}}, -"rpm": {"cmd":misc_sh, "args":{"droppriv":0, "free":0, "sesandbox":0}}, -"package":{"cmd":misc_sh, "args":{"droppriv":0, "free":0, "sesandbox":0}}, +"depend": {"cmd":ebuild_sh, "args":{"droppriv":1, "free":0, "sesandbox":0, "fakeroot":0}}, +"setup": {"cmd":ebuild_sh, "args":{"droppriv":0, "free":1, "sesandbox":0, "fakeroot":0}}, +"unpack": {"cmd":ebuild_sh, "args":{"droppriv":droppriv, "free":0, "sesandbox":sesandbox, "fakeroot":0}}, +"compile":{"cmd":ebuild_sh, "args":{"droppriv":droppriv, "free":nosandbox, "sesandbox":sesandbox, "fakeroot":0}}, +"test": {"cmd":ebuild_sh, "args":{"droppriv":droppriv, "free":nosandbox, "sesandbox":sesandbox, "fakeroot":0}}, +"install":{"cmd":ebuild_sh, "args":{"droppriv":0, "free":0, "sesandbox":sesandbox, "fakeroot":fakeroot}}, +"rpm": {"cmd":misc_sh, "args":{"droppriv":0, "free":0, "sesandbox":0, "fakeroot":fakeroot}}, +"package":{"cmd":misc_sh, "args":{"droppriv":0, "free":0, "sesandbox":0, "fakeroot":fakeroot}}, } # merge the deps in so we have again a 'full' actionmap diff --git a/pym/portage/dbapi/porttree.py b/pym/portage/dbapi/porttree.py index 34eff92a7..00d5b2112 100644 --- a/pym/portage/dbapi/porttree.py +++ b/pym/portage/dbapi/porttree.py @@ -130,17 +130,8 @@ class portdbapi(dbapi): modemask = 02 try: - for mydir in (self.depcachedir,): - if ensure_dirs(mydir, gid=portage_gid, mode=dirmode, mask=modemask): - writemsg("Adjusting permissions recursively: '%s'\n" % mydir, - noiselevel=-1) - def onerror(e): - raise # bail out on the first error that occurs during recursion - if not apply_recursive_permissions(mydir, - gid=portage_gid, dirmode=dirmode, dirmask=modemask, - filemode=filemode, filemask=modemask, onerror=onerror): - raise OperationNotPermitted( - "Failed to apply recursive permissions for the portage group.") + ensure_dirs(self.depcachedir, gid=portage_gid, + mode=dirmode, mask=modemask) except PortageException, e: pass diff --git a/pym/portage/process.py b/pym/portage/process.py index fad38770e..fcec7588c 100644 --- a/pym/portage/process.py +++ b/pym/portage/process.py @@ -10,7 +10,7 @@ import signal import sys from portage.util import dump_traceback -from portage.const import BASH_BINARY, SANDBOX_BINARY +from portage.const import BASH_BINARY, SANDBOX_BINARY, FAKEROOT_BINARY from portage.exception import CommandNotFound try: @@ -29,6 +29,9 @@ else: sandbox_capable = (os.path.isfile(SANDBOX_BINARY) and os.access(SANDBOX_BINARY, os.X_OK)) +fakeroot_capable = (os.path.isfile(FAKEROOT_BINARY) and + os.access(FAKEROOT_BINARY, os.X_OK)) + def spawn_bash(mycommand, debug=False, opt_name=None, **keywords): """ Spawns a bash shell running a specific commands @@ -62,6 +65,22 @@ def spawn_sandbox(mycommand, opt_name=None, **keywords): args.append(mycommand) return spawn(args, opt_name=opt_name, **keywords) +def spawn_fakeroot(mycommand, fakeroot_state=None, opt_name=None, **keywords): + args=[FAKEROOT_BINARY] + if not opt_name: + opt_name = os.path.basename(mycommand.split()[0]) + if fakeroot_state: + open(fakeroot_state, "a").close() + args.append("-s") + args.append(fakeroot_state) + args.append("-i") + args.append(fakeroot_state) + args.append("--") + args.append(BASH_BINARY) + args.append("-c") + args.append(mycommand) + return spawn(args, opt_name=opt_name, **keywords) + _exithandlers = [] def atexit_register(func, *args, **kargs): """Wrapper around atexit.register that is needed in order to track @@ -113,16 +132,6 @@ def cleanup(): atexit_register(cleanup) -# Make sure the original terminal attributes are reverted at exit. -if hasattr(sys.stdin, "isatty") and sys.stdin.isatty(): - import termios - _stdin_termios = termios.tcgetattr(sys.stdin.fileno()) - def _reset_stdin_termios(stdin_termios): - import termios - termios.tcsetattr(sys.stdin.fileno(), termios.TCSAFLUSH, stdin_termios) - atexit_register(_reset_stdin_termios, _stdin_termios) - del termios, _stdin_termios, _reset_stdin_termios - def spawn(mycommand, env={}, opt_name=None, fd_pipes=None, returnpid=False, uid=None, gid=None, groups=None, umask=None, logfile=None, path_lookup=True, pre_exec=None): -- 2.26.2