Let a server service carry helper scripts and timers, starting with UseSend's cert refresh
This commit is contained in:
1 parent
a987cbab66
commit
95fa480469
9 files changed
+304
-59
No files matched your search
+65
-15
@@ -4,8 +4,10 @@
|
||||
#
|
||||
# The repository carries the catalog: server/vps/<Name>/ holds a
|
||||
# compose.yml, a podman-<name>.service user unit, and an .env.example naming
|
||||
# what the service needs told. The machine carries the rest: ~/Server/<Name>/
|
||||
# is a real directory owning the .env (secrets never sit inside the checkout,
|
||||
# what the service needs told. A service may also carry helper units (any
|
||||
# other *.service or *.timer, e.g. a cert refresh) and helper files (scripts,
|
||||
# a README) beside them. The machine carries the rest: ~/Server/<Name>/ is a
|
||||
# real directory owning the .env (secrets never sit inside the checkout,
|
||||
# gitignored or not) and the bind-mounted data. Only the tracked files are
|
||||
# symlinked, so a `git clean` in the repo can never reach a database.
|
||||
#
|
||||
@@ -83,12 +85,12 @@ require_service() {
|
||||
fi
|
||||
}
|
||||
|
||||
# The one unit file a service directory carries. Its filename is its identity
|
||||
# -- podman-<name>.service, exactly what lands in the systemd user directory --
|
||||
# so nothing here invents a name that could drift from the file's.
|
||||
# The one compose unit a service directory carries. Its filename is its
|
||||
# identity -- podman-<name>.service, exactly what lands in the systemd user
|
||||
# directory -- so nothing here invents a name that could drift from the file's.
|
||||
unit_path_for() {
|
||||
local name="$1" unit
|
||||
for unit in "$SERVER_DIR/$name"/*.service; do
|
||||
for unit in "$SERVER_DIR/$name"/podman-*.service; do
|
||||
[[ -e "$unit" ]] || continue
|
||||
printf '%s' "$unit"
|
||||
return 0
|
||||
@@ -96,6 +98,44 @@ unit_path_for() {
|
||||
return 1
|
||||
}
|
||||
|
||||
# Every other unit in the directory: helper services and the timers that fire
|
||||
# them. They are linked beside the compose unit, and each timer is enabled.
|
||||
helper_units_for() {
|
||||
local name="$1" unit
|
||||
for unit in "$SERVER_DIR/$name"/*.service "$SERVER_DIR/$name"/*.timer; do
|
||||
[[ -e "$unit" ]] || continue
|
||||
[[ "$(basename "$unit")" == podman-*.service ]] && continue
|
||||
printf '%s\n' "$unit"
|
||||
done
|
||||
}
|
||||
|
||||
# The files linked into ~/Server/<Name>/: every visible top-level file that is
|
||||
# not a unit. That is compose.yml plus any helper script or README; dotfiles
|
||||
# are skipped so .env.example (and a stray .env) never become links.
|
||||
live_files_for() {
|
||||
local name="$1" file
|
||||
for file in "$SERVER_DIR/$name"/*; do
|
||||
[[ -f "$file" ]] || continue
|
||||
case "$file" in *.service|*.timer) continue ;; esac
|
||||
printf '%s\n' "$file"
|
||||
done
|
||||
}
|
||||
|
||||
link_service_files() {
|
||||
local name="$1" file unit
|
||||
mkdir -p "$TARGET_DIR/$name" "$UNIT_DIR"
|
||||
while IFS= read -r file; do
|
||||
link_file "$file" "$TARGET_DIR/$name/$(basename "$file")"
|
||||
done < <(live_files_for "$name")
|
||||
while IFS= read -r unit; do
|
||||
link_file "$unit" "$UNIT_DIR/$(basename "$unit")"
|
||||
done < <(helper_units_for "$name")
|
||||
}
|
||||
|
||||
helper_timers_for() {
|
||||
helper_units_for "$1" | grep '\.timer$' | xargs -r -n1 basename
|
||||
}
|
||||
|
||||
unit_name_for() {
|
||||
local unit
|
||||
unit="$(unit_path_for "$1")" || return 1
|
||||
@@ -111,10 +151,12 @@ unit_installed() {
|
||||
[[ -L "$UNIT_DIR/$unit_name" ]]
|
||||
}
|
||||
|
||||
# Everything this machine links for the service, so a change to a helper
|
||||
# script or timer is reported by relink just like a compose change.
|
||||
definition_hash() {
|
||||
local name="$1" unit
|
||||
unit="$(unit_path_for "$name")" || unit=/dev/null
|
||||
cat "$SERVER_DIR/$name/compose.yml" "$unit" 2>/dev/null | sha256sum | cut -d' ' -f1
|
||||
local name="$1"
|
||||
{ live_files_for "$name"; unit_path_for "$name" && echo; helper_units_for "$name"; } \
|
||||
| sort | xargs -r -d '\n' cat 2>/dev/null | sha256sum | cut -d' ' -f1
|
||||
}
|
||||
|
||||
recorded_hash() {
|
||||
@@ -198,6 +240,7 @@ cmd_enable() {
|
||||
fi
|
||||
|
||||
mkdir -p "$UNIT_DIR"
|
||||
link_service_files "$name"
|
||||
link_file "$unit_path" "$UNIT_DIR/$unit_name"
|
||||
systemctl --user daemon-reload
|
||||
if systemctl --user enable --now "$unit_name"; then
|
||||
@@ -207,6 +250,10 @@ cmd_enable() {
|
||||
err "$unit_name did not start; see: systemctl --user status $unit_name"
|
||||
exit 1
|
||||
fi
|
||||
local timer
|
||||
for timer in $(helper_timers_for "$name"); do
|
||||
systemctl --user enable --now "$timer" && ok "Enabled $timer"
|
||||
done
|
||||
}
|
||||
|
||||
cmd_disable() {
|
||||
@@ -216,11 +263,15 @@ cmd_disable() {
|
||||
local unit_name
|
||||
unit_name="$(unit_name_for "$name")" || { err "$name has no unit file in the catalog"; exit 1; }
|
||||
|
||||
local timer unit
|
||||
for timer in $(helper_timers_for "$name"); do
|
||||
systemctl --user disable --now "$timer" 2>/dev/null || true
|
||||
done
|
||||
systemctl --user disable --now "$unit_name" 2>/dev/null || true
|
||||
if [[ -L "$UNIT_DIR/$unit_name" ]]; then
|
||||
rm "$UNIT_DIR/$unit_name"
|
||||
systemctl --user daemon-reload
|
||||
fi
|
||||
for unit in "$UNIT_DIR/$unit_name" $(helper_units_for "$name" | xargs -r -n1 basename | sed "s|^|$UNIT_DIR/|"); do
|
||||
[[ -L "$unit" ]] && rm "$unit"
|
||||
done
|
||||
systemctl --user daemon-reload
|
||||
ok "$name disabled. ~/Server/$name, its .env and its data were not touched."
|
||||
}
|
||||
|
||||
@@ -267,8 +318,7 @@ cmd_relink() {
|
||||
unit_installed "$name" || continue
|
||||
|
||||
link_file "$unit_path" "$UNIT_DIR/$unit_name"
|
||||
mkdir -p "$TARGET_DIR/$name"
|
||||
link_file "$SERVER_DIR/$name/compose.yml" "$TARGET_DIR/$name/compose.yml"
|
||||
link_service_files "$name"
|
||||
refreshed=$((refreshed + 1))
|
||||
|
||||
# Changed since the last time this machine looked, which is what makes a
|
||||
|
||||
Reference in new issue
Block a user