feat(installer): stop-and-check gate — recognize an existing install#339
Open
LukasWodka wants to merge 2 commits into
Open
feat(installer): stop-and-check gate — recognize an existing install#339LukasWodka wants to merge 2 commits into
LukasWodka wants to merge 2 commits into
Conversation
…ome screen
Re-running the installer on an already-set-up machine no longer drags the user
through full provisioning. A new read-only gate (scripts/lib/assess.sh) runs
after the banner and classifies the machine:
• healthy — cluster running AND a tracebloc release present AND jobs-manager
Ready AND the CLI present → print "Already set up on this
machine", hand off to `tracebloc` (the home screen), exit 0.
• degraded — cluster stopped / workload not Ready / CLI missing / any partial
state → print an honest one-liner, fall through to the normal
flow to reconcile.
• fresh — no cluster, or a cluster with no release → the normal flow.
assess is STRICTLY non-mutating and bounded: read-only `k3d cluster list`,
`helm list`/`get values` (reuses detect_installed_client), and a bounded
`kubectl get` (--request-timeout). On ANY uncertainty it degrades toward the
normal flow — never a false "healthy" that would skip a needed install. The
hand-off uses `exit 0` (not exec) so the EXIT-trap cleanup still runs; if the
CLI is somehow unresolvable it falls back to a status line and still exits 0.
--force / --reinstall (or TRACEBLOC_FORCE_REINSTALL=1) bypasses the gate. A
healthy machine still short-circuits under curl|bash (output only, no input).
Per-layer surgical repair of a degraded machine is a deliberate fast-follow so
this PR stays off provision.sh (clear of the active #838 work).
Wires the gate into main() (after print_banner, before the roadmap), adds
scripts/lib/assess.sh to the bootstrap FILES + gen-manifest, regenerates
scripts/manifest.sha256, and adds scripts/tests/assess.bats. New copy says
"secure environment", never "client". PR 2 of 2 (PR 1 = the cli home screen,
cli#244).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
… awk branch
Code-review should-fix items on the stop-and-check gate:
1. _assess_cluster_servers_running: add `|| line=""` to the awk-branch
assignment, mirroring the jq branch. awk's `exit` closes the pipe, so under
`set -o pipefail` a SIGPIPE from k3d (141) — or any k3d failure — would
otherwise propagate non-zero out of the assignment and abort the installer.
2. "healthy" must match the installer's OWN definition of ready. The probe now
requires ALL the workloads wait_for_client_ready checks — mysql-client,
${ns}-jobs-manager, ${ns}-requests-proxy — not jobs-manager alone. Previously
a machine with jobs-manager up but requests-proxy (training egress) or
mysql-client down was classified healthy and short-circuited without
reconciling — the false-positive we designed against.
Single source of truth: the deployment set is extracted into
_client_workload_deployments (common.sh); both wait_for_client_ready
(summary.sh) and the assess gate consume it, so they can't drift. Renamed
_assess_jobs_manager_ready -> _assess_workload_ready (reason stays
`workload-not-ready`); any one workload not-Ready/absent -> degraded.
Tests: _assess_workload_ready now covers all-three-Ready plus each workload
individually down/absent; classify covers "one down -> degraded" via the real
probe and "all three Ready + CLI -> healthy". Mutation-checked: shrinking the
shared list to jobs-manager-only fails the mysql-client/requests-proxy/one-down
tests. Manifest regenerated (assess.sh, common.sh, summary.sh). provision.sh
untouched.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Contributor
Author
|
👋 Heads-up — Code review queue is at 46 / 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.) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a read-only "stop-and-check" gate to the installer so re-running it on an already-set-up machine no longer drags the user through full provisioning. On a verifiably healthy machine it prints one line and hands off to
tracebloc(the home screen), then exits 0. Otherwise it falls through to today's 5-step flow, unchanged.This is PR 2 of 2 (PR 1 = the status-aware
traceblochome screen, tracebloc/cli#244). Together they fix the "I just wanted to use the CLI / reinstall, and suddenly a whole new environment gets provisioned" problem.Behavior
The gate runs after the banner, before the 5-step roadmap.
assess_existing_install()classifies the machine (read-only, bounded, never fatal):mysql-client+jobs-manager+requests-proxy) AND the CLI present → prints✓ Already set up on this machine — no need to run the installer again., then runstracebloc(the home screen) andexit 0. Never re-provisions, never re-prompts login.--force/--reinstall(orTRACEBLOC_FORCE_REINSTALL=1) bypasses the gate entirely. Non-interactive (curl | bash): healthy still short-circuits (the hand-off is output-only, reads no stdin); degraded/fresh run the normal flow.Safety (this is a public, cosign-verified installer)
assessis strictly read-only —k3d cluster list,kubectl get,helm list(via the reuseddetect_installed_client),has. It never starts the cluster, runshelm upgrade, mints credentials, or writes anything, and it does not call the mutating_handle_existing_cluster.scripts/lib/assess.shis added to both bootstrapFILESarrays andmanifest.sha256is regenerated (gen-manifest.sh --check→ up to date), so the cosign bootstrap still verifies;install-bootstrap.batsfile-count lists updated (15 → 16).exit 0(notexec) so theinstall_cleanupEXIT trap still runs — a verified no-op at gate time (before any credential / sudo-keepalive is set).provision.shuntouched, to stay clear of the active #838 provision rewrite.Single source of truth for "ready"
Extracted the client-workload deployment list into
_client_workload_deployments()(common.sh); bothwait_for_client_ready(the post-install gate) and the assess readiness probe consume it, so the installer's definition of "ready" and the gate's can't drift.Code review
Adversarial review before opening — both invariants (no false-healthy; non-mutating + manifest-consistent) confirmed and mutation-proven. Fixed in the second commit:
jobs-manager; a machine with jobs-manager up butrequests-proxy(training egress) ormysql-clientdown could be called "healthy" → now requires all three, via the shared helper.set -e/pipefail (SIGPIPE) → guarded to match its jq sibling.Deferred (fast-follow)
Surgical per-layer repair of a degraded machine (start-only / CLI-only / reconcile-only, and skipping re-login when already authenticated) — deliberately left out to keep this PR off
provision.shand clear of #838. Rebases cleanly once #838 lands.Test plan
scripts/tests/assess.bats(31 tests): each probe (cluster-running jq + awk fallback; workload-ready per-deployment incl.requests-proxy/mysql-clientdown; CLI present); all classify branches; the hand-off (runstracebloc,exit 0, fallback); and themain()branch (healthy → hand-off + exit 0;--forcebypass; degraded/fresh → flow). Assertions are fail-loud (grep-backed + single-bracket status) to dodge the macOS bats[[ ]]blindspot; the healthy short-circuit and the all-three-workloads gate are mutation-verified.shellcheck --severity=errorclean;bash -nclean;gen-manifest.sh --checkup to date.develop, unrelated files) — Linux CI is authoritative for bats.Checklist
developFILESin syncprovision.shuntouched (#838 coordination)Pairs with tracebloc/cli#244. Hand-off degrades gracefully: shows today's home screen on the released CLI, the new status-aware one once cli#244 ships.
Note
Medium Risk
Changes behavior of the cosign-verified public installer entrypoint; a false healthy would skip needed setup, though the design biases toward fall-through on any doubt and adds extensive bats coverage.
Overview
Adds a read-only stop-and-check gate so re-running the installer on an already-healthy machine skips full provisioning and hands off to
traceblocinstead.New
scripts/lib/assess.shclassifies the host as fresh, degraded, or healthy using boundedk3d/kubectl/helmprobes (never mutating). Only healthy short-circuits: running cluster, tracebloc release, all core workloads ready, and CLI present. Uncertainty always falls through to the normal install flow—never a false “already set up.”install-k8s.shinvokes the gate after the banner;--force/--reinstallandTRACEBLOC_FORCE_REINSTALL=1bypass it.assess.shis guarded when missing (stale bootstrap) like other optional libs._client_workload_deployments()incommon.shcentralizes readiness (mysql-client, jobs-manager, requests-proxy);wait_for_client_readyand the assess gate both use it so “ready” cannot drift.Bootstrap
FILES,gen-manifest.sh,manifest.sha256, help text, andassess.bats/ bootstrap tests updated for the new module.Reviewed by Cursor Bugbot for commit 18b113a. Bugbot is set up for automated code reviews on this repo. Configure here.