* Mask console-getty.service to prevent multi-distro failures (#13595)
When multiple WSL distros run concurrently, /dev/tty devices are shared
at the VM level. The second distro's console-getty.service fails because
the tty is already held by the first, causing systemd to report failed
units and triggering user@UID.service failures.
Mask console-getty.service during WSL systemd unit generation, similar
to the existing masking of networkd-wait-online. This service provides
no value in WSL since users don't connect to the underlying tty.
Fixes#13595
* format source
* pr feedback
---------
Co-authored-by: Ben Hillis <benhill@ntdev.microsoft.com>
* Split x64/arm64 builds into parallel pipeline stages
Restructure the CI/CD pipeline to build x64 and arm64 in parallel
instead of sequentially, reducing end-to-end build time.
Pipeline shapes:
- PR: build_x64 ∥ build_arm64 → test (uses installer.msix directly)
- Nightly: build_x64 ∥ build_arm64 → package → test (dev-cert bundle)
- Release: build_x64 ∥ build_arm64 → package → test (ESRP-signed bundle)
Key changes:
- Extract shared build-job.yml template parameterized by platform
- Add package-stage.yml that creates msixbundle from both platform
artifacts, ESRP-signs for release, dev-cert signs for nightly
- PR tests run immediately after x64 build using installer.msix
(no package stage, no bundle needed)
- Release/nightly tests wait for the package stage and test the real
signed bundle that gets published
- CloudTest configs are parameterized: release tests pull the bundle
from the [package] artifact, PR tests use installer.msix from [drop]
- arm64 + formatting checks always run in parallel with x64 but don't
block the PR test gate
- CodeQL runs in the arm64 stage (off the critical path)
- flight-stage and nuget-stage updated for new stage names
* formatting
* Remove redundant runtime conditions on release-only tasks
These tasks are already wrapped in compile-time conditionals which
prevent them from being added to the pipeline definition for
non-release builds. The runtime condition checks can never evaluate
to false at that point, so they are pure noise.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Address review feedback from OneBlue
- Remove wslcsdk NuGet staging (wslc is not in master)
- Always include [package] provider in TestMap.xml.in instead of
conditionally injecting via PACKAGE_PROVIDER_BLOCK cmake variable.
PR builds simply use [drop] as TEST_PACKAGE_PROVIDER; the [package]
provider exists but is unused.
- Add BUNDLE_ONLY cmake option so the package pipeline stage reuses
cmake's existing bundle target instead of forking makeappx logic.
This locks the SDK version via cmake (CMAKE_SYSTEM_VERSION) and
keeps bundle creation logic in one place (msixinstaller/CMakeLists.txt).
The pipeline now copies msix files to expected paths, runs a fast
cmake configure with -DBUNDLE_ONLY=TRUE, and builds the bundle target.
- Remove dead NuGet binary restore step in package stage.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Address PR review feedback
- Fix PACKAGE_VERSION regex: escape dots so only A.B.C.D is accepted
- Consolidate CMake defaults (build type, config types, output dir)
before BUNDLE_ONLY block to avoid duplication
- Nightly tests now use the full bundle from the package stage instead
of installer.msix (new INCLUDE_PACKAGE_STAGE cmake variable)
- Package stage reuses version output from build stage instead of
recomputing it
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---------
Co-authored-by: Ben Hillis <benhill@ntdev.microsoft.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Replace pre-commit hook with CMake-generated clang-format check
Replace the old pre-commit hook that shelled out to PowerShell and
never blocked commits (-NoFail) with a CMake-generated hook that
calls clang-format directly on staged C/C++ files.
- Add tools/hooks/pre-commit.in as a CMake template
- CMake resolves the clang-format path at configure time via
LLVM_INSTALL_DIR, matching the existing FormatSource.ps1.in pattern
- Hook blocks commits on formatting errors, skips gracefully if
clang-format is not available (cmake not yet run)
- ~5x faster than the old PowerShell approach (~0.5s vs ~2.6s)
* Make pre-commit hook behavior configurable via WSL_PRE_COMMIT_MODE
Add WSL_PRE_COMMIT_MODE CMake cache variable with three modes:
- warn (default): report formatting issues without blocking commit
- error: block commit when formatting issues are found
- fix: auto-format files and re-stage them
Also addresses PR feedback:
- Generate hook into build tree, copy to source tree for out-of-source builds
- Use repo-local tools/clang-format.exe instead of LLVM_INSTALL_DIR path
- Use @ONLY in configure_file to avoid shell variable substitution issues
- Document modes in dev-loop.md and UserConfig.cmake.sample
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---------
Co-authored-by: Ben Hillis <benhill@ntdev.microsoft.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Add /attachdebugger option to automatically launch WinDbgX for test debugging
When /attachdebugger is passed to test.bat, run-tests.ps1 now:
- Starts te.exe with /waitfordebugger in the background
- Polls for the TE.ProcessHost.exe child process via WMI
- Launches WinDbgX attached directly to the test host PID
- With /inproc, attaches to TE.exe itself instead
This replaces the manual workflow of running /waitfordebugger, reading
the PID from the output, and launching WinDbgX separately.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* run-tests: use /inproc with /attachdebugger, simplify exit
Per review feedback from @OneBlue:
- Add /inproc when /attachdebugger is set so WinDbgX attaches
directly to TE.exe instead of polling for TE.ProcessHost.exe
- Simplify exit to pass through TE.exe exit code directly
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* docs: update /attachdebugger to reflect /inproc behavior
The script now always adds /inproc, so update the README to match:
WinDbgX attaches directly to TE.exe, no ProcessHost polling.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---------
Co-authored-by: Ben Hillis <benhill@ntdev.microsoft.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* build: add Source Link to embed GitHub source mappings in PDBs
* Gate Source Link on pipeline builds only
Only generate sourcelink.json and pass /SOURCELINK to the linker when
PIPELINE_BUILD_ID is defined (i.e. during CI pipeline builds). This
avoids unnecessary Source Link artifacts in local developer builds.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---------
Co-authored-by: Ben Hillis <benhill@ntdev.microsoft.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Fix UnicodeEncodeError in create-release.py on cp1252 consoles
Reconfigure stdout/stderr with errors='backslashreplace' so commit
messages containing characters outside the console code-page (e.g.
U+2225) are escaped instead of crashing the script. Also redirect the
'failed to extract PR number' warning to stderr for consistency.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Fix return type annotation for get_github_pr_message()
Update the return annotation from str to tuple[str | None, str | None]
to match the actual return values (pr_body, pr_number).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---------
Co-authored-by: Ben Hillis <benhill@ntdev.microsoft.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
When the WSL MSIX package is updated via the Microsoft Store, the
WslInstaller service automatically upgrades the MSI package by calling
MsiInstallProduct. This call was made with INSTALLUILEVEL_NONE (silent
install) but without setting the REBOOT=ReallySuppress property.
Per Windows Installer documentation, when a silent install encounters
files in use and REBOOT is not suppressed, the system reboots
automatically without any user prompt. This could cause unexpected
machine restarts after a Store update when WSL binaries (e.g.
wslservice.exe) were in use during the upgrade.
Every deployment script in the repo already passes /norestart to
msiexec (deploy-to-host.ps1, deploy-to-vm.ps1, install-latest-wsl.ps1,
test-setup.ps1), but the programmatic MsiInstallProduct path used by
the WslInstaller service lacked the equivalent property.
This change:
- Always appends REBOOT=ReallySuppress to MsiInstallProduct arguments
in UpgradeViaMsi, preventing Windows Installer from ever initiating
a system restart during install/upgrade.
- Switches UninstallViaMsi from MsiConfigureProduct to
MsiConfigureProductEx so we can pass REBOOT=ReallySuppress during
uninstall as well.
- Propagates ERROR_SUCCESS_REBOOT_REQUIRED (3010) to callers instead
of swallowing it. User-facing paths (wsl --update, wsl --uninstall)
print a reboot-needed message to stderr. The background WslInstaller
service silently treats 3010 as success since it has no console.
Co-authored-by: Ben Hillis <benhill@ntdev.microsoft.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Move inputs.comment, inputs.issue, and inputs.token into the env
block, consistent with how inputs.previous_body is already handled.
This avoids issues with special characters in input values being
misinterpreted during shell evaluation.
Co-authored-by: Ben Hillis <benhill@ntdev.microsoft.com>
* Update Microsoft.WSL.DeviceHost to version 1.1.48-0 (#14575)
Co-authored-by: Ben Hillis <benhill@ntdev.microsoft.com>
* Re-enable WSLG during testing.
This reverts commit bf759a092b.
* add back config change (will work with new default, but makes test explicit)
---------
Co-authored-by: Ben Hillis <benhill@ntdev.microsoft.com>
* Revert "test: enable virtiofs tests and enable WSLG during testing (#14387)"
* enable wslg for SystemdNoClearTmpUnit test
---------
Co-authored-by: Ben Hillis <benhill@ntdev.microsoft.com>
* test: Add arm64 test distro support
* update unit test baseline
* more test baseline updates
---------
Co-authored-by: Ben Hillis <benhill@ntdev.microsoft.com>
* detach terminal before running mount -a
* Potential fix for pull request finding
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* use _exit on error before execv in child process to avoid unintentional resource release
* Add regression test
* Fix clang format issue
* fix all clang format issue
* Potential fix for pull request finding
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* resolve ai comments
* move test to unit test
* Fix string literal
* Overwrite fstab to resolve pipeline missing file issue
---------
Co-authored-by: Feng Wang <wangfen@microsoft.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* Refactor: trim unnecessary DLL deps from COMMON_LINK_LIBRARIES
- Split MSI/Wintrust install functions from wslutil.cpp into install.cpp
- Remove MI.lib, wsldeps.lib, msi.lib, Wintrust.lib, computecore.lib,
computenetwork.lib, Iphlpapi.lib from COMMON_LINK_LIBRARIES
- Add per-target MSI_LINK_LIBRARIES, HCS_LINK_LIBRARIES, SERVICE_LINK_LIBRARIES
- Delay-load msi.dll and WINTRUST.dll for wsl.exe and wslg.exe
- Result: wslhost, wslrelay, wslcsdk, testplugin lose msi/wintrust startup imports;
wsl.exe and wslg.exe defer msi/wintrust loading until actually needed;
wslservice is the only target that imports computecore/computenetwork/Iphlpapi
* minor fixes to install.cpp that were caught during PR
* move to wsl::windows::common::install namespace
---------
Co-authored-by: Ben Hillis <benhill@ntdev.microsoft.com>
- Allow VirtioProxy to keep EnableDnsTunneling=true in config, but clear
socket-specific options (BestEffortDnsParsing, DnsTunnelingIpAddress)
- Suppress dedicated DNS tunneling hvsocket for VirtioProxy; tunneling
is handled through the VirtioNetworking device host instead
- Set DnsTunneling flag on VirtioNetworkingFlags so the device host
knows to tunnel DNS
- Expand SWIOTLB kernel cmdline to cover VirtioFs and VirtioProxy
- Bump DeviceHost package to 1.1.39-0
- Add VirtioProxy DNS test coverage for tunneling on/off
- Skip GuestPortIsReleasedV6 on Windows 10
Co-authored-by: Ben Hillis <benhill@ntdev.microsoft.com>
* Move all supported Ubuntu images to the new format
We backported the build pipeline so all current LTSes come out in the new tar-based format
* Remove the appx based distros
All WSL users can run tar-based distros by now, right?
There is no benefit in maintaining both formats.
There were instructions already on how to install tcpdump in WSL, but
iptables are also needed for the log collection to be complete, so this
PR adds instructions on how to also install iptables.
Co-authored-by: Andre Muezerie <andremue@linux.microsoft.com>
* Initial work
* .
* pr feedback and add unit test
* minor tweaks an fix use after free in logging statement
* implement PR feedback
* hopefully final pr feedback
* pr feedback in test function
* Address PR feedback: add try/catch to TrackPort and PortZeroBind queue push
---------
Co-authored-by: Ben Hillis <benhill@ntdev.microsoft.com>
* VirtioProxy: Add IPv6 address, gateway, and route support
- Add PreferredIpv6Address field and GetBestGatewayV6* methods to NetworkSettings
- Extend GetHostEndpointSettings() to discover IPv6 unicast address and gateway
- Add UpdateIpv6Address() using ModifyGuestEndpointSettingRequest<IPAddress>
- Push IPv6 default route to guest via UpdateDefaultRoute(AF_INET6)
- Remove AF_INET6 early return in ModifyOpenPorts, use INETADDR_PORT()
- Add EndpointRoute::DefaultRoute() static factory
- Pass client_ip_ipv6 in devicehost options (not yet parsed by devicehost)
- Remove gateway_ip from devicehost options (only needed for DHCP)
- Include IPv6 DNS servers in non-tunneling DNS settings
- Add ConfigurationV6 and DnsResolutionAAAA tests
* cleanup and add more ipv6 tests
* added test coverage and minor updates
* clang format
* pr feedback
* format source
* pr feedback
* test fixes
---------
Co-authored-by: Ben Hillis <benhill@ntdev.microsoft.com>
* virtiofs: update logic so querying virtiofs mount source does not require a call to the service
* more pr feedback
* use std::filesystem::read_symlink
* pr feedback and use canonical path in virtiofs symlink
* make sure canonical path is always used
---------
Co-authored-by: Ben Hillis <benhill@ntdev.microsoft.com>
* Ship initrd.img in MSI using build-time generation via tar.exe
Replace the install-time CreateInitrd/RemoveInitrd custom actions with a
build-time step that generates initrd.img using the Windows built-in
tar.exe (libarchive/bsdtar) and ships it directly in the MSI.
The install-time approach had a race condition: wsl.exe could launch
before the CreateInitrd custom action completed, causing
ERROR_FILE_NOT_FOUND for initrd.img.
Changes:
- Add CMake custom command to generate initrd.img via tar.exe --format=newc
- Add initrd.img as a regular file in the MSI tools component
- Remove CreateInitrd/RemoveInitrd custom actions from WiX, DllMain,
and wslinstall.def
- Remove CreateCpioInitrd helper and its tests (no longer needed)
- Update pipeline build targets to build initramfs instead of init
* pr feedback
* more pr feedback
* switch to using a powershell script instead of tar.exe
* powershell script feedback
* hopefully final pr feedback
---------
Co-authored-by: Ben Hillis <benhill@ntdev.microsoft.com>
Addresses Dependabot alerts #10 and #11. The Microsoft.NETCore.App.Runtime
packages (win-x64 and win-arm64) at version 10.0.0 are vulnerable to a
denial of service via out-of-bounds read when decoding malformed Base64Url
input (CVSS 7.5 High). Bumped to 10.0.4 which includes the fix.
Co-authored-by: Ben Hillis <benhill@ntdev.microsoft.com>
Use ResolveIpNetEntry2 to look up the host gateway's MAC address and
pass it as the gateway_mac device option to the virtio net adapter.
This allows the guest to see the real gateway MAC instead of the
default consomme address.
Co-authored-by: Ben Hillis <benhill@ntdev.microsoft.com>