Uh oh!
There was an error while loading. Please reload this page.
fix(#431): idempotent GPU reconfigure — no cluster bounce on re-run - #508
Conversation
…ounce on re-run
On a GPU host, every re-run of install_nvidia_container_toolkit unconditionally ran
`nvidia-ctk runtime configure --runtime=docker`, then `systemctl restart docker`,
then a CUDA smoke test that re-pulls nvidia/cuda. Restarting Docker takes the live
k3d cluster DOWN mid-reinstall (a correctness hazard, not just wasted time).
- Skip-when-satisfied: reconfigure + restart Docker only when the running daemon
isn't ALREADY defaulting to the NVIDIA runtime (_docker_default_runtime_is_nvidia
via `docker info`). A re-run on a configured host does nothing here — no restart,
no cluster bounce.
- When a restart IS needed and the cluster is live, say so and sequence it: warn,
restart Docker, then `k3d cluster start` to bring the cluster back deterministically
rather than relying only on the nodes' restart policy. Cluster-running is detected
jq-free via _k3d_cluster_running.
- Cache the smoke test: record the toolkit+driver signature (_gpu_stack_signature) of
the last PASSING test; skip (no image pull) when unchanged, re-verify when it changes.
Also fixes a latent awk bug the tests caught: an `exit 0` in a main rule still runs
END, so the old `END { exit 1 }` overrode a positive result — the running-cluster
check now decides only in END.
Tests: new scripts/tests/gpu-nvidia.bats — the three helpers plus the acceptance
behaviors (already-nvidia -> no reconfigure/restart; not-nvidia -> reconfigure +
restart; live cluster -> warn + k3d cluster start; cached smoke test -> no pull;
first run -> records the signature).
Closes#431LukasWodka
commented
Jul 31, 2026
👋 Heads-up — Code review queue is at 42 / 30 Above the WIP limit. The team convention is to review existing PRs before opening new work. Open PRs currently in Code review (oldest first):
Pull from review before opening new work. (This is a nudge from the kanban WIP check, not a block.) |
LukasWodka
commented
Jul 31, 2026
👋 Heads-up — Code review queue is at 50 / 30 Above the WIP limit. The team convention is to review existing PRs before opening new work. Open PRs currently in Code review (oldest first):
Pull from review before opening new work. (This is a nudge from the kanban WIP check, not a block.) |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
… reconfigure Bugbot round on the idempotent GPU work: - High: _docker_default_runtime_is_nvidia ran a bare `docker info` with no timeout — a wedged daemon would hang a headless re-run at the skip gate. Route it (and the k3d probe) through _bounded (timeout(1)/gtimeout(1)) with TB_PROBE_TIMEOUT. - Medium: after warning the cluster would restart, `k3d cluster start` discarded output and `|| true`'d failure, so a failed bring-up was reported as success. Capture output, and on failure warn with the k3d error + a manual-start hint. - Medium: the smoke-test cache keyed only on toolkit+driver signature, so a re-run that ACTUALLY reconfigured + restarted Docker could still skip `docker run --gpus all` and report a possibly-broken post-restart path as verified. Force the smoke test (bypass the cache) whenever the runtime was reconfigured this run. Tests: bounded-probe source guard; a failed cluster restart is surfaced (warn + manual hint); a reconfigure re-verifies even with a matching marker. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Uh oh!
There was an error while loading. Please reload this page.
The `k3d cluster start` added to bring the cluster back after a Docker restart had no
deadline; k3d defaults to --wait with timeout 0 (forever), so a slow post-restart
bring-up could hang a headless re-run. Add --wait --timeout "${min}m"
(TB_CLUSTER_START_TIMEOUT_MIN, default 5) so it aborts with a real k3d error — which
the existing failure path then surfaces (warn + manual-start hint). Mirrors the
bounded `cluster create` (#426). Source guard added.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
…r stale smoke marker Bugbot round 3: - Medium: a forced smoke re-verify that FAILS left the old .gpu-smoke-ok marker in place, so the next (reconfigured=0) run saw a matching signature and skipped the test, treating a failing stack as verified. Remove the marker on smoke failure. - Medium: _k3d_cluster_running returned "not running" both when the cluster was genuinely down AND when the bounded probe failed/timed out. On a wedged daemon (which also fails the nvidia check) that meant Docker was restarted WITHOUT a cluster start, silently leaving a live cluster down. Make it tri-state (0 running / 1 not running / 2 unknown); the caller now attempts recovery on running OR unknown, warning "Couldn't confirm … will try to bring it back". Tests: probe failure -> unknown (rc 2); unknown state still attempts recovery + warns; a failed forced smoke test clears the stale pass marker. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
…et -euo) Bugbot round 4 — the idempotency helpers tripped the installer's `set -e`: - High: `_k3d_cluster_running; cr=$?` (and the internal `out=$(...); rc=$?`) are bare sequences, so a non-zero probe aborts the install before `systemctl restart docker` on a first-run GPU host (no cluster yet, probe returns 1) — and made the UNKNOWN(2) timeout path unreachable. Use `|| cr=$?` / `|| rc=$?` so the code is captured, not fatal. - Medium: `_gpu_stack_signature` ended on a failed `[[ -n … ]] && printf`, returning 1 when no versions are found; `gpu_sig="$(…)"` then aborted under set -e. Add `return 0` so an empty signature means "don't cache", not "abort". Tests: two set -e integration tests (source common.sh + gpu-nvidia.sh under `set -euo pipefail`) — empty signature and a failed cluster probe both complete without aborting. These exercise the exact context the unit tests (no set -e) missed. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Uh oh!
There was an error while loading. Please reload this page.
_gpu_stack_signature shelled out to nvidia-ctk + nvidia-smi with no deadline, and it
runs at the smoke-test skip gate on every re-run — a half-ready driver (installed
without reboot) or a stuck device node could hang a headless re-run, the same class
already bounded for docker info / k3d cluster list. Route both through _bounded
"${TB_PROBE_TIMEOUT:-5}"; an empty signature on timeout already means "don't cache".
Source guard extended to assert both signature probes are bounded.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 1917877. Configure here.
Uh oh!
There was an error while loading. Please reload this page.
The two _gpu_stack_signature tests didn't mock `has`, so on a runner that HAS
timeout(1) (CI) the newly-_bounded probes exec the real (absent) nvidia-ctk/nvidia-smi
via `timeout` — which can't see shell-function mocks — and the "combines versions"
assertion failed (it passed on macOS, which lacks timeout, so _bounded took its
passthrough branch). Add `has() { return 1; }` to both tests so _bounded runs the
function mocks, matching how the docker/k3d probe tests already suppress timeout.
Verified with a fake `timeout` on PATH: 21/21 pass. Production is unaffected (real
GPU hosts have the binaries); this was purely a test-mocking gap.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>LukasWodka
commented
Aug 2, 2026
/fr-pass |

