Uh oh!
There was an error while loading. Please reload this page.
fix(installer): WSL update survives Store-blocked networks + skips when current (#414) - #484
Conversation
…rrent The installer ran `wsl --update` through the Microsoft Store with a 90s silent- timeout job: on Store-blocked corporate networks it silently skipped (Docker Desktop then confronted the user with its own install-WSL prompt + reboot), it re-ran up to 90s on every re-run even when the kernel was current, and its output went only to the log. New Update-Wsl: - Skips when WSL is already current (Test-WslCurrent parses `wsl --version`), so the block finishes in <2s on a re-run. - Uses `wsl --update --web-download`, which fetches from Microsoft's servers instead of the Store, so a Store-blocked machine still updates the kernel with no Docker Desktop WSL prompt. Runs as a killable tracked process with a deadline. - On failure, surfaces the exact manual MSI step on screen (github.com/microsoft/ WSL/releases), not swallowed to the log. Scope note: the issue also suggested auto-falling-back to the GitHub-releases MSI. That isn't implemented automatically because it would require api.github.com (the WSL asset name carries a 4th version component the API-free /releases/latest redirect can't resolve), and #410 -- enforced by a test -- forbids the rate-limited GitHub API in this installer. The manual step is surfaced clearly instead; a test guards against a regression that re-adds the API. Tests: Test-WslCurrent parsing; source guards for --web-download, skip-when-current, no bare Store-path job, the manual step, and the #410 no-API invariant. Closes#414 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
LukasWodka
commented
Jul 30, 2026
👋 Heads-up — Code review queue is at 36 / 30 Above the WIP limit. The team convention is to review existing PRs before opening new work. Open PRs currently in Code review (oldest first):
Pull from review before opening new work. (This is a nudge from the kanban WIP check, not a block.) |
Uh oh!
There was an error while loading. Please reload this page.
LukasWodka
commented
Jul 30, 2026
👋 Heads-up — Code review queue is at 37 / 30 Above the WIP limit. The team convention is to review existing PRs before opening new work. Open PRs currently in Code review (oldest first):
Pull from review before opening new work. (This is a nudge from the kanban WIP check, not a block.) |
…(Bugbot) wsl.exe writes UTF-16LE; capturing it via 'cmd /c ... | Out-String' left the output null-interleaved, so Test-WslCurrent never matched -- skip-when-current never fired and every re-run attempted a full (up to 5 min) web update and could show a false MSI warning. Capture wsl --version with [Console]::OutputEncoding set to Unicode (the same pattern the wsl --list reader already uses), restored in a finally. Adds a source guard. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Uh oh!
There was an error while loading. Please reload this page.
The manual fallback hint hardcoded wsl.<version>.x64.msi, but Get-WindowsArch returns arm64 on ARM hosts and GitHub ships wsl.<version>.arm64.msi. An ARM operator following the x64 step installs the wrong package and still hits the Docker Desktop WSL prompt this path avoids. Compute the MSI arch from the host. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Uh oh!
There was an error while loading. Please reload this page.
… (Bugbot) Test-WslCurrent matched the English 'WSL version:' label, but wsl --version localizes it (e.g. Japanese 'WSL バージョン:'), so skip-when-current never fired on non-English Windows and every re-run attempted the full web update. Match the dotted version number instead, which modern WSL always prints regardless of locale. Adds a non-English test case. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…-store-fallback # Conflicts: # scripts/manifest.sha256
saadqbal
left a comment
There was a problem hiding this comment.
Good direction and the Bugbot rounds landed cleanly. One thing I'd want fixed before merge: Test-WslCurrent is a presence check, not a currency check, so the new skip path no-ops on exactly the stale machines #414 is about. Beyond that, the wsl --version read is now the only unbounded call in the file, and the failure path logs nothing. Comments inline.
One outside the diff: install-k8s.ps1:948 still tells the operator to run wsl --update manually — the Store command this PR just removed as broken. Worth updating in the same pass.
(Manifest hash matches, check-style clean.)
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
saadqbal
left a comment
There was a problem hiding this comment.
One more, missed it on the first pass.
Uh oh!
There was an error while loading. Please reload this page.
…, real errors
Reworked Update-Wsl to address Asad's review:
- Test-WslCurrent now grades a version FLOOR, not mere presence: it pulls the
first dotted version (the WSL version line, locale-independent) and requires
>= TB_WSL_MIN_VERSION (default 2.1.0), so a stale modern WSL (2.0.x) still
updates instead of being green-OK'd forever.
- The wsl --version probe is BOUNDED: Get-WslVersionOutput runs it in a job with
Wait-JobWithProgress -TimeoutSec 20 (like the wsl --list reader) and returns ""
on timeout, so a wedged LxssManager can't freeze Step 1. The encoding restore is
wrapped (finally { try {...} catch {} }) so it can't kill the installer on a
console-less host.
- Invoke-WslUpdate runs wsl --update as a tracked process with a deadline,
redirects stdout/stderr to temp files (logged), and classifies the outcome
(ok / not-found / timeout / failed) — so failures leave real WSL evidence in the
log + -Diagnose, and wsl's \r progress no longer fights the spinner.
- Two-rung ladder: on a non-zero web-download exit (unpatched wsl.exe rejects the
flag), retry plain `wsl --update` before giving up.
- Differentiated failure messages: not-found / timed out / exited N — no longer
the single "the Store may be blocked" line that --web-download rules out.
Tests: Update-Wsl is now EXECUTED (mocked deps) across skip / web-download / retry
/ timeout / not-found branches; Test-WslCurrent covers the stale-floor + custom-
floor cases; source guards anchored on the real invocations; dropped the duplicate
#410 guard (the #410 Describe owns that invariant).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 9d8132b. Configure here.
Uh oh!
There was an error while loading. Please reload this page.
… (Bugbot) The 2.1.0 floor let 2.1.0-2.1.4 boxes skip the update yet still hit Docker Desktop's update-WSL prompt (it requires >= 2.1.5). Default the floor to 2.1.5. Adds a 2.1.4 boundary test. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

What & why
The installer ran
wsl --updatethrough the Microsoft Store with a 90s silent-timeout job. On Store-blocked corporate networks it silently skipped — Docker Desktop then confronted the user with its own install-WSL dialog + reboot (the root of the "every user installs WSL themselves" experience). It also re-ran up to 90s on every run even when the kernel was current, and its output went only to the log.Changes (
scripts/install-k8s.ps1)New
Update-Wsl(replaces the inline Store-path job):Test-WslCurrentparseswsl --version; a re-run on an up-to-date machine finishes in <2s.wsl --update --web-download— fetches from Microsoft's servers instead of the Store, so a Store-blocked machine still updates the kernel with no Docker Desktop WSL prompt. Runs as a killable tracked process with a deadline.Acceptance (from #414)
wsl --versionbefore updatingwsl --update --web-download(bypasses the Store)--web-download)Scope note — automated GitHub-releases MSI fallback
The issue also suggested auto-falling-back to the WSL MSI from GitHub releases. That is not implemented automatically: resolving the WSL release asset URL needs
api.github.com(the asset name carries a 4th version component the API-free/releases/latestredirect can't resolve), and #410 — enforced by a test — forbids the rate-limited GitHub API in this installer. The manual MSI step is surfaced clearly instead, and a test guards against a regression that re-adds the API. Happy to wire an automated fallback if we decide to relax #410 for this rare path.Tests
Test-WslCurrentparsing (current / absent / legacy); source guards for--web-download, skip-when-current, removal of the bare Store-path job, the on-screen manual step, and the #410 no-API invariant.Local verification
Pester 264/0/8 · check-style pass · drift clean · manifest regenerated · PS parse OK. (No bash changes — bats unaffected.)
Closes#414
Note
Low Risk
Changes are confined to the Windows install script’s WSL step and tests; behavior is more defensive (timeouts, version floor) with no auth or cluster data impact.
Overview
Replaces the Windows installer’s inline 90s Store-only
wsl --updatejob with a dedicatedUpdate-Wslflow so corporate machines that block the Microsoft Store can still get a current WSL kernel before Docker Desktop runs.Skip when already current: A bounded
wsl --versionprobe (Get-WslVersionOutput, 20s job timeout) feedsTest-WslCurrent, which compares the first dotted version in the output to a 2.1.5 floor (Docker Desktop’s documented minimum; overridable viaTB_WSL_MIN_VERSION). Re-runs on an up-to-date box exit in under ~2s instead of waiting up to 90s every time.Update path:
Invoke-WslUpdaterunswsl --updateas a tracked process (5-minute deadline, stdout/stderr to temp files and the install log). The installer prefers--web-download(Microsoft CDN, not the Store), then retries plainwsl --updateonce if the first attempt fails with a real exit code (not timeout or missingwsl.exe).Failures on screen: Timeouts, missing
wsl.exe, and non-zero exits get distinct warnings plus an arch-matched manual MSI hint (x64/arm64fromGet-WindowsArch). Automated GitHub MSI download is intentionally not added (conflicts with #410’s no-GitHub-API rule).Pester coverage exercises version parsing,
Update-Wslbranching, and source guards;scripts/manifest.sha256is updated forinstall-k8s.ps1.Reviewed by Cursor Bugbot for commit 85cf456. Bugbot is set up for automated code reviews on this repo. Configure here.