From b9b1c642065220aaf857a6ab221756be60519448 Mon Sep 17 00:00:00 2001 From: Zac Medico Date: Thu, 8 Dec 2011 18:54:41 -0800 Subject: [PATCH] Enable PORTAGE_GRPNAME/USERNAME in make.conf. 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 | 1 + pym/portage/_legacy_globals.py | 1 + pym/portage/data.py | 169 ++++++++++++++++++--------- pym/portage/package/ebuild/config.py | 6 +- 4 files changed, 118 insertions(+), 59 deletions(-) diff --git a/pym/_emerge/actions.py b/pym/_emerge/actions.py index 87610a693..2849598d3 100644 --- a/pym/_emerge/actions.py +++ b/pym/_emerge/actions.py @@ -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 diff --git a/pym/portage/_legacy_globals.py b/pym/portage/_legacy_globals.py index f13e95d4b..e818e7e7a 100644 --- a/pym/portage/_legacy_globals.py +++ b/pym/portage/_legacy_globals.py @@ -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') diff --git a/pym/portage/data.py b/pym/portage/data.py index c496c0b92..fa6970c42 100644 --- a/pym/portage/data.py +++ b/pym/portage/data.py @@ -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') diff --git a/pym/portage/package/ebuild/config.py b/pym/portage/package/ebuild/config.py index 959ecbedb..53a625bc3 100644 --- a/pym/portage/package/ebuild/config.py +++ b/pym/portage/package/ebuild/config.py @@ -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) -- 2.26.2