Portage's env-update currently transforms the environment information
from /etc/env.d into /etc/profile.env, which is typically sourced by
every user session, setting up its environment.
However, /etc/profile.env is not sourced by systemd user
services. Instead, for the definition of a systemd user session
environment, the 'environment.d' machinery exists. Unfortunately, up
to now, env-update does not produce a profile.env equivalent for this
machinery, causing issues for systemd user services. For example, an
emacs daemon run as user systemd service does not have a complete
PATH (bug #704412 [1]), because some PATH components are injected by
packages via /etc/env.d. For example, an LLVM ebuild may set
PATH="/usr/lib/llvm/9/bin".
This commit changes env-update so that a systemd user session
environment configuration file named
/etc/environment.d/10-gentoo-env.conf
is created.
Thanks to Michael 'veremitz' Everitt, Arfrever Frehtes Taifersar
Arahesis, Ulrich Müller, Joakim Tjernlund, and Zac Medico for the
useful feedback.
1: https://bugs.gentoo.org/704412
Closes: https://bugs.gentoo.org/704416
Signed-off-by: Florian Schmaus
---
Notes:
- Shorten created filename to 10-gentoo-env.conf
- Minor fixes in the commit message
- Use atomic_ofstream()
- Use os.makedirs() (Thanks Zac)
lib/portage/util/env_update.py | 42 +++---
1 file changed, 39 insertions(+), 3 deletions(-)
diff --git a/lib/portage/util/env_update.py b/lib/portage/util/env_update.py
index f130b6f6b..ab3caee47 100644
--- a/lib/portage/util/env_update.py
+++ b/lib/portage/util/env_update.py
@@ -333,14 +333,16 @@ def _env_update(makelinks, target_root, prev_mtimes,
contents, env,
del specials["LDPATH"]
- penvnotice = "# THIS FILE IS AUTOMATICALLY GENERATED BY env-update.\n"
- penvnotice += "# DO NOT EDIT THIS FILE. CHANGES TO STARTUP PROFILES\n"
+ notice = "# THIS FILE IS AUTOMATICALLY GENERATED BY env-update.\n"
+ notice += "# DO NOT EDIT THIS FILE."
+ penvnotice = notice + " CHANGES TO STARTUP PROFILES\n"
cenvnotice = penvnotice[:]
penvnotice += "# GO INTO /etc/profile NOT /etc/profile.env\n\n"
cenvnotice += "# GO INTO /etc/csh.cshrc NOT /etc/csh.env\n\n"
#create /etc/profile.env for bash support
- outfile = atomic_ofstream(os.path.join(eroot, "etc", "profile.env"))
+ profile_env_path = os.path.join(eroot, "etc", "profile.env")
+ outfile = atomic_ofstream(profile_env_path)
outfile.write(penvnotice)
env_keys = [x for x in env if x != "LDPATH"]
@@ -353,6 +355,40 @@ def _env_update(makelinks, target_root, prev_mtimes,
contents, env,
outfile.write("export %s='%s'\n" % (k, v))
outfile.close()
+ # Create the systemd user environment configuration file
+ # /etc/environment.d/10-gentoo-env.conf with the
+ # environment configuration from /etc/env.d.
+ systemd_environment_dir = os.path.join(eroot, "etc", "environment.d")
+ os.makedirs(systemd_environment_dir, exist_ok=True)
+
+ systemd_gentoo_env_path = os.path.join(systemd_environment_dir,
+"10-gentoo-env.conf")
+ systemd_gentoo_env = atomic_ofstream(systemd_gentoo_env_path)
+ try:
+ senvnotice = notice + "\n\n"
+ systemd_gentoo_env.write(senvnotice)
+
+ for env_key in env_keys:
+ env_key_value = env[env_key]
+
+ # Skip variables with the empty string
+ # as value. Those sometimes appear in
+ # profile.env (e.g. "export GCC_SPECS=''"),
+ # but are invalid in systemd's syntax.
+ if not env_key_value:
+ continue
+
+ # Transform into systemd environment.d
+ # conf syntax, basically shell variable
+ # assignment (without "export ").
+ line = f"{env_key}={env_key_value}\n"
+
+ systemd_gentoo_env.write(line)
+ except:
+ systemd_gentoo_env.abort()
+ raise
+ systemd_gentoo_env.close()
+
#create /etc/csh.env for (t)csh support
outfile = atomic_ofstream(os.path.join(eroot, "etc", "csh.env"))
outfile.write(cenvnotice)
--
2.26.2