Skip to content

Fix and harden Windows tentacle upgrade download path

Placeholder ppxd requested to merge fix-windows-tentacle-download-webclient into main

Summary

Make the Windows tentacle self-upgrade work, and work reliably across Windows versions and environments.

Correctness fix (the field report: upgrade to 1.8.13 failed with "End of central directory record could not be found", exit 14):

  • Invoke-WebRequest -OutFile corrupted the large binary download on PS 5.1 → extraction failed. Switch to System.Net.WebClient.DownloadFile + forced TLS 1.2.
  • The .sha256 companion (served by GitHub as application/octet-stream) was fetched with Invoke-WebRequest, which returns .Content as a byte[] for octet-stream → the hex split failed → SHA verification was silently skipped, letting the corrupt download through. Switch to WebClient.DownloadString (always a string) + log an ASCII snippet of any malformed companion.
  • Extract via [System.IO.Compression.ZipFile]::ExtractToDirectory instead of Expand-Archive.
  • Script is now pure ASCII so PS 5.1 + the web log don't mojibake under non-Latin OEM codepages.

Reliability hardening (raise success rate toward 100%):

  • Retry the download with backoff (3 attempts, env-tunable SQUID_UPGRADE_DOWNLOAD_RETRIES) — survives transient TCP reset / CDN 503 / proxy blips.
  • Route through the configured proxy with default credentials — authenticated corporate proxies (407) no longer block it.
  • Reject a 0-byte / truncated download with a clear message instead of an opaque extraction error.
  • Retry extraction + binary swap — Defender briefly locking a freshly-written file no longer fails the upgrade.

Same fix + hardening applied to install-tentacle.ps1.

Test plan

  • 705 upgrade unit tests + resource/strategy/parity drift detectors green (macOS)
  • Cross-platform drift detectors: WebClient+TLS12 download, ZipFile extraction, pure-ASCII script, retry/proxy/size hardening
  • Octet-stream SHA regression test — reproduces the real cause; fails the old Invoke-WebRequest code
  • Behavioural download-retry E2E — LocalReleaseMirror.FailNextArchiveRequests(1) injects a 503; the real .ps1 retries and the upgrade still succeeds
  • Windows E2E green on a real Windows runner (run 26962192825, 10m): production .ps1 end-to-end — WebClient download → SHA → ZipFile extract → swap → restart → last-upgrade.json
  • Windows E2E matrix (windows-2019 + windows-2022) — re-dispatched on this branch with the hardening + retry test
  • Manual confirmation on the reporting operator's box (already verified WebClient returns the byte-exact archive: size + SHA match)

Merge request reports

Loading