Fix and harden Windows tentacle upgrade download path#420
Merged
Conversation
Windows PowerShell 5.1's Invoke-WebRequest broke the self-upgrade two ways: - `-OutFile` corrupted the large binary download, so extraction failed with "End of central directory record could not be found" (exit 14). - For the .sha256 companion (served by GitHub as application/octet-stream), Invoke-WebRequest returns .Content as a byte[], so the hex split produced garbage, the 64-hex regex failed, and SHA verification was silently skipped — letting the corrupt download through unchecked. Switch both the upgrade and install scripts to System.Net.WebClient (DownloadFile / DownloadString) with forced TLS 1.2, and extract via [System.IO.Compression.ZipFile]::ExtractToDirectory instead of Expand-Archive. Make the whole upgrade script pure ASCII so PS 5.1 and the web log don't mojibake it under non-Latin OEM codepages, and log an ASCII snippet of any malformed SHA companion so operators can diagnose from the web log. Add cross-platform drift detectors pinning the WebClient/TLS12/ZipFile/ASCII shape and an octet-stream SHA regression test that reproduces the real cause, and reconcile stale test pins that were validating the old Invoke-WebRequest shape.
Raise upgrade success rate toward 100% by surviving the transient Windows failures that cause most field upgrade failures: - Retry the archive download with linear backoff (3 attempts, env-tunable via SQUID_UPGRADE_DOWNLOAD_RETRIES) so a single TCP reset / CDN 503 / proxy blip doesn't fail the whole upgrade. - Route the download through the machine's configured proxy with default credentials so authenticated corporate proxies (407) don't block it. - Reject a 0-byte / truncated download with a clear message instead of an opaque "central directory" error at extraction time. - Retry extraction and the binary swap so Defender briefly locking a freshly-written file doesn't fail the upgrade. The same hardening is applied to install-tentacle.ps1. Add a behavioural E2E proving the download-retry recovers from a transient 503 (LocalReleaseMirror.FailNextArchiveRequests), cross-platform drift detectors pinning the retry / proxy / size measures, and a windows-2019 + windows-2022 matrix on the Windows E2E workflow to prove the upgrade across Windows versions.
The size floor (< 1024 bytes) rejected the install E2E fixtures' tiny test archives (~143 bytes), failing 11 Windows install tests. Validate the PK magic bytes (0x50 0x4B) instead: a valid zip of any size passes, and HTML error pages / truncated downloads are still rejected -- more robustly than a size floor, which would also miss large error pages. Also swap the E2E matrix off the retired windows-2019 runner label (which queues forever with no available runner) to windows-2025.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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 -OutFilecorrupted the large binary download on PS 5.1 → extraction failed. Switch toSystem.Net.WebClient.DownloadFile+ forced TLS 1.2..sha256companion (served by GitHub asapplication/octet-stream) was fetched withInvoke-WebRequest, which returns.Contentas abyte[]for octet-stream → the hex split failed → SHA verification was silently skipped, letting the corrupt download through. Switch toWebClient.DownloadString(always a string) + log an ASCII snippet of any malformed companion.[System.IO.Compression.ZipFile]::ExtractToDirectoryinstead ofExpand-Archive.Reliability hardening (raise success rate toward 100%):
SQUID_UPGRADE_DOWNLOAD_RETRIES) — survives transient TCP reset / CDN 503 / proxy blips.Same fix + hardening applied to
install-tentacle.ps1.Test plan
Invoke-WebRequestcodeLocalReleaseMirror.FailNextArchiveRequests(1)injects a 503; the real.ps1retries and the upgrade still succeeds.ps1end-to-end — WebClient download → SHA → ZipFile extract → swap → restart →last-upgrade.json