Add FEATURES=fakeroot support which causes install and package phases to run inside...
authorZac Medico <zmedico@gentoo.org>
Tue, 24 Jul 2007 00:52:59 +0000 (00:52 -0000)
committerZac Medico <zmedico@gentoo.org>
Tue, 24 Jul 2007 00:52:59 +0000 (00:52 -0000)
svn path=/main/branches/2.1.2/; revision=7380

bin/ebuild.sh
man/make.conf.5
pym/portage.py
pym/portage_const.py
pym/portage_exec.py

index c9bacd4a53584ae2e025eebe0470602687d8c8a0..0e50cdb63121438b2875d7a950fff3a21924ca86 100755 (executable)
@@ -1726,8 +1726,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:portage "${T}/environment" &>/dev/null
        chmod g+w "${T}/environment" &>/dev/null
index 6228dfdc80d9776c5b7cb798af86356b60cce7bb..db8cad760edf11bdb9bb576aac731ec65fffe64f 100644 (file)
@@ -169,6 +169,10 @@ strangely configured Samba server (oplocks off, NFS re\-export). A tool
 /usr/lib/portage/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 
index a4097f551281bdf5d3f78b6d74dd0e87ea27d455..107d19ff1c96de2f0c3a2d1526deb04363200715 100644 (file)
@@ -2277,7 +2277,7 @@ class config:
 
 # 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:
@@ -2305,6 +2305,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
@@ -2344,7 +2346,10 @@ def spawn(mystring, mysettings, debug=0, free=0, droppriv=0, sesandbox=0, **keyw
                keywords["fd_pipes"] = fd_pipes
 
        features = mysettings.features
-       restrict = mysettings.get("PORTAGE_RESTRICT","").split()
+       # 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_exec.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})
 
@@ -2355,6 +2360,10 @@ def spawn(mystring, mysettings, debug=0, free=0, droppriv=0, sesandbox=0, **keyw
        if free:
                keywords["opt_name"] += " bash"
                spawn_func = portage_exec.spawn_bash
+       elif fakeroot:
+               keywords["opt_name"] += " fakeroot"
+               keywords["fakeroot_state"] = os.path.join(mysettings["T"], "fakeroot.state")
+               spawn_func = portage_exec.spawn_fakeroot
        else:
                keywords["opt_name"] += " sandbox"
                spawn_func = portage_exec.spawn_sandbox
@@ -3911,19 +3920,21 @@ def doebuild(myebuild, mydo, myroot, mysettings, debug=0, listonly=0,
                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":droppriv, "free":0,         "sesandbox":sesandbox}},
-"compile":{"cmd":ebuild_sh, "args":{"droppriv":droppriv, "free":nosandbox, "sesandbox":sesandbox}},
-"test":   {"cmd":ebuild_sh, "args":{"droppriv":droppriv, "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
@@ -5969,17 +5980,8 @@ class portdbapi(dbapi):
                modemask =    02
 
                try:
-                       for mydir in (self.depcachedir,):
-                               if portage_util.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 portage_exception.OperationNotPermitted(
-                                                       "Failed to apply recursive permissions for the portage group.")
+                       portage_util.ensure_dirs(self.depcachedir, gid=portage_gid,
+                               mode=dirmode, mask=modemask)
                except portage_exception.PortageException, e:
                        pass
 
index 2b33f20130474fbb803e3218a25cf819b245dd6c..8eea0faba3a0f816a78140bc7a79926848ff02ab 100644 (file)
@@ -29,6 +29,7 @@ LOCALE_DATA_PATH        = PORTAGE_BASE_PATH+"/locale"
 EBUILD_SH_BINARY        = PORTAGE_BIN_PATH+"/ebuild.sh"
 MISC_SH_BINARY          = PORTAGE_BIN_PATH + "/misc-functions.sh"
 SANDBOX_BINARY          = "/usr/bin/sandbox"
+FAKEROOT_BINARY         = "/usr/bin/fakeroot"
 BASH_BINARY             = "/bin/bash"
 MOVE_BINARY             = "/bin/mv"
 PRELINK_BINARY          = "/usr/sbin/prelink"
index 800535f55fb9a2b365cea4f1117746c381c33db6..3a53661bbfc2826a6ee55f7840db23789fa9652d 100644 (file)
@@ -8,7 +8,7 @@ import os, atexit, signal, sys
 import portage_data
 
 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:
@@ -27,6 +27,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
@@ -60,6 +63,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