You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: CLAUDE.md
+2Lines changed: 2 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -77,6 +77,8 @@ Notification state is persisted in `${CACHE_LOCATION}/hoist-<safe-name>.notified
77
77
78
78
Each `process_container` invocation appends outcome tokens (`updated`, `update_failed`, `notified`, `no_change`, `skipped`, `not_compose_managed`, `would_update`, `would_notify`, `paused`, `constraint_blocked`, `group_aborted`, `unhealthy`, `rolled_back`, `rollback_failed`) to `${CACHE_LOCATION}/hoist-<safe-name>.run-result`. After all containers finish, `print_summary` aggregates them into a single one-line summary. Result files (and `hoist-group-*.failed` flags) are wiped at the start of each run. The end-of-run Healthchecks.io ping is `/fail` if any container produced `update_failed`, `unhealthy`, or `rollback_failed`; otherwise success. **`not_compose_managed`** flags a container with hoist `update`/`notify` labels but no `com.docker.compose.*` metadata — it's logged unconditionally and can't be acted on.
79
79
80
+
When `SUMMARY_LIST_NAMES` is true (default), the summary also names which containers landed in the `updated`/`update_failed` buckets, e.g. `4 updated [web, api, db, cache] (1 failed: worker)`, instead of just counts — the other buckets stay counts-only to avoid bloating the line on routine runs. `process_container` writes each container's raw name once, up front, to a sibling `${CACHE_LOCATION}/hoist-<safe-name>.name` file (wiped alongside `.run-result`/`.rollup` at run start); `print_summary` joins it back in only for containers whose `.run-result` contained `updated` or `update_failed`. Set `SUMMARY_LIST_NAMES=false` to keep the old count-only text (e.g. for scripts that parse the summary line verbatim).
81
+
80
82
### Run lock and exit code
81
83
82
84
`_acquire_run_lock` (`hoist.sh:417`) takes an exclusive `flock` on `${CACHE_LOCATION}/hoist.lock` at startup (with an `mkdir`-plus-stale-PID fallback when `flock` is absent). A second run that finds the lock held logs and exits 0 rather than racing over shared state; `--list`/`--status` skips the lock. **flock fd handoff:** bash sets no close-on-exec on the `{_LOCK_FD}` redirection fd, so docker/compose children and `&`-spawned workers would otherwise inherit it and keep the lock held — a Ctrl+C that orphans a `docker compose pull` subprocess would wedge every later run with "Another hoist run holds the lock". So after acquiring, hoist hands the held fd to a single childless holder process (`( exec sleep … ) &`, `disown`ed so the parallel pool's `wait`/`wait -n` ignore it), closes its own copy of the fd, and arms an EXIT trap (also reached via `_on_signal`'s `exit`) that kills the holder — releasing the lock the instant hoist truly exits, regardless of orphaned docker children. After `print_summary`, hoist **exits non-zero** if any container produced `update_failed`, `unhealthy`, or `rollback_failed` (drives `Type=oneshot` systemd, cron `MAILTO`, CI). Boolean gates (`update`/`notify`/`rollback`/`healthcheck.wait`, `ROLLBACK_DEFAULT`) are routed through `_is_true`, which accepts `true|1|yes|on` case-insensitively.
# Dry-run does not pull, so it cannot know which containers actually have
@@ -2656,7 +2688,14 @@ print_summary() {
2656
2688
msg="Run complete (dry-run): ${would_update} eligible to update, ${would_notify} eligible to notify (not pulled — run live to detect available updates), ${skipped} skipped"
0 commit comments