[PATCH] env-update: create systemd env configuration if required

Florian Schmaus <[email protected]>
Newsgroups gmane.linux.gentoo.portage.devel
Message-ID <[email protected]>
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 a 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, after profile.env has was
generated, a systemd user session environment configuration file named

/usr/lib/environment.d/gentoo-profile-env.conf

is created, if the directory /usr/lib/environment.d exists.

1: https://bugs.gentoo.org/704412

Closes: https://bugs.gentoo.org/704416
Signed-off-by: Florian Schmaus <[email protected]>
---
 lib/portage/util/env_update.py | 40 +++++++++++++++++++++++++++++++++-
 1 file changed, 39 insertions(+), 1 deletion(-)

diff --git a/lib/portage/util/env_update.py b/lib/portage/util/env_update.py
index f130b6f6b..9bddf281b 100644
--- a/lib/portage/util/env_update.py
+++ b/lib/portage/util/env_update.py
@@ -6,6 +6,7 @@ __all__ = ['env_update']
 import errno
 import glob
 import io
+import re
 import stat
 import time
 
@@ -340,7 +341,8 @@ def _env_update(makelinks, target_root, prev_mtimes, contents, env,
 	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,42 @@ 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
+	# /usr/lib/environment.d/gentoo-profile-env.conf with the
+	# environment variables of /etc/profile.enf if
+	# /usr/lib/environment.d exists.
+	systemd_environment_dir = os.path.join(eroot, "usr", "lib", "environment.d")
+	if os.path.isdir(systemd_environment_dir):
+		with open(profile_env_path, "r") as profile_env:
+			lines = profile_env.readlines()
+
+		systemd_profile_env_path = os.path.join(systemd_environment_dir,
+						     "gentoo-profile-env.conf")
+
+		with open(systemd_profile_env_path, "w") as systemd_profile_env:
+			for line in lines:
+				# Skip comments.
+				if re.match(r"^[ \t]*#", line):
+					continue
+
+				# Skip empty lines.
+				if re.match(r"^[ \t]*$", line):
+					continue
+
+				# 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 line.endswith("=''\n"):
+					continue
+
+				# Transform into systemd environment.d
+				# conf syntax, basically shell variable
+				# assignment (without "export ").
+				line = re.sub(r"^export ", "", line)
+
+				systemd_profile_env.write(line)
+
 	#create /etc/csh.env for (t)csh support
 	outfile = atomic_ofstream(os.path.join(eroot, "etc", "csh.env"))
 	outfile.write(cenvnotice)
-- 
2.26.2
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.