Skip to content

H1: UpgradeEligibilityReason + cold-cache short-circuit + OS-aware messages

Summary

H1 of the 1.8.0 Upgrade Hardening initiative (8 PRs total, sequential H1-H8).

Fixes the operator-facing 1.7.x bug where clicking Upgrade on a Windows tentacle without a recent health check showed "Docker Hub unreachable, set SQUID_TARGET_LINUX_TENTACLE_VERSION" — sending Windows operators down the wrong remediation path.

Behaviour changes

Scenario Pre-H1 Post-H1
Cold cache + TentaclePolling LinuxStrategy historical-default → Docker Hub queried → misleading Linux env-var hint Short-circuit before strategy resolution → NoOsDetected reason code + message pointing to health-check endpoint
Windows machine + registry empty "Docker Hub unreachable, set SQUID_TARGET_LINUX_TENTACLE_VERSION" "github.com unreachable, set SQUID_TARGET_WINDOWS_TENTACLE_VERSION"
Linux machine + registry empty Same as before Same as before (preserved)
Cold cache + Ssh "Ssh not supported" "Ssh not supported" (preserved — non-tentacle styles bypass H1)
API response shape {canUpgrade, currentVersion, latestAvailableVersion, reason} Adds reasonCode field (additive, backward-compat)

API additions

  • New enum UpgradeEligibilityReason (9 codes, ordinals + name strings pinned by integrity tests per Rule 8)
  • New ReasonCode field on GetUpgradeInfoResponseData
  • FE can branch on reasonCode === "NoOsDetected" to render a "Run Health Check" deep-link button

Test plan

  • +9 integrity-test rows pinning every enum name + ordinal
  • +5 new GetUpgradeInfoAsync scenario tests covering the H1 behaviour changes
  • +1 drift detector pinning long-form Windows OS still routes correctly (regression guard for PR #351)
  • Updated 6 existing tests that relied on the cold-cache Linux historical default
  • 5540/5540 unit tests green (vs 5517 before H1 → +23 net new tests)
  • Integration / E2E coverage: deferred to H8 (comprehensive E2E matrix)

Backward compatibility

  • API response shape: additive (existing clients reading only reason are unaffected)
  • Enum stability: values + names pinned via UpgradeEligibilityReasonIntegrityTests — re-ordering or renaming is now a test-time-visible decision
  • Cold-cache + tentacle style behaviour: intentional break — old behaviour (allow optimistic upgrade) was the root cause of the operator's 1.7.x failure chain. New behaviour rejects with actionable guidance. Operators who were depending on the old behaviour will see canUpgrade=false with reasonCode=NoOsDetected — they should run a health check first

What's NOT in this PR (later phases)

  • H2: Capability cache persistence to DB (so server pod restart doesn't wipe cache)
  • H3: Active health-check probe API (currently the UI button doesn't actively probe agent)
  • H4: Upgrade lock TTL + idempotency
  • H5: Cross-OS unified upgrade pipeline
  • H6: Agent rollback + abandonment recovery
  • H7: Role/feature capability slots
  • H8: Comprehensive E2E test matrix

Merge request reports

Loading