backend/nitro: add#36
Conversation
|
|
||
| . @CONF_PATH@/backend/nitro.conf | ||
| : ${service_env_dir:="${XDG_RUNTIME_DIR}/turnstile.env"} | ||
| envd=${TURNSTILE_ENV_DIR:-${service_env_dir:-${XDG_RUNTIME_DIR:-/run/user/$(id -u)}/turnstile.env}} |
There was a problem hiding this comment.
i don't think it makes sense for the envdir to be in XDG_RUNTIME_DIR. I put it in ~/.config so users could set persistent vars
There was a problem hiding this comment.
I don't really like doing that because you then end up with stale references. Consider for example:
- Service
fooalso updates the activation environment to include its _SOCK variable, but is not launched on session startup (but rather manually by the user). - User imports the activation environment in their rc.
- User starts a session, starts
foo, then reboots. - FOO_SOCK is now in the activation environment, even though it shouldn't be (i.e. it is a stale reference).
There are various ways to update the activation environment that is in control of the user (xdg autostart, profile, window manager config, etc). For persistent vars I would prefer those be used, ensuring that the current activation environment narrowly matches the current session.
There was a problem hiding this comment.
would it make sense for this to be generic across backends that need it?
turnstile-update-envdir <nitro|runit> <var>[=value]
There was a problem hiding this comment.
I think it would, but figured I'd do something closer to what's already in the repo. I had considered a fully-generic envdir + envfile handler, but I can't quite find my draft for that. I have found a turnstile-envdir draft from a bit earlier than that point, see examples for (some of) the motivation. Let me know what you think!
I'm perfectly willing to adapt the PR to also update both envdir-based backends to use this mechanism or something similar if that's what's desirable.
A draft of `turnstile-envdir` I have lying around.
#!/bin/bash
# bash is pulled in for printf %q (which may become POSIX) and namerefs
# clobbers $envdir, $e, $f, $action, $name
# note that printf %q under bash produces $'' strings
# these are POSIX-2024 compliant, but your shell may not be
: ${envdir:=${ENVDIR:-${XDG_RUNTIME_DIR:-/run/user/$(id -u)}/env}}
usage() {
cat <<-EOF
$1 [-LSX] [-d envdir] [VAR...]
Manages a chpst(8)-compatible env dir.
-L: Export environment in a quoted format appropriate for evaluating,
if any VARs are specified, only export those. Default mode.
-S: Update env dir with arguments. If VAR follows the VAR=VAL pattern,
set VAR to VAL, otherwise take the value from the environment.
-X: Take VAR... to be a sublist to execute with the environment.
Exactly equivalent to exec chpst -e "\$envdir".
-d: Set envdir explicitly. The actual envdir is a priority rule:
the OPTARG of -d > \$envdir > \$ENVDIR > /env under \$XDG_RUNTIME_DIR.
With your current invocation, it would be '$envdir'.
Examples:
- eval "\$($1 -L)" # set all variables without exporting them
- set -a; eval "\$($1 -L)"; set +a # ditto, while exporting them
- $1 -S foo bar=baz # set foo to whatever \$foo is right now, and bar to baz
- $1 -X my cmd # run 'my cmd' with the envdir variables set and exported
- $1 -d /some/dir # like '$1 -L' but /some/dir is used as the envdir
EOF
} >&2
action=list
while getopts LSXd: name
do
case $name in
L) action=list ;;
S) action=set ;;
X) action=exec ;;
d) envdir=$OPTARG ;;
?) usage "$(basename "$0")"; exit 2 ;;
esac
done
shift $(( $OPTIND - 1))
case $action in
list)
[ -d "$envdir" ] || break
for f in "$envdir"/*; do
# WARN: printf %q is not POSIX… yet; see notes under POSIX 2024
# it's *not* yet available in the dash builtin or busybox
# use either bash (#!/bin/bash) or coreutils to get this
printf '%s=%q\n' "$(basename "$f")" "$(cat "$f")"
done
;;
set)
[ -d "$envdir" ] || mkdir -pm 0700 "$envdir"
for e; do
case "$e" in
*=*) printf '%s' "${e#*=}" > "$envdir/${e%%=*}" ;;
*)
declare -n name="$e"
printf "$name" >"$envdir/$e"
;;
esac
done
;;
exec)
exec chpst -e "$envdir" "$@"
;;
esac
This is closely modeled after the runit backend, with the following changes:
Globally, this is an adaptation from what I wrote for my system to try and make it fit into the codebase better. What I had locally involved things like a more generic envdir handler that could be shared, but even if this is desirable, fitting into the existing codebase is a higher priority when upstreaming for me.
This adapted version is currently running on the system I am typing this on with no issues, but I did not perform consistent testing. I also didn't bother building/installing this (i.e. it's running by way of manually adding entries to /usr/libexec, /usr/local/bin, and /etc/turnstile).
It may be useful to give users guidance as to how to import the environment locally. NITRO_SOCK is in the envdir (which allows using nitroctl), but this is not automatically imported. I'm not sure if there's interest in automatically propagating service manager environment variables to a user shell like the DBUS_SESSION_BUS_ADDRESS, but even if there is I similarly consider this out of scope here.