fix(deploy): rsync-Ziele als ~/ statt $HOME/ (D77)

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 <noreply@anthropic.com>
This commit is contained in:
mhoennig
2026-08-26 18:28:57 +02:00
co-authored by Claude Opus 5
parent 4aff995a0e
commit 79cd3aa400
2 changed files with 33 additions and 6 deletions
+21
View File
@@ -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 (`#be.scaffold.ci`), und bis dahin ist die 404 die ehrlichste Probe, die ohne
ihn zu haben ist. 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 **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 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 startet mit **genau** den Flags der Unit in einer Sekunde, antwortet auf die
+12 -6
View File
@@ -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}" PORT="$(env_value BACKEND_PORT)"; PORT="${PORT:-9080}"
XMX="$(env_value BACKEND_XMX)"; XMX="${XMX:-192m}" XMX="$(env_value BACKEND_XMX)"; XMX="${XMX:-192m}"
# Zweimal derselbe Pfad in zwei Schreibweisen: systemd kennt `%h`, die Shell # Derselbe Pfad in DREI Schreibweisen, weil ihn drei Werkzeuge lesen:
# kennt `$HOME` — und systemd expandiert `$HOME` nicht (siehe Unit-Vorlage). #
# 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 case "$DIR" in
/*) DIR_UNIT="$DIR"; DIR_SH="$DIR" ;; /*) DIR_UNIT="$DIR"; DIR_SH="$DIR"; DIR_RSYNC="$DIR" ;;
*) DIR_UNIT="%h/$DIR"; DIR_SH="\$HOME/$DIR" ;; *) DIR_UNIT="%h/$DIR"; DIR_SH="\$HOME/$DIR"; DIR_RSYNC="~/$DIR" ;;
esac esac
case "$JDK_DIR" in case "$JDK_DIR" in
/*) JAVA_UNIT="$JDK_DIR/bin/java" ;; /*) JAVA_UNIT="$JDK_DIR/bin/java" ;;
@@ -126,9 +132,9 @@ fi
# räumt nicht auf. # räumt nicht auf.
echo "==> Übertragen" echo "==> Übertragen"
ssh "$SSH_TARGET" "mkdir -p \"$DIR_SH\" \"\$HOME/.config/systemd/user\"" 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" \ 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' ssh "$SSH_TARGET" DIR="$DIR_SH" PORT="$PORT" RESTART="$RESTART" 'bash -s' <<'REMOTE'
set -euo pipefail set -euo pipefail