Skip to content

feat(installer): preflight probes every download host, cross-OS + hard (#416) - #450

Merged
shujaatTracebloc merged 8 commits into
developfrom
feat/416-preflight-probe-hosts
Jul 28, 2026
Merged

feat(installer): preflight probes every download host, cross-OS + hard (#416)#450
shujaatTracebloc merged 8 commits into
developfrom
feat/416-preflight-probe-hosts

Conversation

@shujaatTracebloc

@shujaatTracebloc shujaatTracebloc commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Closes #416.

Problem

Preflight proved connectivity to registries + tracebloc endpoints, then Step 1 downloaded from hosts it never probed (desktop.docker.com, dl.k8s.io, get.helm.sh, github.com/objects.githubusercontent.com, auth.docker.io). On TLS-intercepting / allowlist networks the install passed an all-green preflight, then died ~30s later — misleading the IT contact who just watched it pass. Lukas's cross-OS audit widened this from "a few Windows hosts" to a cross-OS preflight gap.

Fix (both halves, in lockstep)

Probe every download host the default path fetches from, per-OS and HARD (a blocked one is now a named red preflight line, not a warn) — but only when the fetch will actually happen (tool/app absent; a present tool is never re-downloaded, so its host isn't probed).

Scope Hosts added
always auth.docker.io (Docker Hub token host)
Linux get.docker.com, download.docker.com, github.com + objects.githubusercontent.com, dl.k8s.io, get.helm.sh
macOS raw.githubusercontent.com (Homebrew), desktop.docker.com
Windows desktop.docker.com, dl.k8s.io, get.helm.sh, github.com + objects.githubusercontent.com
  • objects.githubusercontent.com is probed explicitly: release assets 302 there and _pf_probe_url can't follow redirects, so github.com passing proved nothing about the asset host.
  • GPU hosts deliberately excluded — GPU setup is optional and fix(installer): GPU container toolkit setup inside WSL times out silently #415 handles its failure with runnable remedies; hard-failing preflight would contradict that.
  • New check-drift.sh parity check (_drift_preflight_hosts) locks the shared-core host set so preflight.sh and install-k8s.ps1 can't drift apart.

Acceptance criteria

  • Any blocked download host = a named red preflight line before anything is installed or modified
  • bash + ps1 preflight host lists covered by the drift check

Tests

+5 bats (preflight.bats), +2 bats (check-drift.bats), +7 Pester (install-k8s.Tests.ps1).

One existing test updated: the single warn-only assertion in preflight.bats is updated to the new hard behaviour (the acceptance criterion requires red/hard). It's the only existing test touched — everything else is additive.

Verified locally (CI-identical):

  • Pester full: 182 passed, 0 failed, 8 skipped (Windows-only)
  • preflight.bats + check-drift.bats: 74 passed, 0 failed
  • all bats: 3 failures are pre-existing macOS-local flakes (confirmed on clean develop); ubuntu CI is the arbiter
  • PSScriptAnalyzer: 0 Error-severity · check-style / drift: clean · manifest regenerated

Note

Low Risk
Changes are limited to installer preflight/drift checks and tests; no runtime cluster, auth, or data-path behavior.

Overview
Fixes the gap where preflight could pass on corporate/allowlist networks, then the install failed ~30s later on hosts that were never probed (#416).

Connectivity: Adds auth.docker.io as a hard critical probe on Windows (install-k8s.ps1) and Unix (preflight.sh). Promotes tool-download hosts from warn-only to hard failures when that tool is missing—e.g. dl.k8s.io, get.helm.sh, github.com, objects.githubusercontent.com, and on Windows desktop.docker.com when Docker Desktop isn’t installed. Probes run only when a fetch will happen (installed tools aren’t re-checked). Linux keeps Docker-engine install URLs (get.docker.com / download.docker.com) soft (warn) because the path varies by distro; macOS branches on _pf_has_gui_session (Docker Desktop vs Colima/brew) so blocked hosts on unused paths don’t abort installs.

Parity & tests: New check-drift.sh Check 4 (_drift_preflight_hosts) compares probe URLs between preflight.sh and install-k8s.ps1 (not comment/hint greps). manifest.sha256 updated for changed scripts. Expanded bats (preflight.bats, check-drift.bats) and Pester (install-k8s.Tests.ps1) cover hard fails, macOS GUI/headless branches, and drift edge cases.

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

#416)

Preflight proved connectivity to registries + tracebloc endpoints, then Step 1
downloaded from hosts it never probed — so an all-green preflight was followed
~30s later by a blocked-download failure on TLS-intercepting / allowlist
networks, misleading the IT contact who just watched preflight pass.

- Probe every download host the default path fetches from, per-OS and HARD
  (a blocked one is now a named red preflight line, not a warn), but only when
  the fetch will actually happen (tool/app absent — a present tool is never
  re-downloaded, so its host isn't probed).
  * always: auth.docker.io (Docker Hub token host — allowed registry-1 but
    blocked token host used to fail only at in-cluster pull time)
  * Linux: get.docker.com, download.docker.com, github.com +
    objects.githubusercontent.com, dl.k8s.io, get.helm.sh
  * macOS: raw.githubusercontent.com (Homebrew), desktop.docker.com
  * Windows: desktop.docker.com, dl.k8s.io, get.helm.sh, github.com +
    objects.githubusercontent.com
- objects.githubusercontent.com is probed explicitly: release assets 302 there
  and _pf_probe_url does not follow redirects, so github.com passing proved
  nothing about the asset host.
- GPU hosts are deliberately excluded (GPU setup is optional; #415 handles its
  failure with runnable remedies — hard-failing preflight would contradict that).
- New check-drift.sh parity check (_drift_preflight_hosts) locks the shared-core
  host set so the two installers can't drift apart.

Fixes both halves in lockstep (preflight.sh + install-k8s.ps1). Tests: +5 bats
(preflight), +2 bats (drift), +7 Pester; the one existing warn-only assertion
(preflight.bats) is updated to the new hard behaviour.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@shujaatTracebloc shujaatTracebloc self-assigned this Jul 28, 2026
@shujaatTracebloc
shujaatTracebloc marked this pull request as draft July 28, 2026 12:15
Comment thread scripts/lib/preflight.sh Outdated
Comment thread scripts/lib/preflight.sh
Comment thread scripts/lib/preflight.sh Outdated
…es all hosts (Bugbot #416)

Bugbot found the download-host hard-probing over-generalized which host each path
fetches Docker from, so a blocked but UNUSED host could abort a supported install:
- macOS: desktop.docker.com hard-failed headless Macs that use Colima via brew.
- Linux: get.docker.com / download.docker.com both hard, but pacman/zypper/Amazon
  use distro repos and RHEL clones use only download.docker.com.

The Docker-engine install host is path/distro/environment-dependent, so it's now
WARN-only (soft bucket) on Linux + macOS. The k8s tool binaries (dl.k8s.io,
get.helm.sh, github.com + objects.githubusercontent.com) stay HARD — they're
always direct-downloaded from the same host. Windows is unchanged: Docker Desktop
is its sole path, so install-k8s.ps1 keeps desktop.docker.com hard.

Also (Bugbot medium): the egress hint listed only the old always-critical hosts;
it now names the tool-download hosts too, so a red line for a blocked download
host has matching remediation. Mirrored in preflight.sh + install-k8s.ps1.

Updated the two #416 bats tests that asserted the old hard behavior to assert
warn-only for the Docker-engine host.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@shujaatTracebloc
shujaatTracebloc marked this pull request as ready for review July 28, 2026 13:56
…-probe-hosts

# Conflicts:
#	scripts/manifest.sha256
#	scripts/tests/install-k8s.Tests.ps1
Comment thread scripts/lib/preflight.sh Outdated
…Bugbot #416)

install_homebrew fetches the install script from raw.githubusercontent.com and
then git-clones Homebrew/brew + core from github.com. Preflight probed only the
raw host, so a network that allows it but blocks github.com passed preflight then
failed during Homebrew setup — the same multi-host gap already closed for k3d via
objects.githubusercontent.com. Probe github.com too on macOS when brew is absent.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

@saadqbal saadqbal left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Careful PR — the conditional/hard-vs-soft logic is right, and I traced the Linux + Windows fetch hosts against setup-linux.sh / install-k8s.ps1 and every hard-probed host matches what the installer actually pulls from. Two things worth a look before merge (inline): the drift check doesn't actually catch a removed probe, and macOS misses formulae.brew.sh. Neither blocks the core fix.

Comment thread scripts/tests/check-drift.sh Outdated
Comment thread scripts/lib/preflight.sh Outdated
…Ls (review #416)

Two reviewer findings (saadqbal):

1. formulae.brew.sh unprobed on macOS: `brew install` pulls formula METADATA from
   formulae.brew.sh (bottles come from ghcr.io, already probed), and it's hit even
   when brew is already installed. A blocked metadata host = green preflight then a
   failed `brew install`. Now hard-probed on macOS whenever a brew-installed tool
   (kubectl/k3d/helm/docker) is absent.

2. Drift check couldn't detect a deleted probe: it grepped the whole file, so each
   shared host also matched inside comments and the egress-hint strings — passing
   even if a real probe line were removed (the AC wasn't enforced; the bats cases
   only passed because the fixtures lacked that text). check-drift now extracts
   only the hosts in an actual PROBE URL (bash "…|https://host/…", ps1
   url = "https://host/…") and diffs those. tracebloc.github.io drops from the
   shared set (ps1 probes it via $TRACEBLOC_HELM_REPO_URL, not a literal; Check 1
   already pins the host map). Rewrote the drift bats fixtures to real probe
   entries + added a case proving a comment/hint-only host is still flagged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Comment thread scripts/tests/check-drift.sh Outdated
Comment thread scripts/lib/preflight.sh
…ger (Bugbot #416)

Two Bugbot findings, both refining the earlier reviewer fixes (not reverting them):

- Drift check (ps1 side) matched ANY `url = "https://…"`, including the winget
  bootstrap download line, so deleting the real k3d github.com probe still passed.
  Scope the extractor to hashtable probe entries (require `label =` on the line),
  so only genuine preflight probes count. Added a bats case with a stray $url=
  download line + a deleted probe -> now correctly flags drift.
- formulae.brew.sh was hard-probed on `! has docker` too, but GUI Macs install
  Docker Desktop (desktop.docker.com), not brew — so docker-only-missing would
  hard-fail a host the install never uses. Trigger only on kubectl/k3d/helm (the
  tools that always install via brew). Added a bats case for docker-only-missing.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Comment thread scripts/lib/preflight.sh Outdated
…nstalls too (Bugbot #416)

Round-3 dropped docker from the formulae.brew.sh trigger to avoid a GUI-Mac
false-fail (Docker Desktop, not brew). But headless Macs install colima/docker
via `brew install`, which DOES hit formulae.brew.sh — so docker-only-missing on a
headless box went green in preflight then failed in Step 1. Make it path-aware:
add a _pf_has_gui_session helper (mirrors setup-macos.sh) and probe formulae.brew.sh
for a missing docker only when there's NO GUI session (the Colima/brew path). GUI
Macs still skip it (Docker Desktop). Added bats cases for both GUI and headless.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

@cursor cursor Bot 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.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 8912268. Configure here.

Comment thread scripts/lib/preflight.sh Outdated
…gbot #416)

Fold the r3/r4/r5 point-fixes into one GUI-aware block keyed on
_pf_has_gui_session, so each host is hard-probed only on the path that fetches it:
- kubectl/k3d/helm absent -> formulae.brew.sh (always brew).
- docker absent + GUI  -> desktop.docker.com HARD (the actual Docker Desktop path;
  was warn-only -> a blocked CDN passed preflight then failed mid-download, r5).
- docker absent + headless -> formulae.brew.sh (colima/docker via brew, r4).
desktop.docker.com leaves the warn bucket entirely (it's hard on GUI, unprobed on
headless). No behaviour is looser than before; the GUI Desktop CDN is now caught.
Tests refreshed: GUI vs headless for both desktop.docker.com and formulae.brew.sh.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@shujaatTracebloc
shujaatTracebloc merged commit 5948031 into develop Jul 28, 2026
30 of 31 checks passed
@shujaatTracebloc
shujaatTracebloc deleted the feat/416-preflight-probe-hosts branch July 28, 2026 15:28
Sign up for free to 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.

4 participants