Discuss: A better way to handle environment variables?
markstos opened this issue · 5 comments
This project embeds some environment variables in a shell script. It advises modifying the shell script to update the environment variables, which is not ideal.
Is there a better way?
Is systemd's "environment.d" a possible solution?
https://www.freedesktop.org/software/systemd/man/environment.d.html
As a disclosure, I currently use a shell script to set environment variables when starting sway, which I'll include below.
One thing you'll see in this snippet is that there are a number of other environment variables are useful to get toolkits or apps to prioritize Wayland over X11. These would be common modifications to the script shipped here.
The second thing you'll notice is that I start gnome-keyring here. I tried to run gnome-keyring
as a systemd service but could not get it to work, I think because it needs to export an environment variable in time for other apps that are launched to receive it.
So consider that a challenge to test this project and how it handles environment variables-- can it work with gnome-keyring-daemon
to export SSH_AUTH_SOCK early enough for terminal apps to access it?
#!/usr/bin/env sh
# From here: https://github.com/nullgemm/ly/issues/228
eval $(/usr/bin/gnome-keyring-daemon --start)
export SSH_AUTH_SOCK
export TERMINAL="alacritty"
export _JAVA_AWT_WM_NONREPARENTING=1
export QT_AUTO_SCREEN_SCALE_FACTOR=1
export QT_QPA_PLATFORM=wayland
export QT_WAYLAND_DISABLE_WINDOWDECORATION=1
export MOZ_ENABLE_WAYLAND=1
export MOZ_WEBRENDER=1
export MOZ_ACCELERATED=1
export BEMENU_BACKEND=wayland
export GTK_THEME=Adwaita:dark
/sbin/sway
(If it matters, I'm currently using ly
as my display manager).
Note that the shell script itself does not set any environment variables (except XDG_CURRENT_DESKTOP
, but there's a strong reason for that). The list in the script only controls what's being passed from sway environment to a systemd and dbus activated services.
I imagine that users would still want to extend it for sake of apps launched by systemd-xdg-autostart-generator
, and I plan to eventually add a command-line parameter with extra vars to pass to the services.
Managing sway environment though is hard and highly opinionated. With the amount of ways people launch sway, I don't see a solution that I'm comfortable with imposing on the users as a distribution maintainer, therefore I consider that outside of scope of this project.
For the time being wrapper scripts are still the only working option :'(
environment.d
wouldn't help for those two reasons:
- It only affects systemd user session. Applications launched from sway directly don't get the modified environment.
- There's no way to restrict
environment.d
assignments to a specific DE or WM
Thanks. Let's consider this resolved for now. If someone has a better idea, they can comment to suggest re-opening the conversation.
While working on foot server mode socket activation, I had some thoughts about this subject.
The idea would be, instead of importing variables, use template units to points to a EnvironmentFile, which would be provisioned before starting the target, something like:
session-service@.service
[Service]
EnvironmentFile=%t/env-session/%i
[Install]
WantedBy=sway-session@.target
(Instead of importing session env variables, it creates a kind of "overlay", which would also obviates the need for cleaning up at the end of the session, if I'm correct)
However, that would require going all-in to templated session targets and the like + some amount of machinery (maybe systemd generators or something). Would you be interested in opening another issue to discuss that line of thoughts (given multiples session are an explicit non-goals in the README), since it's a wider scope that just environment variables ?
@VannTen It's an interesting line of thought, but I agree it deserves a new issue. It sounds like it's really about discussing multiple-session support.
@VannTen that is a nice approach, but as with any attempt to trick systemd into supporting multiple graphical sessions, it'll have roughly the same set of issues:
- DBus and socket activation - if any of the activated services interacts with Wayland display or reads the environment, it'll work only in the session that started the service. Notably, this applies to
xdg-desktop-portal
,gpg-agent.socket
, the units generated bysystemd-xdg-autostart-generator
, etc.
And you can't actually activate a template unit from a non-template socket/dbus service without a serious magic. - expanding the idea of the aforementioned: you can only have a single DBus session and a single owner for certain service instances. Void or Artix users may immediately remind me about
dbus-run-session
... well, given that systemd itself listens on the DBus user session bus, creating another one isolated from the first does not reflect well on the user experience (based on the experimental data). - Some things may decide to continue running after the graphical session ends. Imagine
service2@wayland-2
trying to start a dependencyservice1@wayland-2
all whileservice1@wayland-1
is still running and keeping some important resource locked. - Generators run
only onceon each daemon (re)load, which is good as you can addimport-environment; daemon-reload
to the session script, but also bad as the old generated units will be destroyed (unless there are running instances IIRC; the state of a running service without an unit file on disk is interesting). - Imagine the amount of unit files you'd have to fork, convert to templates and maintain... All of it while receiving occasional complaints from upstreams which in their turn get the issues reported by users with a third-party unit file.
Note that theEnvironment
orEnvironmentFile
is not inherited going down the dependency tree.
I thought I had a longer list, but can't recall anything important right now :(
Some of these are not applicable if we explicitly restrict things to a single (templated) session. But then the only benefit we get is to be able to use %i=wayland-n in the units, which doesn't quite need the whole complexity with the environment variables. #15 seems to be almost sufficient for that purpose.