Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 25 additions & 5 deletions .github/workflows/go-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,20 @@ jobs:
sudo rm -rf /usr/local/lib/android /usr/share/dotnet /opt/ghc
sudo apt-get update
sudo apt-get install -y --no-install-recommends qemu-system-x86 qemu-utils ovmf python3-venv unzip zstd
sudo chmod a+rw /dev/kvm
- name: Resolve Windows image revision
id: windows_image_revision
run: |
revision=$(git ls-remote https://github.com/starcatmeow/nylon-ci-windows-image.git refs/heads/main | cut -f1)
echo "revision=$revision" >> "$GITHUB_OUTPUT"
- name: Restore Windows image
id: windows_image_cache
uses: actions/cache/restore@v4
with:
path: ${{ runner.temp }}/windows.qcow2.zst
key: windows-image-zstd-${{ runner.os }}-${{ runner.arch }}-${{ steps.windows_image_revision.outputs.revision }}
- uses: cachix/install-nix-action@v31
if: steps.windows_image_cache.outputs.cache-hit != 'true'
with:
extra_nix_config: |
extra-substituters = https://pub-b7e688bb852e422d84f49c2dce8e3461.r2.dev
Expand All @@ -99,14 +112,21 @@ jobs:
download-attempts = 1
extra-system-features = kvm
- name: Build Windows image
id: windows_image
if: steps.windows_image_cache.outputs.cache-hit != 'true'
run: |
nix build github:starcatmeow/nylon-ci-windows-image/main#nylon-ci-win2025 \
nix build github:starcatmeow/nylon-ci-windows-image/${{ steps.windows_image_revision.outputs.revision }}#nylon-ci-win2025 \
--out-link "$RUNNER_TEMP/windows-image" --fallback
zstd -d "$RUNNER_TEMP/windows-image/nylon-ci-win2025.qcow2.zst" -o "$RUNNER_TEMP/windows.qcow2"
echo "qcow2=$RUNNER_TEMP/windows.qcow2" >> "$GITHUB_OUTPUT"
cp "$RUNNER_TEMP/windows-image/nylon-ci-win2025.qcow2.zst" "$RUNNER_TEMP/windows.qcow2.zst"
- name: Save Windows image
if: steps.windows_image_cache.outputs.cache-hit != 'true'
uses: actions/cache/save@v4
with:
path: ${{ runner.temp }}/windows.qcow2.zst
key: ${{ steps.windows_image_cache.outputs.cache-primary-key }}
- name: Decompress Windows image
run: zstd -d "$RUNNER_TEMP/windows.qcow2.zst" -o "$RUNNER_TEMP/windows.qcow2"
- name: Run Windows e2e
run: e2e/windows/run.sh '${{ steps.windows_image.outputs.qcow2 }}'
run: e2e/windows/run.sh "$RUNNER_TEMP/windows.qcow2"
- name: Upload Windows e2e logs
if: failure()
uses: actions/upload-artifact@v4
Expand Down
7 changes: 5 additions & 2 deletions e2e/windows/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,11 @@ replies in both directions between the Windows nodes, and between win1 and Linux
The Docker network and WinRM ports are fixed; run only one instance per host.
Logs stay in `workdir/e2e/windows`; VMs, overlays, TAPs and containers are removed.

CI builds `github:starcatmeow/nylon-ci-windows-image/main#nylon-ci-win2025`,
decompresses its output, and passes the qcow2 path to the same script.
CI caches the zstd-compressed qcow2 with GitHub Actions, keyed by the image
repository's main revision. A cache hit skips installing Nix and building the
image. On a miss, CI builds `#nylon-ci-win2025` at that exact revision of
`github:starcatmeow/nylon-ci-windows-image`. Both paths decompress the cached
output and pass the qcow2 path to the same script.
CI reads the public Nix cache at
`https://pub-b7e688bb852e422d84f49c2dce8e3461.r2.dev`, trusting the
`nylon-cache-1` public key configured in the workflow. Cache misses or download
Expand Down
11 changes: 9 additions & 2 deletions e2e/windows/connectivity.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,10 @@ def configure():
if process.poll() is not None:
self.fail(f"{name} QEMU exited; see {directory / 'qemu.log'}")
return powershell(port, f"""
# WinRM shells share profile handles; don't unload the hive while another still uses it.
$policy = 'HKLM:\\SOFTWARE\\Policies\\Microsoft\\Windows\\System'
New-Item -Path $policy -Force | Out-Null
New-ItemProperty -Path $policy -Name DisableForceUnload -PropertyType DWord -Value 1 -Force | Out-Null
$adapter = Get-NetAdapter | Where-Object {{ $_.MacAddress -eq '52-54-00-00-00-0{index}' }}
Set-NetIPInterface -InterfaceIndex $adapter.ifIndex -AddressFamily IPv4 -Dhcp Disabled
Get-NetIPAddress -InterfaceIndex $adapter.ifIndex -AddressFamily IPv4 -ErrorAction SilentlyContinue | Remove-NetIPAddress -Confirm:$false
Expand Down Expand Up @@ -146,12 +150,15 @@ def test_connectivity(self):
# SYSTEM provides UAPI privileges and the scheduled task survives closing WinRM.
$action = New-ScheduledTaskAction -Execute 'C:\\nylon-e2e\\nylon.exe' -WorkingDirectory 'C:\\nylon-e2e' -Argument 'run -v -w --config central.json --node {name}.json'
$principal = New-ScheduledTaskPrincipal -UserId 'SYSTEM' -LogonType ServiceAccount -RunLevel Highest
Register-ScheduledTask -TaskName 'nylon-e2e' -Action $action -Principal $principal | Out-Null
# Task Scheduler defaults to background priority; Nylon must keep up with probes.
$settings = New-ScheduledTaskSettingsSet -Priority 4
Register-ScheduledTask -TaskName 'nylon-e2e' -Action $action -Principal $principal -Settings $settings | Out-Null
Start-ScheduledTask -TaskName 'nylon-e2e'
""")

def collect_logs():
(WORK / "linux.log").write_text(run("docker", "logs", LINUX))
logs = subprocess.run(["docker", "logs", LINUX], check=True, capture_output=True, text=True)
(WORK / "linux.log").write_text(logs.stdout + logs.stderr)
for name, port in ports.items():
try:
(WORK / name / "nylon.log").write_text(powershell(port,
Expand Down
Loading