-
Notifications
You must be signed in to change notification settings - Fork 22
backend/nitro: add #36
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,100 @@ | ||
| #!/bin/sh | ||
| # | ||
| # This is the turnstile nitro backend. It accepts the action as its first | ||
| # argument, which is either "ready", "run", or "stop". In case of "run", it's | ||
| # invoked directly through /bin/sh as if it was a login shell, and therefore | ||
| # it has acccess to shell profile, and the shebang is functionally useless but | ||
| # should be preserved as a convention. For "ready", it's a regular shell. | ||
| # | ||
| # Arguments for "ready": | ||
| # | ||
| # srvstr: path to the readiness indicator temporary file | ||
| # | ||
| # Arguments for "run": | ||
| # | ||
| # ready_p: readiness pipe (fifo). has the path to a temporary file created by | ||
| # nitro SYS/setup written to it. | ||
| # srvdir: the nitro control socket goes here, as well as the envdir for chpst. | ||
| # the envdir then gets destructively symlinked to the service_env_dir. | ||
| # confdir: the path where turnstile's configuration data resides, used | ||
| # to source the configuration file | ||
| # | ||
| # Arguments for "stop": | ||
| # | ||
| # pid: the PID of the service manager to stop (gracefully); it should | ||
| # terminate the services it's running and then stop itself | ||
| # | ||
| # Copyright 2026 toast <code@toast.bunkerlabs.net> | ||
| # License: BSD-2-Clause | ||
|
|
||
| log() { echo "$@"; } >&2 | ||
| die() { log "$1"; exit "$2"; } | ||
|
|
||
| case "$1" in | ||
| ready) [ -f "$2" ] && exec rm "$2" || | ||
| die "nitro: invalid readiness indicator '$2'" 64 ;; | ||
| run) ;; # continued after esac | ||
| # nitro gracefully terminates on SIGTERM | ||
| stop) exec kill "$2" ;; | ||
| *) exit 32 ;; | ||
| esac | ||
|
|
||
| READYP=${2:?readiness pipe unset} | ||
| SRVDIR=${3:?srvdir unset} | ||
| CONFIG=${4:?confdir unset}/nitro.conf | ||
|
|
||
| if [ ! -p "$READYP" ]; then | ||
| die "nitro: invalid input argument(s)" 64 | ||
| fi | ||
|
|
||
| if [ ! -d "${HOME:?}" ]; then | ||
| dir "nitro: invalid home directory" 65 | ||
| fi | ||
|
|
||
| shift $# | ||
|
|
||
| # source system profile mainly for profile.d | ||
| # do it before switching to set -e etc. | ||
| [ -r /etc/profile ] && . /etc/profile | ||
| set -e | ||
| [ -r "$CONFIG" ] && . "$CONFIG" | ||
|
|
||
| # config defaults in case it's mangled or missing | ||
| : ${services_dir:="${HOME}/.config/nitro.session"} \ | ||
| ${service_env_dir:="${XDG_RUNTIME_DIR:?}/turnstile.env"} | ||
|
|
||
| envd="$SRVDIR/env" | ||
| mkdir -pm 0700 "$envd" | ||
| NITRO_SOCK="$SRVDIR/nitro.sock" | ||
| printf "$NITRO_SOCK" >"$envd/NITRO_SOCK" | ||
|
|
||
| # destructively symlink the per-manager envdir to the configured one | ||
| if [ -n "$service_env_dir" ]; then | ||
| [ -d "$(dirname "$service_env_dir")" ] || | ||
| die 'nitro: invalid location for service env_dir' | ||
| # unless we're not managing it | ||
| if [ ! -e "$service_env_dir" ] || [ -h "$service_env_dir" ]; then | ||
| ln -sf "$envd" "$service_env_dir" | ||
| else | ||
| die "nitro: refusing to overwrite '$service_env_dir'" 73 | ||
| fi | ||
| fi | ||
|
|
||
| # this must succeed | ||
| mkdir -p "$services_dir/SYS" | ||
| cat << EOF > "$services_dir/SYS/setup" | ||
| #!/bin/sh | ||
| # DO NOT MODIFY: THIS WILL GET OVERWRITTEN | ||
| # PLACE YOUR SETUP IN ./rc | ||
| [ -r ./rc ] && . ./rc # nitroctl start my core services | ||
| # signal readiness | ||
| if [ -p "$READYP" ]; then | ||
| touch "$SRVDIR/ready" | ||
| printf '%s' "$SRVDIR/ready" > "$READYP" | ||
| fi | ||
| EOF | ||
| chmod +x "$services_dir/SYS/setup" | ||
|
|
||
| # use envd directly so another manager can run at the same time | ||
| exec env TURNSTILE_ENV_DIR="$envd" NITRO_SOCK="$NITRO_SOCK" \ | ||
| nitro "$services_dir" |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| # This is the configuration file for turnstile's nitro backend. | ||
| # | ||
| # It follows the POSIX shell syntax (being sourced into a script). | ||
| # The complete launch environment available to dinit can be used. | ||
| # | ||
| # It is a low-level configuration file. In most cases, it should | ||
| # not be modified by the user. | ||
|
|
||
| # the directory user service files are read from. | ||
| services_dir="${HOME}/.config/nitro.session" | ||
|
|
||
| # the environment variable directory user service files can read from. | ||
| service_env_dir="${XDG_RUNTIME_DIR}/turnstile.env" |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| #!/bin/sh | ||
| # Copyright 2026 toast <code@toast.bunkerlabs.net> | ||
| # License: BSD-2-Clause | ||
|
|
||
| usage() { | ||
| cat <<-EOF | ||
| turnstile-update-nitro-env [VAR] ... | ||
| Updates values in the shared chpst(8) env dir. | ||
|
|
||
| If VAR is a variable name, the value is taken from the environment. | ||
| If VAR is VAR=VAL, sets VAR to VAL. | ||
| EOF | ||
| } | ||
|
|
||
| . @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}} | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i don't think it makes sense for the envdir to be in
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't really like doing that because you then end up with stale references. Consider for example:
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. |
||
|
|
||
| if [ $# -eq 0 ] || [ "$1" = "-h" ]; then | ||
| usage | ||
| exit 0 | ||
| fi | ||
|
|
||
| for var; do | ||
| case "$var" in | ||
| *=*) | ||
| eval echo "${var#*=}" > "$envd/${var%%=*}" | ||
| ;; | ||
| *) | ||
| eval echo '$'"$var" > "$envd/$var" | ||
| ;; | ||
| esac | ||
| done | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
would it make sense for this to be generic across backends that need it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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-envdirdraft 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.