#431 — idempotent GPU reconfigure (no Docker restart / cluster bounce on re-run)
On a Tier-1/2 GPU host, every re-run of
install_nvidia_container_toolkitunconditionally rannvidia-ctk runtime configure --runtime=docker, thensystemctl restart docker,sleep 3, and a CUDA smoke test (docker run --gpus all nvidia/cuda:…). Restarting Docker takes the live k3d cluster down mid-reinstall — a correctness hazard, not just wasted time — and the smoke test re-pulls the CUDA image whenever it was evicted.Fix (
scripts/lib/gpu-nvidia.sh)_docker_default_runtime_is_nvidia, viadocker info). A re-run on a configured host does nothing here — no restart, no cluster bounce, no image pull._k3d_cluster_running, jq-free), it warns that the cluster will restart, restarts Docker, thenk3d cluster startbrings the cluster back deterministically rather than relying only on the nodes' restart policy._gpu_stack_signature) of the last passing test; skips the CUDA pull when unchanged, re-verifies when the toolkit or driver changes.Bonus (found by the tests)
Fixed a latent awk bug: an
exit 0in a main rule still runsEND, so the oldEND { exit 1 }overrode a positive result. The running-cluster check now decides only inEND.Acceptance
Tests
New
scripts/tests/gpu-nvidia.bats(13 tests): the three helpers + the acceptance behaviours — already-nvidia → no reconfigure/restart; not-nvidia → reconfigure + restart; live cluster → warn +k3d cluster start; cached smoke test → no pull; first run → records the signature.bash -n+shellcheck --severity=errorclean; check-style + check-drift clean;scripts/manifest.sha256regenerated (R8). CI discovers the new bats file via itsscripts/tests/*.batsglob.Closes#431
Note
Medium Risk
Touches installer paths that restart Docker and bring k3d back—high impact when mis-probed—but changes are guarded with bounded probes, explicit recovery, and broad bats coverage.
Overview
Makes
install_nvidia_container_toolkitsafe to re-run on hosts that already use the NVIDIA Docker runtime, so a repeat install no longer restarts Docker (which drops a live k3d cluster) or re-pulls the CUDA smoke-test image unless something actually changed.Skip-when-satisfied: New helpers probe the running daemon (
docker infovia bounded_bounded) and only runnvidia-ctk runtime configure+systemctl restart dockerwhen the default runtime is not alreadynvidia.When a restart is required: A tri-state
_k3d_cluster_runningcheck (running / not running / unknown on probe failure) drives warnings and a boundedk3d cluster start … --wait --timeoutrecovery path; cluster start failures are surfaced with a manual hint instead of being swallowed.Smoke-test cache: A toolkit+driver signature is stored in
~/.tracebloc/.gpu-smoke-ok(underHOST_DATA_DIR); matching signatures skipdocker rununless this run reconfigured Docker, in which case the GPU path is re-verified and failed runs clear the marker.Adds
scripts/tests/gpu-nvidia.batsfor helpers and acceptance cases; updatesscripts/manifest.sha256forgpu-nvidia.sh.Reviewed by Cursor Bugbot for commit 534403c. Bugbot is set up for automated code reviews on this repo. Configure here.