refactor(apps): per-app post-install hooks + move gluetun/crowdsec logic into their apps

Replace the central app-name if-ladder in app_update_specifics.sh with a generic
dispatcher: each app ships containers/<app>/scripts/<app>_update_specifics.sh
defining appUpdateSpecifics_<app> (live-sourced by the container scan, dispatched
by `declare -F` — same pattern as tools). A hook may set shouldrestart=true. Apps
with no specifics ship no hook.

- Move the adguard/pihole (DNS updater), dashy (conf refresh), focalboard (nobody
  ownership + restart), and libreportal (webui regen) branches to per-app hooks.
- Move scripts/gluetun/gluetun_route_apps.sh -> containers/gluetun/scripts/
  (scripts/gluetun/ removed).
- Move scripts/install/install_crowdsec.sh -> containers/crowdsec/scripts/
  crowdsec_install_host.sh; fix the path note in crowdsec.sh.
- Regenerate arrays (moved files drop out; the per-app files are container-scanned,
  not arrayed).

Dispatch verified with stubs: adguard/pihole/dashy/focalboard/libreportal behave
identically to the old ladder (incl. shouldrestart propagation), apps without a
hook are a clean no-op. The CLI itself had no per-app branches — app-specific CLI
is already the (now fully modular) tools system.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Signed-off-by: librelad <librelad@digitalangels.vip>
This commit is contained in:
librelad 2026-05-25 23:38:19 +01:00
parent e944e4b92c
commit 98e1a0a05d
12 changed files with 63 additions and 42 deletions

View File

@ -0,0 +1,12 @@
#!/bin/bash
# Post-install/update specifics for AdGuard Home — dispatched by appUpdateSpecifics
# (containers/<app>/scripts/<app>_update_specifics.sh defining appUpdateSpecifics_<app>).
appUpdateSpecifics_adguard() {
local app_name="$1"
if [[ $CFG_REQUIREMENT_DNS_UPDATER == "true" ]]; then
updateDNS "$app_name" install
fi
# Split-horizon local DNS: app subdomains resolve to the box on the LAN.
declare -F setupLocalDnsRewrites >/dev/null 2>&1 && setupLocalDnsRewrites
}

View File

@ -4,8 +4,8 @@
# Description : CrowdSec - Intrusion Prevention (c/u/s/r/i): # Description : CrowdSec - Intrusion Prevention (c/u/s/r/i):
# #
# Host-installed agent (apt + systemd) — no Docker container. Host install # Host-installed agent (apt + systemd) — no Docker container. Host install
# logic lives in scripts/install/install_crowdsec.sh (installCrowdsecHost); # logic lives in scripts/crowdsec_install_host.sh (installCrowdsecHost) beside
# install registration uses the shared hostAppInstall helper # this file; install registration uses the shared hostAppInstall helper
# (scripts/install/host_app.sh). uninstall/stop/restartCrowdsec (below) are the # (scripts/install/host_app.sh). uninstall/stop/restartCrowdsec (below) are the
# host-side hooks dockerUninstallApp / dockerStopApp / dockerRestartApp invoke. # host-side hooks dockerUninstallApp / dockerStopApp / dockerRestartApp invoke.

View File

@ -0,0 +1,10 @@
#!/bin/bash
# Post-install/update specifics for Dashy — dispatched by appUpdateSpecifics.
appUpdateSpecifics_dashy() {
# Refresh apps-services.json (the source of truth appDashyUpdateConf reads)
# before generating dashy's conf.yml. On a first dashy install the file may
# not yet reflect dashy itself; on a re-install the previous selection survives.
webuiLibrePortalUpdate
appDashyUpdateConf
}

View File

@ -0,0 +1,12 @@
#!/bin/bash
# Post-install/update specifics for Focalboard — dispatched by appUpdateSpecifics.
appUpdateSpecifics_focalboard() {
local app_name="$1"
# Focalboard runs as nobody (65534) and writes its sqlite db + uploads under
# its mounted data dir; fixPermissionsBeforeStart hands the dir to the install
# user, so give it to 65534 here or the server can't open the database.
# Setting shouldrestart (not local) requests the restart in appUpdateSpecifics.
runOwnership app-data-nobody "$app_name"
shouldrestart="true"
}

View File

