diff options
-rw-r--r-- | pym/_emerge/actions.py | 1 | ||||
-rw-r--r-- | pym/portage/_legacy_globals.py | 1 | ||||
-rw-r--r-- | pym/portage/data.py | 169 | ||||
-rw-r--r-- | 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) |