From 79cd3aa400df4d8d87e676d9fe60667b6afea75c Mon Sep 17 00:00:00 2001 From: mhoennig Date: Wed, 26 Aug 2026 18:28:57 +0200 Subject: [PATCH] fix(deploy): rsync-Ziele als ~/ statt $HOME/ (D77) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Seit rsync 3.2.4 ist --protect-args voreingestellt: Der entfernte Pfad geht nicht mehr durch eine Shell, und ein $HOME bleibt woertlich stehen. Gemessen gegen die Zielumgebung: change_dir "/home/pacs/mih00/$HOME/opt/werkbaum" failed. Mit ~/ gelingt es — die Tilde expandiert rsync selbst, und genau deshalb funktioniert deploy-prod.sh seit jeher. Derselbe Pfad steht jetzt in drei Schreibweisen da, je eine fuer systemd (%h), die Shell im ssh-Aufruf ($HOME) und rsync (~). Jedes der drei Werkzeuge liest ihn anders. Der Stub-Test hat das nicht gefunden, weil ein Protokoll-Skript nichts expandiert: Er bewies, dass die richtigen Pfade uebergeben werden, nicht dass die Gegenseite sie versteht. Co-Authored-By: Claude Opus 5 --- docs/DECISIONS.md | 21 +++++++++++++++++++++ scripts/deploy-backend.sh | 18 ++++++++++++------ 2 files changed, 33 insertions(+), 6 deletions(-) diff --git a/docs/DECISIONS.md b/docs/DECISIONS.md index 0eac69a..2f26454 100644 --- a/docs/DECISIONS.md +++ b/docs/DECISIONS.md @@ -6348,6 +6348,27 @@ Laufzeit-Abhängigkeit (Actuator) — er steht als eigener Knoten im Plan (`#be.scaffold.ci`), und bis dahin ist die 404 die ehrlichste Probe, die ohne ihn zu haben ist. +**Nachtrag beim ersten Lauf: `$HOME` taugt nicht als rsync-Ziel.** Das Skript +schrieb die entfernten Pfade als `$HOME/opt/werkbaum/…`. Seit rsync 3.2.4 ist +`--protect-args` aber **voreingestellt**: Der entfernte Pfad geht nicht mehr +durch eine Shell, und ein `$HOME` bleibt wörtlich stehen. Gemessen gegen die +Zielumgebung (beide Seiten 3.2.7): `change_dir "/home/pacs/mih00/$HOME/opt/ +werkbaum" failed: No such file or directory`. Mit `~/opt/werkbaum` gelingt es — +die Tilde expandiert rsync selbst, und genau deshalb funktioniert +`deploy-prod.sh` seit jeher. + +Damit steht derselbe Pfad jetzt in **drei** Schreibweisen im Skript, je eine +für systemd (`%h`, keine Shell-Variablen), die Shell im ssh-Aufruf (`$HOME`) +und rsync (`~`). Das sieht nach Umständlichkeit aus und ist keine: Jedes der +drei Werkzeuge liest den Pfad anders, und zwei davon scheitern still oder +legen ein Verzeichnis an, das wörtlich `$HOME` heißt. + +**Warum es der Stub-Test nicht gefunden hat:** Er ersetzte `rsync` durch ein +Skript, das seine Argumente protokolliert — und ein Protokoll expandiert +nichts. Der Test hat bewiesen, dass die richtigen Pfade *übergeben* werden, +nicht dass die Gegenseite sie versteht. Dieselbe Grenze wie in D25 und D72, +nur eine Ebene tiefer: Ein Stub prüft die eigene Seite der Naht. + **Nicht getestet, weil es nicht zu testen war:** Alles bis zur SSH-Grenze ist gemessen — die erzeugte Unit ist mit `systemd-analyze verify` gültig, das Jar startet mit **genau** den Flags der Unit in einer Sekunde, antwortet auf die diff --git a/scripts/deploy-backend.sh b/scripts/deploy-backend.sh index 2df20d2..d04aead 100755 --- a/scripts/deploy-backend.sh +++ b/scripts/deploy-backend.sh @@ -69,11 +69,17 @@ JDK_DIR="$(env_value BACKEND_JDK_DIR)"; JDK_DIR="${JDK_DIR:-opt/jdk21}" PORT="$(env_value BACKEND_PORT)"; PORT="${PORT:-9080}" XMX="$(env_value BACKEND_XMX)"; XMX="${XMX:-192m}" -# Zweimal derselbe Pfad in zwei Schreibweisen: systemd kennt `%h`, die Shell -# kennt `$HOME` — und systemd expandiert `$HOME` nicht (siehe Unit-Vorlage). +# Derselbe Pfad in DREI Schreibweisen, weil ihn drei Werkzeuge lesen: +# +# systemd kennt `%h` und expandiert **keine** Shell-Variablen +# die Shell kennt `$HOME` (in einem ssh-Aufruf läuft eine) +# rsync kennt `~`, aber **kein** `$HOME`: Seit 3.2.4 ist +# `--protect-args` voreingestellt, der entfernte Pfad geht also +# nicht mehr durch eine Shell. Ein `$HOME` bliebe wörtlich stehen — +# gemessen: „change_dir /home/pacs/mih00/\$HOME/opt/werkbaum failed". case "$DIR" in - /*) DIR_UNIT="$DIR"; DIR_SH="$DIR" ;; - *) DIR_UNIT="%h/$DIR"; DIR_SH="\$HOME/$DIR" ;; + /*) DIR_UNIT="$DIR"; DIR_SH="$DIR"; DIR_RSYNC="$DIR" ;; + *) DIR_UNIT="%h/$DIR"; DIR_SH="\$HOME/$DIR"; DIR_RSYNC="~/$DIR" ;; esac case "$JDK_DIR" in /*) JAVA_UNIT="$JDK_DIR/bin/java" ;; @@ -126,9 +132,9 @@ fi # räumt nicht auf. echo "==> Übertragen" ssh "$SSH_TARGET" "mkdir -p \"$DIR_SH\" \"\$HOME/.config/systemd/user\"" -rsync -az --chmod=F644 "$STAGE/werkbaum-backend.jar" "$SSH_TARGET:$DIR_SH/werkbaum-backend.jar" +rsync -az --chmod=F644 "$STAGE/werkbaum-backend.jar" "$SSH_TARGET:$DIR_RSYNC/werkbaum-backend.jar" rsync -az --chmod=F644 "$STAGE/werkbaum-backend.service" \ - "$SSH_TARGET:\$HOME/.config/systemd/user/werkbaum-backend.service" + "$SSH_TARGET:~/.config/systemd/user/werkbaum-backend.service" ssh "$SSH_TARGET" DIR="$DIR_SH" PORT="$PORT" RESTART="$RESTART" 'bash -s' <<'REMOTE' set -euo pipefail