@ -0,0 +1,8 @@
#!/bin/bash
# Post-install/update specifics for LibrePortal itself — dispatched by
# appUpdateSpecifics. Regenerate the WebUI data so the dashboard reflects the
# just-(re)installed control plane.
appUpdateSpecifics_libreportal() {
webuiLibrePortalUpdate
}

View File

@ -0,0 +1,11 @@
#!/bin/bash
# Post-install/update specifics for Pi-hole — dispatched by appUpdateSpecifics.
appUpdateSpecifics_pihole() {
local app_name="$1"
if [[ $CFG_REQUIREMENT_DNS_UPDATER == "true" ]]; then
updateDNS "$app_name" install
fi
# Split-horizon local DNS: app subdomains resolve to the box on the LAN.
declare -F setupLocalDnsRewrites >/dev/null 2>&1 && setupLocalDnsRewrites
}

View File

@ -1,40 +1,19 @@
#!/bin/bash #!/bin/bash
# Generic post-install/update dispatcher. App-specific behavior lives WITH the app:
# containers/<app>/scripts/<app>_update_specifics.sh defines appUpdateSpecifics_<app>
# (live-sourced by the container scan). A hook may set shouldrestart=true to request
# a container restart. Apps with no specifics simply ship no hook.
appUpdateSpecifics() appUpdateSpecifics()
{ {
local app_name="$1" local app_name="$1"
# Initialize setup. # Initialize setup (loads CFG_* for the hook to read).
initializeAppVariables $app_name; initializeAppVariables $app_name;
if [[ $app_name == "adguard" ]] || [[ $app_name == "pihole" ]]; then local hook="appUpdateSpecifics_${app_name}"
if [[ $CFG_REQUIREMENT_DNS_UPDATER == "true" ]]; then if declare -F "$hook" >/dev/null 2>&1; then
updateDNS $app_name install; "$hook" "$app_name"
fi
# Split-horizon local DNS: app subdomains resolve to the box on the LAN.
declare -F setupLocalDnsRewrites >/dev/null 2>&1 && setupLocalDnsRewrites
fi
if [[ $app_name == "libreportal" ]]; then
webuiLibrePortalUpdate;
fi
if [[ $app_name == "dashy" ]]; then
# Refresh apps-services.json (the source of truth that
# appDashyUpdateConf reads) before generating dashy's conf.yml.
# On a first dashy install the file may not yet reflect dashy
# itself; on a re-install the previous selection survives.
webuiLibrePortalUpdate;
appDashyUpdateConf;
fi
if [[ $app_name == "focalboard" ]]; then
# Focalboard runs as nobody (65534) and writes its sqlite db + uploads
# under its mounted data dir; fixPermissionsBeforeStart hands the dir to
# the install user, so give it to 65534 here or the server can't open
# the database. Restart so it picks the dir up.
runOwnership app-data-nobody "$app_name";
shouldrestart="true";
fi fi
if [[ $shouldrestart == "true" ]]; then if [[ $shouldrestart == "true" ]]; then

View File

@ -1,9 +0,0 @@
#!/bin/bash
# This file is auto-generated by generate_arrays.sh
# Do not edit manually - run './scripts/source/files/generate_arrays.sh run' to regenerate
gluetun_scripts=(
"gluetun/gluetun_route_apps.sh"
)

View File

@ -6,7 +6,6 @@
install_scripts=( install_scripts=(
"install/host_app.sh" "install/host_app.sh"
"install/install_certificate.sh" "install/install_certificate.sh"
"install/install_crowdsec.sh"
"install/install_restic.sh" "install/install_restic.sh"
"install/install_swapfile.sh" "install/install_swapfile.sh"
"install/install_ufwd.sh" "install/install_ufwd.sh"

View File

@ -14,7 +14,6 @@ source_scripts=(
"source/files/arrays/files_database.sh" "source/files/arrays/files_database.sh"
"source/files/arrays/files_docker.sh" "source/files/arrays/files_docker.sh"
"source/files/arrays/files_function.sh" "source/files/arrays/files_function.sh"
"source/files/arrays/files_gluetun.sh"
"source/files/arrays/files_headscale.sh" "source/files/arrays/files_headscale.sh"
"source/files/arrays/files_install.sh" "source/files/arrays/files_install.sh"
"source/files/arrays/files_logs.sh" "source/files/arrays/files_logs.sh"