Enable PORTAGE_GRPNAME/USERNAME in make.conf.
authorZac Medico <zmedico@gentoo.org>
Fri, 9 Dec 2011 02:54:41 +0000 (18:54 -0800)
committerZac Medico <zmedico@gentoo.org>
Fri, 9 Dec 2011 02:54:41 +0000 (18:54 -0800)
This is handy for prefix installs, since it allows these variables to
be set in make.conf rather than having them hardcoded. Eventually,
the corresponding portage.data constants may be deprecated in favor of
config attributes, since it's conceivable that multiple configurations
with different constants could be used simultaneously.

pym/_emerge/actions.py
pym/portage/_legacy_globals.py
pym/portage/data.py
pym/portage/package/ebuild/config.py

index 87610a693d8147621baf2c258e9058f6d9dad8fb..2849598d3712021db4c9d54786c7478aa8692ce5 100644 (file)
@@ -2997,6 +2997,7 @@ def load_emerge_config(trees=None):
        mtimedbfile = os.path.join(settings['EROOT'], portage.CACHE_PATH, "mtimedb")
        mtimedb = portage.MtimeDB(mtimedbfile)
        portage.output._init(config_root=settings['PORTAGE_CONFIGROOT'])
+       portage.data._init(settings)
        QueryCommand._db = trees
        return settings, trees, mtimedb
 
index f13e95d4b4980250cc40cb9f50ce863967370ae7..e818e7e7a18873a6d457bedbb805f3ac9c0faaf6 100644 (file)
@@ -37,6 +37,7 @@ def _get_legacy_global(name):
 
        settings = portage.db[portage.db._target_eroot]["vartree"].settings
        portage.output._init(config_root=settings['PORTAGE_CONFIGROOT'])
+       portage.data._init(settings)
 
        portage.settings = settings
        constructed.add('settings')
index c496c0b92d49851f9c437c4afa6124e2853e2287..fa6970c42f198b587d796e83e38ff81e980f94f9 100644 (file)
@@ -58,68 +58,125 @@ def portage_group_warning():
 # If the "wheel" group does not exist then wheelgid falls back to 0.
 # If the "portage" group does not exist then portage_uid falls back to wheelgid.
 
-secpass=0
-
 uid=os.getuid()
 wheelgid=0
 
-if uid==0:
-       secpass=2
-elif "__PORTAGE_TEST_EPREFIX" in os.environ:
-       secpass = 2
-
 try:
        wheelgid=grp.getgrnam("wheel")[2]
 except KeyError:
        pass
 
-# Allow the overriding of the user used for 'userpriv' and 'userfetch'
-_portage_uname = os.environ.get('PORTAGE_USERNAME', 'portage')
-_portage_grpname = os.environ.get('PORTAGE_GRPNAME', 'portage')
+# The portage_uid and portage_gid global constants, and others that
+# depend on them are initialized lazily, in order to allow configuration
+# via make.conf. Eventually, these constants may be deprecated in favor
+# of config attributes, since it's conceivable that multiple
+# configurations with different constants could be used simultaneously.
+_initialized_globals = set()
 
