Windows launcher only creates a differential disk; seed via Unattend.xml
run-windows11.py no longer installs Windows or touches ISO/img files: it creates a QCOW2 overlay on the base image (made by vm-images/build-windows-base.sh) and, when the disk is created, mounts seed.iso. Windows reads the Unattend.xml in its root during the specialize and OOBE passes (host name, account, auto logon, Remote Desktop) and Configure-Windows.ps1 then installs OpenSSH with the host's key, turns off Windows Update and copies the installer scripts. The VM hardware uses devices with inbox Windows drivers (IDE/NVMe, e1000e, ramfb on arm64), since the base image has no VirtIO drivers. Autounattend.xml moves to vm-images; the vm-images pointer is updated. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
fe7250870e
commit
a920ba0ca5
11 files changed
+456
-735
No files matched your search
@@ -48,8 +48,7 @@ corresponding `*_STATE_DIR` environment variable:
|
||||
|
||||
With `--download-only`, a launcher only downloads the media it would fetch
|
||||
automatically and then exits without creating a VM disk or starting QEMU: the
|
||||
base image for Debian, AlmaLinux, Fedora and Ubuntu, and the VirtIO tools ISO
|
||||
for Windows 11 (whose installation ISO and base QCOW2 are supplied manually):
|
||||
base image for Debian, AlmaLinux, Fedora and Ubuntu:
|
||||
|
||||
```bash
|
||||
./run-fedora44.py --download-only
|
||||
@@ -165,43 +164,49 @@ from the shared Windows 11 QCOW2 base image:
|
||||
./run-windows11.py
|
||||
```
|
||||
|
||||
It creates a persistent 64G disk at `vm/windows11/disk.qcow2`, automatically
|
||||
partitions it, completes OOBE, creates the local administrator `guofang` with
|
||||
the initial password `wang`, and enables Remote Desktop on
|
||||
`0.0.0.0:3389` (all host interfaces; connect to `localhost:3389` on the host itself). During the first login it also silently installs the VirtIO
|
||||
drivers (the guest tools installer on amd64, the Arm64 driver packages from the
|
||||
VirtIO ISO with `pnputil` on arm64), without which the guest has no network on
|
||||
arm64. The installer includes the VirtIO drivers, SPICE vdagent, and QEMU Guest
|
||||
Agent. The launcher exposes the vdagent channel for host/guest clipboard
|
||||
integration and the QEMU Guest Agent at `vm/windows11/qemu-guest-agent.sock`.
|
||||
Change the password after first login. The OpenSSH Server is installed during
|
||||
the first logon from the Win32-OpenSSH zip for the host architecture, which the
|
||||
seed ISO carries (downloaded by `vm-images/download-images.sh openssh-win`), so
|
||||
Windows Update is not needed. Connect with `ssh guofang@localhost -p 2222`; the
|
||||
seed ISO also carries the host's SSH public key (`$SSH_PUBLIC_KEY_FILE`, else the
|
||||
first of `~/.ssh/id_ed25519.pub`, `id_ecdsa.pub`, `id_rsa.pub`) for passwordless
|
||||
administrator login.
|
||||
It creates a persistent 64G disk at `vm/windows11/disk.qcow2` as a QCOW2
|
||||
overlay on the base image and nothing else: the launcher only creates the
|
||||
differential disk and starts QEMU. The base image is generic and holds nothing
|
||||
but Windows (see `vm-images/README.md`): no account, no SSH, no VirtIO or other
|
||||
hardware-specific drivers, no machine identity. Like a cloud image, each VM is
|
||||
configured on its first boot, from the seed ISO.
|
||||
|
||||
Whenever the disk does not exist yet, the launcher also mounts the seed ISO
|
||||
`vm/windows11/seed.iso` (beside the disk; built from `seediso/windows11/` when
|
||||
missing or outdated, with the OpenSSH zip and the host's SSH public key,
|
||||
`$SSH_PUBLIC_KEY_FILE` or the first of `~/.ssh/id_ed25519.pub`, `id_ecdsa.pub`,
|
||||
`id_rsa.pub`). Windows reads the `Unattend.xml` in the root of that CD-ROM
|
||||
during its specialize and OOBE passes: host name `WIN11`, time zone, Remote
|
||||
Desktop on `0.0.0.0:3389` (all host interfaces; connect to `localhost:3389` on
|
||||
the host itself), the local administrator `guofang` (initial password `wang`;
|
||||
change it after first login) and automatic logon. At the first logon it runs
|
||||
`Configure-Windows.ps1` from the seed ISO, which installs the OpenSSH Server
|
||||
from the zip with the SSH key (connect with `ssh guofang@localhost -p 2222`),
|
||||
turns off Windows Update and copies the numbered installer scripts
|
||||
(`seediso/windows11/NN-*.bat` and `.ps1`) to the desktop folder `Tools`. Later
|
||||
starts do not mount the seed ISO.
|
||||
|
||||
Because the image has no VirtIO drivers, the VM only uses devices that Windows
|
||||
has inbox drivers for: an IDE disk and e1000e NIC on amd64, an NVMe disk, e1000e
|
||||
NIC and ramfb display on arm64 (a fixed-size framebuffer there). The SPICE
|
||||
vdagent and QEMU Guest Agent come with the VirtIO guest tools, so host/guest
|
||||
clipboard integration and the guest agent are not available unless you install
|
||||
those tools in the VM yourself.
|
||||
The Windows VM hardware (8G memory, 8 CPUs, system disk, devices)
|
||||
is defined in `qemu/windows11/config.ini`, with the accelerators and machine type in
|
||||
`qemu/windows11/<os>-<arch>.ini`; the launcher renders the former to
|
||||
`vm/windows11/qemu.ini` and loads both with `-readconfig`. Only the network
|
||||
(see Port forwards) and the installation media are still set by the launcher. QEMU arguments after
|
||||
(see Port forwards) and the seed ISO are still set by the launcher. QEMU arguments after
|
||||
`--` override the config files, for example `./run-windows11.py -- -m 4G -smp 4`.
|
||||
The generated answer-file ISO is stored beside the disk as
|
||||
`vm/windows11/seed.iso`.
|
||||
|
||||
To install from the Windows ISO instead, use `./run-windows11.py
|
||||
--install-from-iso`. This choice only applies while creating a missing system
|
||||
disk; subsequent starts always boot the existing system disk normally. During
|
||||
ISO installation, the launcher resolves its tools ISO through the shared image
|
||||
helper and downloads it when missing. Override the base QCOW2, source ISO,
|
||||
tools ISO, RDP port, or SSH port with the `WIN11_VM_` environment
|
||||
variables shown by `./run-windows11.py --help`. For example, when the VirtIO ISO
|
||||
is elsewhere:
|
||||
|
||||
```bash
|
||||
WIN11_VM_TOOLS_ISO=/custom/path/virtio-win.iso ./run-windows11.py --install-from-iso
|
||||
```
|
||||
The launcher has no installation options and stops with a hint if the base image
|
||||
is missing. Make the base image once with `vm-images/build-windows-base.sh`,
|
||||
which is self-contained in `vm-images/` (its own answer file, QEMU config and
|
||||
installation logic, written in bash): it installs Windows unattended from the
|
||||
ISO into a scratch disk, runs `sysprep` as its last step and stores the disk as
|
||||
the read-only base image. Override the base QCOW2, seed ISO, RDP port, or SSH
|
||||
port with the `WIN11_VM_` environment variables shown by
|
||||
`./run-windows11.py --help`.
|
||||
|
||||
## Port forwards
|
||||
|
||||
|
||||
Reference in new issue
Block a user