Initialize Synology bind directories explicitly and preserve failed bootstrap journals

This commit is contained in:
Pigway
2026-10-08 00:54:15 +08:00
parent e927df9c62
commit b78b998bb8
3 changed files with 155 additions and 27 deletions
+11 -6
View File
@@ -216,11 +216,12 @@ Do not paste the real Secret into logs or repository files.
Bootstrap builds the verified main revision first, then acquires the same atomic
Docker daemon deployment lock used by deploy. Host path checks run in a short-lived,
network-disabled helper with **read-only** NAS root mounted, not CI workspace paths.
Only explicitly configured data/config directories are subsequently mounted writable
for initialization, owned `10333:10333`, mode `0750`. Nonempty directories, symlinks
Synology does not automatically create missing bind sources with `-v`. A temporary
network-disabled helper mounts the explicitly configured existing parent directories
and creates only their data/config leaves, owned `10333:10333`, mode `0750`. It never
mounts NAS root writable, recursively changes parent permissions, or deletes contents.
Parents must already exist; missing parents fail closed. Nonempty directories, symlinks
(including ancestor symlinks), overlapping paths and unknown journal resources fail closed.
Docker may create missing ancestor directories while creating these exact bind sources;
there is no recursive chmod/chown/delete on their parents.
A same-name residue can be removed **without force** only after checking all of:
Compose project/service labels; `Status=created`; `Running=false`;
@@ -241,8 +242,12 @@ The previously validated never-started residue has no rollback value and is not
**Data/config files, images/build cache and the private CD journal volume are retained.**
No `down -v`, volume prune or removal of unrelated/CI resources is used.
Cleanup failure retains the lock so the always recovery step can retry using the journal.
A failed bootstrap journal prevents automatic retry: review preserved data and diagnostics
before another bootstrap; do not automatically empty those directories or delete the journal.
Only an explicitly dispatched bootstrap may retry a failed first-install journal, and
only when its project/container/mounts/port match, its volume ownership matches, and
target directories remain empty or absent. Prepared/success/foreign journals are refused.
On a new transaction, the prior journal is archived as `deploy.<owner>.json` inside
the private state volume before replacing the active journal; generated data is never
automatically emptied and journals are never deleted.
Abrupt host/runner loss still requires operator review of the lock/journal.
The journal is private (0700/0600) and may contain prior/candidate secrets; never export it
as an Actions artifact. First bootstrap has no prior healthy version to roll back to.