-#Discover the uid and gid of the portage user/group
-try:
-       portage_uid = pwd.getpwnam(_portage_uname)[2]
-       portage_gid = grp.getgrnam(_portage_grpname)[2]
-       if secpass < 1 and portage_gid in os.getgroups():
-               secpass=1
-except KeyError:
-       portage_uid=0
-       portage_gid=0
-       userpriv_groups = [portage_gid]
-       writemsg(colorize("BAD",
-               _("portage: 'portage' user or group missing.")) + "\n", noiselevel=-1)
-       writemsg(_(
-               "         For the defaults, line 1 goes into passwd, "
-               "and 2 into group.\n"), noiselevel=-1)
-       writemsg(colorize("GOOD",
-               "         portage:x:250:250:portage:/var/tmp/portage:/bin/false") \
-               + "\n", noiselevel=-1)
-       writemsg(colorize("GOOD", "         portage::250:portage") + "\n",
-               noiselevel=-1)
-       portage_group_warning()
-else:
-       userpriv_groups = [portage_gid]
-       if secpass >= 2:
-               class _LazyUserprivGroups(portage.proxy.objectproxy.ObjectProxy):
-                       def _get_target(self):
-                               global userpriv_groups
-                               if userpriv_groups is not self:
-                                       return userpriv_groups
-                               userpriv_groups = _userpriv_groups
-                               # Get a list of group IDs for the portage user. Do not use
-                               # grp.getgrall() since it is known to trigger spurious
-                               # SIGPIPE problems with nss_ldap.
-                               mystatus, myoutput = \
-                                       portage.subprocess_getstatusoutput("id -G %s" % _portage_uname)
-                               if mystatus == os.EX_OK:
-                                       for x in myoutput.split():
-                                               try:
-                                                       userpriv_groups.append(int(x))
-                                               except ValueError:
-                                                       pass
-                                       userpriv_groups[:] = sorted(set(userpriv_groups))
-                               return userpriv_groups
-
-               _userpriv_groups = userpriv_groups
-               userpriv_groups = _LazyUserprivGroups()
+def _get_global(k):
+       if k in _initialized_globals:
+               return globals()[k]
+
+       if k in ('portage_gid', 'portage_uid', 'secpass'):
+               global portage_gid, portage_uid, secpass
+               secpass = 0
+               if uid == 0:
+                       secpass = 2
+               elif "__PORTAGE_TEST_EPREFIX" in os.environ:
+                       secpass = 2
+               #Discover the uid and gid of the portage user/group
+               try:
+                       portage_uid = pwd.getpwnam(_get_global('_portage_uname'))[2]
+                       portage_gid = grp.getgrnam(_get_global('_portage_grpname'))[2]
+                       if secpass < 1 and portage_gid in os.getgroups():
+                               secpass = 1
+               except KeyError:
+                       portage_uid = 0
+                       portage_gid = 0
+                       writemsg(colorize("BAD",
+                               _("portage: 'portage' user or group missing.")) + "\n", noiselevel=-1)
+                       writemsg(_(
+                               "         For the defaults, line 1 goes into passwd, "
+                               "and 2 into group.\n"), noiselevel=-1)
+                       writemsg(colorize("GOOD",
+                               "         portage:x:250:250:portage:/var/tmp/portage:/bin/false") \
+                               + "\n", noiselevel=-1)
+                       writemsg(colorize("GOOD", "         portage::250:portage") + "\n",
+                               noiselevel=-1)
+                       portage_group_warning()
+
+               _initialized_globals.add('portage_gid')
+               _initialized_globals.add('portage_uid')
+               _initialized_globals.add('secpass')
+
+               if k == 'portage_gid':
+                       return portage_gid
+               elif k == 'portage_uid':
+                       return portage_uid
+               elif k == 'secpass':
+                       return secpass
+               else:
+                       raise AssertionError('unknown name: %s' % k)
+
+       elif k == 'userpriv_groups':
+               v = [portage_gid]
+               if secpass >= 2:
+                       # Get a list of group IDs for the portage user. Do not use
+                       # grp.getgrall() since it is known to trigger spurious
+                       # SIGPIPE problems with nss_ldap.
+                       mystatus, myoutput = \
+                               portage.subprocess_getstatusoutput("id -G %s" % _portage_uname)
+                       if mystatus == os.EX_OK:
+                               for x in myoutput.split():
+                                       try:
+                                               v.append(int(x))
+                                       except ValueError:
+                                               pass
+                               v = sorted(set(v))
+
+       elif k == '_portage_grpname':
+               env = getattr(portage, 'settings', os.environ)
+               v = env.get('PORTAGE_GRPNAME', 'portage')
+       elif k == '_portage_uname':
+               env = getattr(portage, 'settings', os.environ)
+               v = env.get('PORTAGE_USERNAME', 'portage')
+       else:
+               raise AssertionError('unknown name: %s' % k)
+
+       globals()[k] = v
+       _initialized_globals.add(k)
+       return v
+
+class _GlobalProxy(portage.proxy.objectproxy.ObjectProxy):
+
+       __slots__ = ('_name',)
+
+       def __init__(self, name):
+               portage.proxy.objectproxy.ObjectProxy.__init__(self)
+               object.__setattr__(self, '_name', name)
+
+       def _get_target(self):
+               return _get_global(object.__getattribute__(self, '_name'))
+
+for k in ('portage_gid', 'portage_uid', 'secpass', 'userpriv_groups',
+       '_portage_grpname', '_portage_uname'):
+       globals()[k] = _GlobalProxy(k)
+del k
+
+def _init(settings):
+       """
+       Use config variables like PORTAGE_GRPNAME and PORTAGE_USERNAME to
+       initialize global variables. This allows settings to come from make.conf
+       instead of requiring them to be set in the calling environment.
+       """
+       if '_portage_grpname' not in _initialized_globals:
+               v = settings.get('PORTAGE_GRPNAME')
+               if v is not None:
+                       globals()['_portage_grpname'] = v
+                       _initialized_globals.add('_portage_grpname')
+
+       if '_portage_uname' not in _initialized_globals:
+               v = settings.get('PORTAGE_USERNAME')
+               if v is not None:
+                       globals()['_portage_uname'] = v
+                       _initialized_globals.add('_portage_uname')
index 959ecbedb085cbeaf91edf2a25541dca55aebe7e..53a625bc39e00032ce1146b41715d1992fb8247a 100644 (file)
@@ -685,9 +685,6 @@ class config(object):
                        if "USE_ORDER" not in self:
                                self.backupenv["USE_ORDER"] = "env:pkg:conf:defaults:pkginternal:repo:env.d"
 
-                       self["PORTAGE_GID"] = str(portage_gid)
-                       self.backup_changes("PORTAGE_GID")
-
                        self.depcachedir = DEPCACHE_PATH
                        if eprefix:
                                # See comments about make.globals and EPREFIX
@@ -2096,6 +2093,8 @@ class config(object):
                        return portage._bin_path
                elif mykey == "PORTAGE_PYM_PATH":
                        return portage._pym_path
+               elif mykey == "PORTAGE_GID":
+                       return _unicode_decode(str(portage_gid))
 
                for d in self.lookuplist:
                        try:
@@ -2150,6 +2149,7 @@ class config(object):
                keys = set()
                keys.add("PORTAGE_BIN_PATH")
                keys.add("PORTAGE_PYM_PATH")
+               keys.add("PORTAGE_GID")
                for d in self.lookuplist:
                        keys.update(d)
                return iter(keys)