nzbhydra2/WINDOWS-VM-BUILD-SETUP.md
TheOtherP 285adaaadf
Some checks failed
system-test / waitForNative (push) Has been cancelled
system-test / buildMockserver (push) Has been cancelled
system-test / runSystemTestsLinux (map[name:core port:5076]) (push) Has been cancelled
system-test / runSystemTestsLinux (map[name:v1Migration port:5077]) (push) Has been cancelled
system-test / runSystemTestsWindows (push) Has been cancelled
Convert build script to python
2026-01-17 21:24:49 +01:00

6.0 KiB

Windows VM Setup for GraalVM Native Builds

This document describes how to set up a headless Windows VM on Linux for building Windows native executables using GraalVM.

Why This Is Needed

GraalVM native-image doesn't support cross-compilation. To build Windows executables from Linux, you need a Windows environment. A headless VM with SSH access provides CLI-controllable builds.

Prerequisites

Step 1: Install QEMU/KVM

Ubuntu/Debian

sudo apt install qemu-kvm libvirt-daemon-system virtinst virt-manager
sudo usermod -aG libvirt,kvm $USER
# Log out and back in for group changes

Fedora

sudo dnf install @virtualization
sudo systemctl enable --now libvirtd
sudo usermod -aG libvirt $USER

Arch

sudo pacman -S qemu-full libvirt virt-manager dnsmasq
sudo systemctl enable --now libvirtd
sudo usermod -aG libvirt $USER

Step 2: Create Windows VM

# Create directory for VMs
mkdir -p ~/vms

# Create disk image (60GB, grows dynamically)
qemu-img create -f qcow2 ~/vms/windows-build.qcow2 60G

# Start installation
virt-install \
  --name windows-build \
  --ram 8192 \
  --vcpus 4 \
  --disk path=~/vms/windows-build.qcow2,format=qcow2,bus=virtio \
  --cdrom /path/to/windows.iso \
  --disk path=/path/to/virtio-win.iso,device=cdrom \
  --os-variant win11 \
  --network network=default,model=virtio \
  --graphics spice

This opens a graphical installer. Complete the Windows installation.

During installation: Load VirtIO drivers from the second CD-ROM when Windows can't find the disk.

Step 3: Windows VM Configuration

After Windows is installed, perform these steps inside the VM:

Install VirtIO Drivers

  • Open Device Manager
  • Update any devices with missing drivers using the VirtIO CD-ROM

Install OpenSSH Server

Open PowerShell as Administrator:

# Install OpenSSH Server
Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0

# Start and enable the service
Start-Service sshd
Set-Service -Name sshd -StartupType Automatic

# Configure firewall (usually automatic)
New-NetFirewallRule -Name sshd -DisplayName 'OpenSSH Server' -Enabled True -Direction Inbound -Protocol TCP -Action Allow -LocalPort 22

Install Build Tools

  1. GraalVM Community Edition

  2. Visual Studio Build Tools

  3. Maven

  4. Git (optional, if syncing via git instead of rsync)

In Windows Network Settings, set a static IP like 192.168.122.100 to make SSH scripting easier.

Set Up SSH Key Authentication

From your Linux host:

ssh-copy-id builder@192.168.122.100

Step 4: VM Management Commands

# Start VM (headless)
virsh start windows-build

# Check running VMs
virsh list

# Get VM IP address
virsh domifaddr windows-build

# Shutdown gracefully
virsh shutdown windows-build

# Force stop
virsh destroy windows-build

# Create snapshot (recommended after setup)
virsh snapshot-create-as windows-build clean-setup "Fresh install with build tools"

# Restore snapshot
virsh snapshot-revert windows-build clean-setup

Step 5: Build Script

Create build-windows.sh in the project root:

#!/bin/bash
set -e

VM_NAME="windows-build"
WIN_USER="builder"
WIN_HOST="192.168.122.100"
PROJECT_DIR="$(cd "$(dirname "$0")" && pwd)"
BUILD_DIR="C:\\Users\\$WIN_USER\\nzbhydra2"

echo "=== Windows Native Build ==="

# Start VM if not running
if ! virsh list --name | grep -q "^${VM_NAME}$"; then
    echo "Starting Windows VM..."
    virsh start "$VM_NAME"
    echo "Waiting for VM to boot..."
    sleep 60
fi

# Wait for SSH to be available
echo "Waiting for SSH..."
until ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=no "$WIN_USER@$WIN_HOST" "echo ready" 2>/dev/null; do
    sleep 5
done
echo "SSH is ready"

# Sync source code
echo "Syncing source code..."
rsync -avz --delete \
    --exclude 'target/' \
    --exclude '.git/' \
    --exclude '.idea/' \
    --exclude '*.iml' \
    "$PROJECT_DIR/" \
    "$WIN_USER@$WIN_HOST:nzbhydra2/"

# Run build
echo "Running build..."
ssh "$WIN_USER@$WIN_HOST" "cd nzbhydra2 && cmd /c buildCore.cmd"

# Copy artifact back
echo "Copying artifact..."
mkdir -p "$PROJECT_DIR/core/target"
scp "$WIN_USER@$WIN_HOST:nzbhydra2/core/target/core.exe" \
    "$PROJECT_DIR/core/target/core-windows.exe"

echo "=== Build complete: core/target/core-windows.exe ==="

# Uncomment to shutdown VM after build:
# virsh shutdown "$VM_NAME"

Make it executable:

chmod +x build-windows.sh

Usage

# One command to build Windows executable
./build-windows.sh

Troubleshooting

VM won't start

# Check for errors
virsh start windows-build 2>&1

# Check libvirt logs
sudo journalctl -u libvirtd

Can't connect via SSH

# Check VM is running
virsh list

# Get IP address
virsh domifaddr windows-build

# Check if SSH port is open
nc -zv 192.168.122.100 22

Build fails

SSH into the VM and run the build manually to see full output:

ssh builder@192.168.122.100
cd nzbhydra2
cmd /c buildCore.cmd

Performance issues

  • Ensure KVM is enabled: lsmod | grep kvm
  • Increase RAM/CPU in VM settings
  • Use VirtIO drivers for disk and network

Notes

  • The Windows VM requires a valid Windows license
  • First boot after shutdown takes longer (Windows updates, etc.)
  • Consider keeping the VM running during development sessions
  • Snapshot the VM after successful setup to enable easy recovery