The base image now carries the VirtIO drivers, which restores the 2304x1440 display that ramfb had lost. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
231 lines
9.5 KiB
Markdown
231 lines
9.5 KiB
Markdown
# cloudhost
|
|
|
|
Start the required operating system with its distribution-specific launcher:
|
|
|
|
```bash
|
|
./run-debian13.py
|
|
./run-almalinux10.py
|
|
./run-fedora44.py
|
|
./run-ubuntu2604.py
|
|
./run-windows11.py
|
|
```
|
|
|
|
All virtual machines use OVMF/UEFI firmware. Each launcher creates a private,
|
|
persistent `OVMF_VARS_4M.fd` variable store in the VM state directory.
|
|
|
|
Closing the QEMU window stops a foreground VM. To keep the launcher in the
|
|
background while still showing the graphical window:
|
|
|
|
```bash
|
|
./run-debian13.py --daemon
|
|
```
|
|
|
|
The launcher uses KVM when `/dev/kvm` is accessible, forwards host port `2222`
|
|
to guest port `22`, and creates `vm/debian13/disk.qcow2` as a 20G writable overlay with the
|
|
original qcow2 image as its backing file. The base image therefore stays
|
|
unchanged. Run `./run-debian13.py --help` for the supported environment
|
|
variables.
|
|
|
|
The Debian VM hardware (8G memory, 8 CPUs, drives) is
|
|
defined in the QEMU config file `qemu/debian13/config.ini`; the machine type and
|
|
architecture-specific devices are in `qemu/debian13/<os>-<arch>.ini`
|
|
(os `linux` or `darwin`, arch `amd64` or `arm64`), together with the
|
|
accelerators. Edit these files to change the settings. The
|
|
launcher fills in the `${...}` file path placeholders of `qemu/debian13/config.ini`,
|
|
writes the result to `vm/debian13/qemu.ini` and starts QEMU with
|
|
`-readconfig` for that file followed by the one for the host system and guest architecture.
|
|
QEMU arguments given after `--` override the config files, for example
|
|
`./run-debian13.py -- -m 4G -smp 4`.
|
|
|
|
The launchers accept `--state-dir DIR` to keep
|
|
the VM disk, seed ISO, UEFI variables, PID file and console log in `DIR`
|
|
instead of the default `vm/<name>/`. The option takes precedence over the
|
|
corresponding `*_STATE_DIR` environment variable:
|
|
|
|
```bash
|
|
./run-debian13.py --state-dir /srv/vms/debian13-test --daemon
|
|
```
|
|
|
|
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:
|
|
|
|
```bash
|
|
./run-fedora44.py --download-only
|
|
```
|
|
|
|
If `vm/debian13/seed.iso` is missing, the launcher automatically builds it
|
|
from `seediso/debian13/user-data`, `seediso/debian13/meta-data`, and
|
|
`seediso/debian13/network-config` before starting the VM.
|
|
|
|
Image download URLs and implementation are maintained in the `vm-images`
|
|
submodule. Clone this repository with its submodules, or initialize it later:
|
|
|
|
```bash
|
|
git submodule update --init --recursive
|
|
```
|
|
|
|
The launchers prefer `vm-images/download-images.sh` when the submodule is
|
|
initialized. Otherwise, they fall back to `../vm-images/download-images.sh`
|
|
for compatibility with the previous sibling-repository layout. Set
|
|
`VM_IMAGE_HELPER` to use another helper path explicitly.
|
|
|
|
If the Debian base image is missing, the launcher calls the selected image
|
|
helper with `debian13`.
|
|
|
|
## AlmaLinux 10
|
|
|
|
Start an AlmaLinux 10 Generic Cloud VM with:
|
|
|
|
```bash
|
|
./run-almalinux10.py
|
|
```
|
|
|
|
When the shared AlmaLinux image is missing, the launcher calls the selected
|
|
image helper with `almalinux10`. It creates the writable
|
|
overlay `vm/almalinux10/disk.qcow2` and uses the NoCloud configuration in
|
|
`seediso/almalinux10/`. SSH is forwarded to host port `2223` by default:
|
|
|
|
```bash
|
|
ssh -p 2223 guofang@localhost
|
|
```
|
|
|
|
AlmaLinux settings use the `ALMA_VM_` prefix. For example:
|
|
|
|
```bash
|
|
ALMA_VM_MEMORY=4G ALMA_VM_CPUS=4 ALMA_VM_SSH_PORT=2224 ./run-almalinux10.py
|
|
```
|
|
|
|
Run `./run-almalinux10.py --help` for all supported settings. The seed ISO is
|
|
stored alongside the VM disk at `vm/almalinux10/seed.iso`. If it already
|
|
exists after editing its source files, rebuild it explicitly with
|
|
`./seediso/almalinux10/build-seed.sh vm/almalinux10/seed.iso`.
|
|
|
|
## Fedora 44
|
|
|
|
Start a Fedora 44 Cloud Base VM with:
|
|
|
|
```bash
|
|
./run-fedora44.py
|
|
```
|
|
|
|
The launcher downloads the `fedora44` image through the shared helper when it
|
|
is missing, creates `vm/fedora44/disk.qcow2`, and builds its NoCloud seed from
|
|
`seediso/fedora44/`. SSH is forwarded to host port `2224` by default:
|
|
|
|
```bash
|
|
ssh -p 2224 guofang@localhost
|
|
```
|
|
|
|
On the first boot, cloud-init updates package metadata and installs Fedora's
|
|
GNOME package group through its native package module, then reboots the guest.
|
|
Keep the VM running until this initial installation and reboot have completed.
|
|
|
|
Like the Debian VM, the Fedora VM hardware (8G memory, 8 CPUs, drives) is
|
|
defined in `qemu/fedora44/config.ini`, with the accelerators, machine type and
|
|
platform-specific devices in `qemu/fedora44/<os>-<arch>.ini`. Other Fedora settings use the `FEDORA_VM_` prefix.
|
|
Run `./run-fedora44.py --help` for the complete list of overrides.
|
|
|
|
## Ubuntu 26.04
|
|
|
|
Start an Ubuntu 26.04 LTS (Resolute Raccoon) cloud image VM with:
|
|
|
|
```bash
|
|
./run-ubuntu2604.py
|
|
```
|
|
|
|
The launcher downloads the `ubuntu2604` image through the shared helper when
|
|
it is missing, creates `vm/ubuntu2604/disk.qcow2`, and builds its NoCloud seed
|
|
from `seediso/ubuntu2604/`. Like the Debian seed, it injects the current user's
|
|
SSH public key and points APT at the USTC mirror (`ubuntu-ports` on arm64).
|
|
SSH is forwarded to host port `2225` by default:
|
|
|
|
```bash
|
|
ssh -p 2225 guofang@localhost
|
|
```
|
|
|
|
On the first boot, cloud-init installs `ubuntu-desktop-minimal` (GNOME) and
|
|
`ibus-table-wubi`, makes the graphical target the default and reboots the
|
|
guest. Keep the VM running until this initial installation and reboot have
|
|
completed.
|
|
|
|
The VM hardware (8G memory, 8 CPUs, drives) is defined in
|
|
`qemu/ubuntu2604/config.ini`, with the accelerators, machine type and platform-specific
|
|
devices in `qemu/ubuntu2604/<os>-<arch>.ini`. Other Ubuntu
|
|
settings use the `UBUNTU_VM_` prefix. Run `./run-ubuntu2604.py --help` for the
|
|
complete list of overrides.
|
|
|
|
## Windows 11 23H2
|
|
|
|
On first boot, the Windows 11 launcher creates a writable system-disk overlay
|
|
from the shared Windows 11 QCOW2 base image:
|
|
|
|
```bash
|
|
./run-windows11.py
|
|
```
|
|
|
|
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 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.
|
|
|
|
The base image carries the VirtIO drivers (`build-windows-base.sh` installs them
|
|
from the virtio-win ISO before generalizing), so on arm64 the VM uses virtio-net and
|
|
virtio-gpu (2304x1440 on macOS); amd64 uses an IDE disk and an e1000e NIC. 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 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 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
|
|
|
|
The host ports forwarded to the guest are not in the QEMU config files (a
|
|
config file section cannot hold more than one `hostfwd`) but in one file per
|
|
VM, `qemu/<vm>/forwards.conf`, which the launcher turns into the `-netdev`
|
|
argument. Each line is `LABEL HOST_PORT GUEST_PORT`; `#` starts a comment:
|
|
|
|
```
|
|
# qemu/windows11/forwards.conf
|
|
RDP 3389 3389
|
|
SSH 2222 22
|
|
```
|
|
|
|
Add a line to forward another port. A rule whose host port is already in use
|
|
is skipped with a warning. `ALMA_VM_FORWARDS`, `FEDORA_VM_FORWARDS`,
|
|
`UBUNTU_VM_FORWARDS`, `VM_FORWARDS` (Debian) and `WIN11_VM_FORWARDS` select
|
|
another file. `ALMA_VM_SSH_PORT`, `WIN11_VM_RDP_PORT`, `WIN11_VM_SSH_PORT`
|
|
and `--rdp-port`/`--ssh-port` still replace the host port of the rule with the
|
|
label `SSH` or `RDP`. The launchers import `vmforwards.py` from the repository
|
|
root.
|