Add FEATURES=fakeroot support which causes install and package phases to run inside...
authorZac Medico <zmedico@gentoo.org>
Mon, 23 Jul 2007 23:33:08 +0000 (23:33 -0000)
committerZac Medico <zmedico@gentoo.org>
Mon, 23 Jul 2007 23:33:08 +0000 (23:33 -0000)
svn path=/main/trunk/; revision=7379

bin/ebuild.sh
man/make.conf.5
pym/portage/__init__.py
pym/portage/const.py
pym/portage/dbapi/porttree.py
pym/portage/process.py

index 5f271524be00c3533655eeef547803ae77cb2fb7..72b449927ff3431274dae953fe0945e708b7d206 100755 (executable)
@@ -1648,8 +1648,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 4ae3a2f94ffdd65298bd571b4a881d17acc99640..da6df14dcc4e2b1d51a01c98ece0e37da7902db9 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 a151ad064e800e82ded4314ead9b1d14b5dae348..3fe82f63e7ec4c4b48693eb6b483e3fbf1d0c06e 100644 (file)
@@ -2326,7 +2326,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:
@@ -2354,6 +2354,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
@@ -2443,7 +2445,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.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})
@@ -2455,6 +2460,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
@@ -4022,19 +4031,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
index 28e6f36ff32685bad90a66d552d68d7c0a53a50e..d8bd604d17c3a2e8c7df944ac8727b9ed255262b 100644 (file)
@@ -30,6 +30,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 34eff92a7e583fc42ff4150426d2d184576403a5..00d5b21121129e63e416b0bb886727840de23901 100644 (file)
@@ -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
 
index fad38770e2fd7f8d57920ca3f854c2da526e81ee..8b9ab30e253904e470493687a557b4deefc1fa8e 100644 (file)
@@ -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