ports/main/nnd-s6-services/manage.sh

190 lines
3.8 KiB
Bash
Raw Normal View History

2022-03-21 12:25:55 +00:00
#!/bin/sh
set +e
2022-03-21 12:25:55 +00:00
export PATH="/usr/bin:/bin"
error() {
echo "$@" >&2
}
alt_ab() {
if [ "$1" == "a" ]; then echo "b"; else echo "a"; fi
}
2023-12-14 09:56:14 +00:00
: ${S6_PATH:="${XDG_DATA_HOME:="/etc"}/s6"}
: ${S6_DIST_PATH:="${XDG_CONFIG_HOME:="/usr/share"}/nnd/s6/dist"}
2024-02-14 13:19:42 +00:00
: ${S6_LIVE_PATH:="${XDG_RUNTIME_DIR:="/run"}/s6-rc"}
: ${S6_SCANDIR_PATH:="${XDG_RUNTIME_DIR:="/run"}/service"}
2022-03-21 12:25:55 +00:00
: ${S6_RC_PATH:="$S6_PATH/rc"}
: ${S6_ENV_PATH:="$S6_PATH/env"}
2022-03-21 12:25:55 +00:00
: ${S6_SV_PATH:="$S6_PATH/sv"}
# A/B mode, always keep last copy
DB_FRESH_ACT() {
readlink "$S6_SV_PATH/current" | cut -d. -f2 # if it fails (missing), it will be empty and 'a' will be used as inactive by default
}
2022-03-21 12:25:55 +00:00
DB_FRESH_NAC() {
alt_ab "$(DB_FRESH_ACT)"
2022-03-21 12:25:55 +00:00
}
generate() {
if ! mkdir -p "$S6_SV_PATH"; then
error "Failed to create sv directory"
return "$?"
fi
2022-03-21 12:25:55 +00:00
local NAC="$(DB_FRESH_NAC)"
if [ -d "$S6_SV_PATH/current.$NAC" ]; then
if ! rm -rf "$S6_SV_PATH/current.$NAC"; then
error "Failed to remove inactive database path"
return "$?"
fi
fi
if ! s6-rc-compile "$S6_SV_PATH/current.$NAC" "$S6_RC_PATH"; then
error "Failed to compile current s6 database"
return "$?"
2022-03-21 12:25:55 +00:00
fi
}
swap() {
local new="current.$(DB_FRESH_NAC)"
if ! [ -d "$S6_SV_PATH/$new" ]; then
error "There's no database to switch to"
return 1
fi
if ! s6-rc-db -c "$S6_SV_PATH/$new" check; then
error "Database $new is invalid"
return "$?"
fi
if ! ln -sfn "$new" "$S6_SV_PATH/current"; then
error "Failed to update A/B current symlink"
return "$?"
fi
2022-03-21 12:25:55 +00:00
}
2022-12-08 08:09:51 +00:00
update() {
2024-02-14 13:19:42 +00:00
if ! s6-rc-update -l "$S6_LIVE_PATH" "$S6_SV_PATH/current.$(DB_FRESH_ACT)"; then
2022-12-08 08:09:51 +00:00
error "Failed to update live state of the database"
return "$?"
fi
}
dist() {
2024-02-14 13:19:42 +00:00
#for src in "$S6_DIST_PATH/rc"/* "$S6_DIST_PATH/env"/*; do
for src in "$S6_DIST_PATH/rc"/*; do
2022-12-08 08:09:51 +00:00
local svc="${src#$S6_DIST_PATH/}"
if [ ! -e "$S6_PATH/$svc" ]; then
default "$svc" || return "$?"
fi
done
}
cleanup() {
# Remove any dangling invalid symlinks
2022-12-08 08:09:51 +00:00
for i in rc env; do
removedangle /etc/s6/"$i" || return "$?"
done
}
2022-12-08 08:09:51 +00:00
default() {
for svc in $@; do
local src="$S6_DIST_PATH/$svc"
local target="$S6_PATH/$svc"
if ! [ -e "$src" ]; then
error "$svc doesn't exist"
return "$?"
fi
2022-12-08 08:09:51 +00:00
if [ -h "$target" ]; then
error "$svc is already a default instance"
return "$?"
fi
defaultfunc || return "$?"
done
}
custom() {
2022-12-08 08:09:51 +00:00
for svc in $@; do
local src="$S6_DIST_PATH/$svc"
local target="$S6_PATH/$svc"
2022-12-03 14:30:40 +00:00
2022-12-08 08:09:51 +00:00
if ! [ -e "$src" ]; then
error "$svc doesn't exist"
return "$?"
fi
2022-12-03 14:30:40 +00:00
if ! [ -h "$target" ]; then
2022-12-08 08:09:51 +00:00
error "$svc is already a custom instance"
return "$?"
fi
customfunc || return "$?"
done
}
2022-12-08 08:09:51 +00:00
customfunc() {
2023-12-14 09:56:14 +00:00
: ${src:?"Missing src in customfunc"}
: ${target:?"Missing target in customfunc"}
2022-12-08 08:09:51 +00:00
if ! rm "$target"; then
error "Failed to remove distributed directory $target"
return "$?"
fi
2022-12-08 08:09:51 +00:00
if ! cp -r "$src" "$target"; then
error "Failed to initialise custom directory $target"
return "$?"
fi
}
2022-12-08 08:09:51 +00:00
defaultfunc() {
2023-12-14 09:56:14 +00:00
: ${src:?"Missing src in defaultfunc"}
: ${target:?"Missing target in defaultfunc"}
if ! rm -rf "$target"; then
2022-12-08 08:09:51 +00:00
error "Failed to remove custom directory $target"
return "$?"
fi
2022-12-08 08:09:51 +00:00
if ! ln -sv "$src" "$target"; then
error "Failed to create reference to $src"
return "$?"
2022-12-03 14:30:40 +00:00
fi
}
2022-12-08 08:09:51 +00:00
removedangle() {
local dir="$1"
find -L "$dir" -maxdepth 1 -type l -exec rm -v -- {} +
}
2024-02-14 13:19:42 +00:00
# TODO
# makeusertree() {
# USR="$1"
# UID="$(id -u "$USR")"
# RUNTIME_DIR="/run/user/$UID"
# : ${PARENT_RCDIR:+"/etc/s6/rc"}
# s6-usertree-maker \
# -d "$RUNTIME_DIR"/service \
# -r usertree."$UID"/logger.usertree."$UID" \
# -l "$USR" \
# "$USR" \
# "$RUNTIME_DIR"/uncaught-logs/ \
# "$PARENT_RCDIR"
# }
2022-11-26 14:39:33 +00:00
cmd="$1"
shift
2022-12-08 08:09:51 +00:00
if [ -z "$cmd" ]; then
generate || return "$?"
swap || return "$?"
update || return "$?"
else
case "$cmd" in
generate|swap|update|dist|custom|default|cleanup) eval "$cmd" $@ || return "$?";;
2022-12-08 08:09:51 +00:00
*) error "Invalid command $cmd"; return 1;;
esac
fi