Skip to content

feat(cli): tracebloc delete offboarding + Rev-9 single-machine surface (§7.10) - #160

Merged
saadqbal merged 7 commits into
developfrom
feat/tracebloc-delete-offboard
Jul 7, 2026
Merged

feat(cli): tracebloc delete offboarding + Rev-9 single-machine surface (§7.10)#160
saadqbal merged 7 commits into
developfrom
feat/tracebloc-delete-offboard

Conversation

@LukasWodka

Copy link
Copy Markdown
Contributor

Summary

Phase 1 of RFC-0001 §7.10 offboarding (spec: #157). Adds the top-level tracebloc delete — the soft offboard / inverse-of-install — plus the Rev-9 single-machine surface changes.

What's in

  • tracebloc delete (top-level, internal/cli/delete.go) — the three-scope offboard:
    • Removed from this machine: revoke the machine credential (POST /edge-device/<id>/revokenot the 405 DELETE), helm uninstall, k3d cluster delete (prunes the kubeconfig entry), scoped image reclaim (ghcr.io/tracebloc/* only — never docker system prune), rm -rf ~/.tracebloc, then remove the CLI binary + tb alias.
    • Retained on the backend, as history: nothing is cascade-deleted; the summary says so.
    • Left in place: Docker / Homebrew / kubectl / k3d / helm / NVIDIA — listed, never touched, never a reboot.
    • Verification: typed client-name confirm (not [y/N]); --yes for automation; --keep-data spares ~/.tracebloc; --force overrides the running-job guard.
  • internal/nodeboot — teardown seam (based on the PROTOTYPE: client owns teardown; installer stays create front door; withdraw use, hide list #136 proto): ClusterExists/TeardownCluster/UninstallChart + new scoped PruneImages, injectable Runner, unit-tested with a fake (no real k3d/helm/docker).
  • Surface (Rev 9):client use removed, client list hidden (still callable for the installer pre-flight); home/help updated; residual client use guidance retargeted to client create.
  • Copy fix:data delete no longer claims the backend catalog entry is "removed automatically" — it's kept as a record, marked unavailable.

Adversarial pass — folded before this PR

A verify sweep caught one real issue: the config-save fallback hint still pointed at the now-removed client use; redirected to client create (last commit).

Testing

go build/vet/gofmt clean; go test ./... green (11 packages). delete_test.go proves the safety rails: no---yes-non-interactive refuses; the full sequence order (revoke → uninstall → teardown → prune → rm) via fake seams; --keep-data spares the dir; running-job guard needs --force; typed-name mismatch aborts; NEVER docker system prune. Nothing runs against a real cluster.

Refs: RFC-0001 §7.10 (#157) · epic backend#830 · flow family backend#880. Phase 2 (backend tombstone) is the sibling PR; the two meet at the revoke endpoint.

🤖 Generated with Claude Code

LukasWodkaand others added 5 commits July 7, 2026 13:02
Add internal/nodeboot — the inverse of the installer's node bootstrap that
`tracebloc delete` will drive. Based on the cli#136 prototype's k3d/helm
teardown, with an injectable Runner exec seam:
- ClusterExists(name) / TeardownCluster(name) — `k3d cluster delete` when the
cluster exists (also prunes its kubeconfig entry); a missing cluster is an
idempotent no-op.
- UninstallChart(namespace) — `helm uninstall`, swallowing not-found.
- PruneImages() — NEW beyond #136: reclaim tracebloc images, SCOPED to
`ghcr.io/tracebloc/*` (docker images -q | docker rmi), deduped, best-effort.
NEVER a blanket `docker system prune`.
All four are unit-tested against a fake Runner — no real k3d/helm/docker runs.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add `tracebloc delete` — a top-level command (NOT `client delete --uninstall`):
on the single-machine CLI the host owns one client, so "delete the client" is
"remove tracebloc," and a top-level verb avoids colliding with `data delete`.
A SOFT offboard with a removed / retained / left three-way summary shown before
a TYPED-CLIENT-NAME confirm (skipped only with --yes). Flow, in order:
- guard: refuse if the client is online / has a running job unless --force
(reuses the #146 lookupClientStatus / clientStatusOnline);
- api.RevokeClient(id) → POST /edge-device/<id>/revoke (NEW; 2xx = revoked) —
kills the credential while PRESERVING the row (never a hard destroy that
would cascade the retained training history);
- nodeboot.UninstallChart → TeardownCluster → PruneImages (best-effort warns);
- rm -rf HOST_DATA_DIR (~/.tracebloc) unless --keep-data;
- remove the running CLI binary + its sibling `tb` symlink LAST (best-effort;
on failure prints the exact rm, or `brew uninstall tracebloc` if brew-managed).
Never removes Docker/Homebrew/kubectl/k3d/helm/NVIDIA, never reboots, never
`docker system prune`. Flags: --yes / --keep-data / --force + the standard
--kubeconfig/--context/--namespace; uses the existing exitError contract.
Tests (fake nodeboot Runner + httptest backend + temp HOST_DATA_DIR + temp
config dir; no real ~/.tracebloc, k3d/helm/docker): (a) no --yes non-interactive
refuses with no side effects; (b) --yes runs the full sequence — revoke POSTed to
/edge-device/<id>/revoke, nodeboot fakes called in order, ~/.tracebloc removed;
(c) --keep-data spares ~/.tracebloc; (d) running job refuses unless --force;
(e) the RETAINED + LEFT copy is present in output.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
….10)
The single-machine CLI owns exactly one client, so there is nothing to select:
- Remove `client use` (newClientUseCmd + runClientUse + its AddCommand entry +
TestClientUse). The active-client pointer is now set only by `client create`.
- Hide `client list` (Hidden: true) — kept callable for the installer's
one-client-per-machine pre-flight, off the user-facing surface.
- Rewrite the `client` parent help and the root home-screen: drop the
`client list` line, add `tracebloc delete`, point offboarding at it.
- Retarget the residual "run `client use`" guidance (create save-failure fallback,
client status, doctor, clustertarget "runs elsewhere" + multi-namespace refusal)
to `client create` / --namespace, and adjust the test that asserted the old string.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…0001 §7.10)
The catalog metadata for a deleted dataset is NEVER removed — it is kept as a
record on tracebloc and marked unavailable (soft-flagged). The old
"removed automatically" copy in `data delete` help + its success line, and the
push.TeardownPlan doc comment, wrongly implied the backend deletes it. Reword
all three to "kept as a record on tracebloc, marked unavailable."
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Review finding (medium): the client-create config-save fallback still pointed
at `tracebloc client use %d`, which T3 removes. Point it at `client create`
(idempotent — it re-adopts this cluster's client).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Review follow-ups on the tracebloc delete offboarding PR:
- api: RevokeClient POSTs to /edge-device/<id>/revoke/ WITH a trailing
slash — the DRF DefaultRouter registers the `revoke` @action as
/edge-device/<pk>/revoke/, and a slashless body-bearing POST hits
Django's APPEND_SLASH (which errors instead of redirecting), aborting
the whole offboard at step 1.
- cli: a 403 on revoke now speaks in offboard terms ("offboarding
requires CLIENT_WRITE") instead of the provisioning copy the shared
askAnAdmin hardcoded; askAnAdmin takes action/capability params.
- cli: an empty namespace warns + points at --namespace instead of
silently skipping the Helm uninstall while the summary claims success.
- nodeboot: UninstallChart matches helm's specific "release: not found",
not a bare "not found" that could swallow a cluster-unreachable error.
- cli: --force help no longer advertises a running-job check the guard
doesn't implement.
- cli: looksBrewManaged resolves symlinks so the Intel /usr/local/bin →
Cellar install gets the `brew uninstall` hint.
- config: correct stale `client use` comment.
Tests added for each behavioral fix; go build/vet/test green (11 pkgs).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@saadqbal
saadqbal merged commit bd748d4 into developJul 7, 2026
14 checks passed
@saadqbal
saadqbal deleted the feat/tracebloc-delete-offboard branch July 10, 2026 10:37
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@LukasWodka@saadqbal@divyasinghds