diff --git a/ops/README.md b/ops/README.md index ae7ddb05e..1db61bd68 100644 --- a/ops/README.md +++ b/ops/README.md @@ -24,6 +24,34 @@ Après déploiement, le contrôle qui compte n'est pas que le nouveau widget s'affiche : c'est que les intégrations **préexistantes** fonctionnent encore. C'est la seule preuve que `SECRET_ENCRYPTION_KEY` n'a pas bougé. +## Déplacer l'état hors de /appdata + +`/appdata` vient de l'image Docker, où c'est un point de montage. Sur une +machine, il ne suit aucune convention : l'état d'un service se range sous +`/var/lib`. La correction se fait sur l'**instance installée**, jamais dans le +dépôt — ni le code ni le Dockerfile ne sont touchés, sans quoi chaque rebase sur +l'amont rouvrirait le sujet. + +```bash +sudo ops/use-var-lib-homarr.sh /opt/homarr # ou /opt/homarr-dev +``` + +Le script réécrit `/appdata` en `/var/lib/homarr` dans le `run.sh` et le +`redis.conf` de l'instance, sauvegarde chaque fichier avant de le toucher, et +ajoute `LOCAL_CERTIFICATE_PATH` au démarrage. Cette dernière ligne n'est pas +cosmétique : le chemin des certificats n'est pas lu par `run.sh` mais par +l'application, qui retombe sur le dossier de l'image dès qu'il manque — elle +recréerait donc `/appdata` au premier certificat chargé. + +Le script ne déplace **pas** les données ; il imprime les commandes à passer une +fois, service arrêté. Sur cette installation, `/appdata` ne contient qu'un +fichier : le certificat racine qui valide la console UniFi locale. Le contrôle +d'après-déplacement est donc tout trouvé — si le widget UniFi OS répond encore, +le certificat a suivi. + +À relancer après chaque assemblage : `ops/assemble-standalone.sh` recopie le +`run.sh` du dépôt quand l'instance n'en a pas, et celui-là parle de `/appdata`. + ## Suivre les mises à jour d'Homarr Aujourd'hui `origin` pointe sur le dépôt d'Homarr lui-même et **aucune copie diff --git a/ops/use-var-lib-homarr.sh b/ops/use-var-lib-homarr.sh new file mode 100755 index 000000000..86fbc5bf0 --- /dev/null +++ b/ops/use-var-lib-homarr.sh @@ -0,0 +1,87 @@ +#!/usr/bin/env bash +# +# Fait pointer une instance Homarr installée sur /var/lib/homarr au lieu de +# /appdata. +# +# `/appdata` vient de l'image Docker, où c'est un point de montage. Sur une +# machine, il ne suit aucune convention : l'état d'un service se range sous +# /var/lib. Ce script agit sur l'INSTANCE INSTALLÉE — son `run.sh`, son +# `redis.conf` — et jamais sur le dépôt : ni le code source ni le Dockerfile ne +# sont touchés, pour que le fork reste rebasable sur l'amont. +# +# Idempotent : le relancer ne fait rien de plus. +# +# Usage : ops/use-var-lib-homarr.sh +# ex. : sudo ops/use-var-lib-homarr.sh /opt/homarr +# sudo ops/use-var-lib-homarr.sh /opt/homarr-dev +# +set -euo pipefail + +DIR="${1:?usage: ops/use-var-lib-homarr.sh }" +STATE="${HOMARR_STATE_DIR:-/var/lib/homarr}" +stamp="$(date +%F-%H%M%S)" + +[ -d "$DIR" ] || { echo "$DIR n'existe pas." >&2; exit 1; } +[ -f "$DIR/run.sh" ] || { echo "$DIR/run.sh introuvable — est-ce bien une instance assemblée ?" >&2; exit 1; } + +changed=0 + +for file in run.sh redis.conf; do + target="$DIR/$file" + [ -f "$target" ] || continue + grep -q '/appdata' "$target" || continue + + cp -a "$target" "$target.bak-$stamp" + sed -i "s#/appdata#$STATE#g" "$target" + echo "== $file" + diff -u "$target.bak-$stamp" "$target" | sed -n '4,$p' || true + changed=1 +done + +# Le chemin des certificats n'est pas lu par run.sh mais par l'application, qui +# retombe sur /appdata/trusted-certificates quand la variable est absente. +# Réécrire les `mkdir` ne suffit donc pas : sans cette ligne, Homarr créerait à +# nouveau /appdata au premier chargement de certificat. +if ! grep -q 'LOCAL_CERTIFICATE_PATH' "$DIR/run.sh"; then + [ -f "$DIR/run.sh.bak-$stamp" ] || cp -a "$DIR/run.sh" "$DIR/run.sh.bak-$stamp" + awk -v value="$STATE/trusted-certificates" ' + NR == 1 { + print + print "" + print "# Chemin des certificats de confiance. Sans cette ligne, l'\''application" + print "# retombe sur le dossier de l'\''image et le recrée au premier certificat lu." + print "export LOCAL_CERTIFICATE_PATH=\"${LOCAL_CERTIFICATE_PATH:-" value "}\"" + next + } + { print } + ' "$DIR/run.sh" > "$DIR/run.sh.new" + cat "$DIR/run.sh.new" > "$DIR/run.sh" # préserve les droits et le propriétaire + rm -f "$DIR/run.sh.new" + echo "== run.sh : LOCAL_CERTIFICATE_PATH ajouté ($STATE/trusted-certificates)" + changed=1 +fi + +if [ "$changed" -eq 0 ]; then + echo "Rien à faire : $DIR ne référence déjà plus /appdata." + exit 0 +fi + +mkdir -p "$STATE/trusted-certificates" + +cat </dev/null || true + sudo find /appdata -type f # doit ne RIEN afficher avant la suite + sudo rm -rf /appdata + sudo systemctl start homarr + +Le contrôle qui compte ensuite : l'intégration UniFi OS doit toujours répondre. +C'est elle qui valide son certificat avec le CA déplacé — si elle fonctionne, +le déplacement a réussi. +EOF diff --git a/scripts/run.sh b/scripts/run.sh index 97436c975..efcc50f9f 100644 --- a/scripts/run.sh +++ b/scripts/run.sh @@ -1,25 +1,9 @@ #!/usr/bin/env bash -# Create the directories this instance will actually write to. -# -# Derived from the configuration rather than hard-coded, so an installation that -# stores its state elsewhere — a bare-metal one under /var/lib, say — does not -# get an empty /appdata recreated behind its back at every start. The defaults -# reproduce the image's layout exactly: the Dockerfile sets DB_URL to -# /appdata/db/db.sqlite and DB_DIALECT to sqlite, and REDIS_IS_EXTERNAL to false. -mkdir -p "${LOCAL_CERTIFICATE_PATH:-/appdata/trusted-certificates}" - -# Only for SQLite: on any other engine DB_URL is a connection string, and its -# dirname would be a meaningless path. -if [ "${DB_DIALECT:-sqlite}" = "sqlite" ]; then - mkdir -p "$(dirname "${DB_URL:-/appdata/db/db.sqlite}")" -fi - -# The bundled Redis reads its directory from redis.conf; creating it when an -# external server is used would leave an empty directory nobody writes to. -if [ "$REDIS_IS_EXTERNAL" != "true" ]; then - mkdir -p /appdata/redis -fi +# Create sub directories in volume +mkdir -p /appdata/db +mkdir -p /appdata/redis +mkdir -p /appdata/trusted-certificates # Run migrations if [ "$DB_MIGRATIONS_DISABLED" = "true" ]; then