Skip to content

feat(installer): Windows provisioning parity — login + client create before Helm (#388) - #397

Merged
saadqbal merged 3 commits into
developfrom
feat/win-provisioning-parity
Jul 27, 2026
Merged

feat(installer): Windows provisioning parity — login + client create before Helm (#388)#397
saadqbal merged 3 commits into
developfrom
feat/win-provisioning-parity

Conversation

@LukasWodka

@LukasWodkaLukasWodka commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

What

Ports the bash provisioning sequence (scripts/lib/provision.sh) to the Windows installer, closing the last item of the 2026-07-24 field-test epic (backend#1232). The Windows Step 4 was a generation behind: it stopped mid-install and had the user hand-copy a Client ID (UUID) and password from the web app — wrong-ID retry loops, a secret typed on screen, and a CLI home screen that permanently said "No secure environment on this machine yet" because the active-client pointer only gets written by tracebloc client create (#388).

New flow (bash parity):

  1. Step 3 — Install the tracebloc CLI (moved ahead of connect; failure is non-fatal and degrades Step 4 to the legacy fallback).
  2. Step 4 — Register this machine (Invoke-ProvisionClient): tracebloc login (device-code browser sign-in, attached to the console) + tracebloc client create --yes --credential-file. The credential never reaches the terminal — the file is parsed (KEY=value, first-= split) and deleted immediately; the minted slug becomes the namespace. Includes the one-client-per-machine pre-flight (fail-closed on inconclusive reads, legacy-tracebloc-namespace deferral to client create + the Helm guard) and Print-CreateFailure (surfaces the real create failure, incl. the unrecognized-carbon-zone case).
  3. Step 5 — Install the client via Helm, routed by provisioning mode:
    • minted — fresh credential, no prompts, no re-verify.
    • adopted — re-run on a registered cluster: reuses the previous values-file password and heals a stale clientId to the adopted UUID (cli#125-era numeric ids can't authenticate); honest terminal error if the local values file is gone.
    • presetTRACEBLOC_CLIENT_ID/TRACEBLOC_CLIENT_PASSWORD env pair (unattended/automation), verified once non-interactively.
    • fallback — the old interactive prompts, now reachable ONLY when the CLI is missing or too old (login/client create --help probe, mirroring _cli_supports_provisioning).

Get-InstalledClientInfo factors the one-client enumeration (#200 fail-closed semantics preserved) so the Step-4 pre-flight and the Helm-step guard share one source. Location is never prompted; TRACEBLOC_CLIENT_LOCATION still pins it (Windows has no zone.tab to auto-derive from, and the CLI/backend treat location as optional).

Acceptance (from #388)

  • Fresh install: browser sign-in is the only human step besides naming — no web-UI client creation, no secret prompts.
  • Re-run converges idempotently (client create adopts; the Helm step reconciles).
  • The CLI home screen shows the environment afterwards (client create writes the active-client pointer).
  • Env-var automation path works (and is now verified once before deploy).

Verification

  • Pester: 113 passed / 0 failed / 8 skipped (Windows-only skips) under pwsh 7.5.2 + Pester 5 locally — includes new Describes for the credential-file parser (first-= split, adopt variant), provisioning routing (preset/missing-CLI/too-old → mode), namespace-ownership matcher (prefix-safe), create-failure reporting, and minted/adopted/preset/fallback mode tests through Install-ClientHelm (adopted heals clientId; minted never prompts; preset fails closed on rejected creds).
  • scripts/check-style.sh clean; manifest.sha256 regenerated (R8).

Closes#388.

🤖 Generated with Claude Code


Note

Medium Risk
Large installer changes touch credential handling, Helm deploy paths, and one-client guards on the critical connect path; risk is mitigated by bash parity, fail-closed semantics, and broad new Pester tests.

Overview
Brings the Windows install-k8s.ps1 flow in line with scripts/lib/provision.sh (#388): CLI install moves to step 3, a new step 4 registers the machine via tracebloc login and tracebloc client create (credentials via --credential-file, never on the terminal), and Helm connect becomes step 5.

Provisioning adds helpers (Invoke-ProvisionClient, Get-InstalledClientInfo, credential parsing, input sanitization, namespace ownership checks) and routes Helm by TB_PROV_MODE: minted / adopted (surgical --reuse-values clientId heal, #397) / env preset / legacy fallback when the CLI is missing or too old. One-client-per-machine guards are shared between the pre-mint check and the Helm step. The user-facing roadmap and main execution order are updated accordingly; manifest.sha256 is refreshed.

Tests add Pester coverage for provisioning parsers, routing, and Install-ClientHelm behavior across minted, adopted, preset, and guard paths.

Reviewed by Cursor Bugbot for commit ac5c293. Bugbot is set up for automated code reviews on this repo. Configure here.

…before Helm (#388)
Port the bash provisioning sequence (scripts/lib/provision.sh) to
install-k8s.ps1, ending the legacy hand-copied Client-ID/password flow:
- Step reorder: 3 = install the tracebloc CLI (was 5), 4 = register this
machine, 5 = install the client via Helm. Roadmap updated.
- Invoke-ProvisionClient (Step 4): browser sign-in (tracebloc login,
device flow, attached to the console) + tracebloc client create --yes
--credential-file — the credential never reaches the terminal; the file
is parsed (KEY=value, first-'=' split) and deleted immediately. The
minted slug becomes the namespace (bash Q2 parity). Includes the
one-client-per-machine pre-flight (fail-closed on inconclusive reads;
legacy 'tracebloc'-namespace deferral) and Print-CreateFailure (real
failure reason incl. the carbon-zone special case).
- Adopted re-runs reconcile in place: reuse the previous values password,
heal a stale clientId to the adopted UUID; honest terminal error when
the local values file is gone.
- TRACEBLOC_CLIENT_ID/PASSWORD env pair stays as the unattended path
(verified once, non-interactively). The old interactive prompts survive
ONLY as the fallback for a missing/too-old CLI.
- Get-InstalledClientInfo factors the one-client enumeration (#200
fail-closed semantics) so the pre-flight and the Helm guard share one
source. CLI-install failure copy no longer claims the client is set up.
Closes#388.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Comment threadscripts/install-k8s.ps1
Comment threadscripts/install-k8s.ps1
…tize the name (Bugbot r1)
- The one-client guard now lets ADOPTED mode through on an id mismatch —
that mismatch IS the heal the mode exists for (helm still stores the
cli#125-era numeric dashboard id while the backend anchored this
cluster to the adopted UUID). Every other mode still refuses. The
adopted Pester test now drives the realistic stale-id scenario, plus a
negative test proving the guard is intact outside adopted mode.
- ConvertTo-SanitizedInput strips CSI sequences, bracketed-paste markers,
and control chars from the Step-4 name prompt (port of common.sh
_strip_paste_garbage; customer-reported on the bash flow 2026-07-20).
Pester: 118 passed / 0 failed / 8 skipped (Windows-only).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Comment threadscripts/install-k8s.ps1
Comment threadscripts/install-k8s.ps1 Outdated
Comment threadscripts/install-k8s.ps1 Outdated
…al-safe credential file (Bugbot r2)
- Minted credentials now verify via api-token-auth like every other mode
(never skip verification by provisioning method): backend skew or a
mid-flow deactivated account fails at install, not as a crash-looping
pod. Unreachable backend stays warn-and-continue.
- Adopted mode with a LIVE release reconciles surgically: helm upgrade of
THAT release, in ITS namespace, with --reuse-values --set-string
clientId=<uuid> — preserving the deployed configuration and secret
(bash parity) instead of regenerating values.yaml with fresh defaults.
Needs no local password at all; the local values file gets only its
clientId line healed. A rebuilt cluster (adopted anchor, no release)
keeps the full values write and its honest no-password error.
Wait-ForClientReady now watches the live release's namespace.
- The credential file is removed in a try/finally spanning mint->parse,
so Ctrl-C / terminating errors / Err exits can't leave the secret on
disk (ps1 analogue of _PROVISION_CRED_FILE + install_cleanup).
Pester: 119 passed / 0 failed / 8 skipped (Windows-only).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@LukasWodka

Copy link
Copy Markdown
ContributorAuthor

@cursor review

@cursorcursorBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit ac5c293. Configure here.

@LukasWodkaLukasWodka self-assigned this Jul 25, 2026
@saadqbal
saadqbal merged commit 35c400c into developJul 27, 2026
32 checks passed
LukasWodka added a commit that referenced this pull request Jul 27, 2026
Resolves#400 (curl_secure) + #397 conflicts:
- install_helm keeps #396's verified direct get.helm.sh download; drops develop's get-helm-3 hunk (that is what #396 removes).
- Adopts #400's curl_secure() wrapper on #396's new curl calls (_fetch_helm_release + latest-version lookup); no per-call-site $CURL_SECURE remains.
- Regenerated manifest.sha256 (idempotent) + copy-catalog golden.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@LukasWodka
LukasWodka deleted the feat/win-provisioning-parity branch August 14, 2026 13:53
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@shujaatTracebloc