- Deploy shopfloor-setup with rsync instead of the copy module: the ~4 GB tree took about 4 minutes on every re-run because copy checksums each file. rsync transfers only changes; changed only when it did. - iPXE drops a trailing space, so 'Machine number:' ran into the typed digits. The space now comes from a hex 20 setting. - tests/vm: pxetest-xp is a permanent client (SeaBIOS, qemu32 32-bit CPU, rtl8139, 1 GiB, IDE disk) for the i686 Clonezilla path; start.sh xp. Only one client may run at a time across all three.
151 lines
9.4 KiB
Markdown
151 lines
9.4 KiB
Markdown
# pxetest VM harness
|
|
|
|
Proves a new PXE server can be built from this repo, in two libvirt VMs on
|
|
a laptop, without root and without touching a real network.
|
|
|
|
## Topology
|
|
|
|
| Object | What |
|
|
|-------------------|----------------------------------------------------------------------|
|
|
| `pxetest-imaging` | libvirt network, bridge `virbr-pxetest`. No `<forward>`, no `<ip>`: the host has no address on it and libvirt runs no DHCP there. Only VM taps are on the bridge. |
|
|
| `default` | libvirt NAT, 192.168.122.0/24. Stands in for the GE/corp network. |
|
|
| `pxetest-server` | 2 vCPU, 4 GiB, q35 + OVMF Secure Boot (MS keys), 60G thin qcow2 (`vda`, boot 1), the USB image as a USB disk (`sda`, boot 2). |
|
|
| `pxetest-client` | 2 vCPU, 2 GiB, OVMF Secure Boot (MS keys), 1G blank disk, network boot first (UEFI IPv4 PXE, virtio-net, OVMF driver, no option ROM). Proves shim -> iPXE -> menu -> WinPE under Secure Boot; WinPE has no virtio driver, so it stops at "Waiting for network". |
|
|
| `pxetest-client-nosb` | 2 vCPU, 2 GiB, OVMF without Secure Boot, e1000e NIC, 64G thin SATA disk. WinPE has in-box drivers for both, so startnet gets a network and maps the shares. |
|
|
| `pxetest-xp` | XP/Win7-era PC: 1 vCPU, 1 GiB, i440FX + SeaBIOS (legacy PXE, gets `ipxe.pxe`), `qemu32` CPU (no long mode, so the menu picks the i686 Clonezilla; `fallback='forbid'` so it never silently becomes 64-bit), rtl8139 NIC, 8G thin IDE disk. |
|
|
|
|
NIC MACs (fixed):
|
|
|
|
| VM | NIC | MAC | Network | Playbook var |
|
|
|--------|---------|---------------------|-------------------|-------------------|
|
|
| server | GE | `52:54:00:9e:10:01` | `default` NAT | `corp_nic_mac` |
|
|
| server | imaging | `52:54:00:9e:10:02` | `pxetest-imaging` | `pxe_nic_mac` |
|
|
| client | - | `52:54:00:9e:10:03` | `pxetest-imaging` | - |
|
|
| client-nosb | - | `52:54:00:9e:10:04` | `pxetest-imaging` | - |
|
|
| xp | - | `52:54:00:9e:10:05` | `pxetest-imaging` | - |
|
|
|
|
`build-image.sh` writes `$PXETEST_CACHE/site-vars.yml` with these two
|
|
MACs (`pxe_nic_mac`, `corp_nic_mac`) and passes it to `build-usb.sh
|
|
--site-vars`, so it lands on CIDATA as `playbook/site-vars.yml`. The
|
|
installer brings both NICs up with DHCP; the playbook renames them to
|
|
pxe0 / corp0 and pins pxe0 to 172.16.9.1.
|
|
|
|
The disk boots before the USB on purpose: a blank disk falls through to
|
|
the installer, and after the install the server boots its disk instead of
|
|
re-running autoinstall. CIDATA stays attached for the first-boot playbook.
|
|
|
|
Never attach a pxetest VM to a physical NIC, a host bridge with physical
|
|
ports, or macvtap: the server's dnsmasq serves DHCP/PXE as 172.16.9.1.
|
|
`create.sh`, `start.sh` and `status.sh` check the isolation and refuse to
|
|
continue if `pxetest-imaging` ever gains a `<forward>`, an `<ip>`, a host
|
|
IPv4 address or a non-tap bridge port.
|
|
|
|
## Run it
|
|
|
|
export PXETEST_CACHE=~/.cache/pxetest # ISO + image (about 10 GB)
|
|
export PXETEST_PAYLOAD_ROOT=/home/camp/projects/pxe # checkout holding offline-packages/, boot-files/, ...
|
|
export UBUNTU_ISO_NAME=ubuntu-24.04.3-live-server-amd64.iso # optional; default 24.04.5
|
|
|
|
tests/vm/fetch-iso.sh # the live-server ISO, SHA256SUMS-verified
|
|
scripts/download-packages.sh --iso "$PXETEST_CACHE/$UBUNTU_ISO_NAME" "$PXETEST_PAYLOAD_ROOT/offline-packages"
|
|
scripts/check-updates.py --debs "$PXETEST_PAYLOAD_ROOT/offline-packages"
|
|
tests/vm/build-image.sh # build-usb.sh --image, upload as volume pxetest-usb.img
|
|
tests/vm/create.sh # network, volumes, all VMs (prints the MAC pins)
|
|
tests/vm/start.sh server # autoinstall, reboot, first-boot playbook
|
|
tests/vm/status.sh --shot /tmp/pxetest-shots # states, leases, screenshots
|
|
tests/vm/start.sh client # once the server playbook is done (Secure Boot client)
|
|
tests/vm/stop.sh client
|
|
tests/vm/start.sh client2 # Secure Boot off, e1000e: WinPE maps the shares
|
|
tests/vm/start.sh xp # legacy BIOS, 32-bit: i686 Clonezilla
|
|
tests/vm/stop.sh # ACPI shutdown all, keep them defined
|
|
tests/vm/destroy.sh # remove every pxetest-* object
|
|
|
|
`build-image.sh` skips enrollment/, bios-staging/, drivers-staging/ and
|
|
boot-tools/ by default; `--with-enrollment` and `--with-boot-tools` add
|
|
them back, `--size 20G` fixes the image size (default `auto`). If the host
|
|
has no `sfdisk` or `mtools`, the debs are extracted into
|
|
`$PXETEST_CACHE/tools` (no install, no root).
|
|
|
|
Watch the server with `virt-viewer -c qemu:///system pxetest-server` (VNC on
|
|
127.0.0.1) or screenshots. On the installed system, first-boot output goes
|
|
to `/var/log/first-boot.log`. Once the GE NIC takes a DHCP lease on the NAT
|
|
network, `status.sh` shows its address and `ssh pxe@<address>` works from
|
|
the host.
|
|
|
|
The offline package set must be built against the SAME ISO the image is
|
|
built from (download-packages.sh resolves against that ISO's base). For a
|
|
fresh server disk: `tests/vm/destroy.sh`, then build-image.sh, create.sh,
|
|
start.sh server.
|
|
|
|
Memory: server 4 GiB + one client 2 GiB (start.sh refuses a second client). Keep other VMs (win11) off while
|
|
both run, and stop them when done.
|
|
|
|
Blancco needs more client RAM than 2 GiB: blancco-init downloads its
|
|
~850 MB rootfs into a tmpfs, and at 2 GiB it stops at 48% with "No space
|
|
left on device". To test it within the 6 GiB budget, shrink the server and
|
|
grow the client while both are off, and put them back afterwards:
|
|
|
|
virsh -c qemu:///system setmaxmem pxetest-server 2048M --config
|
|
virsh -c qemu:///system setmem pxetest-server 2048M --config
|
|
virsh -c qemu:///system setmaxmem pxetest-client 4096M --config
|
|
virsh -c qemu:///system setmem pxetest-client 4096M --config
|
|
|
|
Menu keys from the host: `virsh -c qemu:///system send-key <vm> KEY_DOWN`
|
|
(separator lines are skipped: Down x1 = Blancco, x2 = Blancco debug,
|
|
x3 = Clonezilla: back up, x4 = Clonezilla: restore, x5 = Clonezilla manual,
|
|
x6 = Clonezilla manual 32-bit, x7 = Reboot), then KEY_ENTER; startnet
|
|
answers are KEY_<digit> + KEY_ENTER.
|
|
|
|
## Clonezilla back up / restore by machine number (VM test plan)
|
|
|
|
Covers GetPxeScript.aspx (:cz_backup, :cz_restore, :cz_auto64/32),
|
|
playbook/clonezilla-scripts/pxe-cz.sh, the clonezilla Samba account and the
|
|
webapp's Clonezilla backups page. Re-run the playbook first (or rebuild) so
|
|
the server has the new menu, /var/www/html/clonezilla-scripts/pxe-cz.sh and
|
|
the clonezilla user; `--with-boot-tools` is needed for Clonezilla itself
|
|
(clonezilla/ and clonezilla-i686/).
|
|
|
|
0. Server checks (ssh pxe@<corp address>):
|
|
- `grep -c 'smb3://clonezilla:' /var/www/html/Altiris/iPXE/GetPxeScript.aspx` = 2,
|
|
and no `__CLONEZILLA_SMB_PASSWORD__` left in it.
|
|
- `curl -s http://172.16.9.1/clonezilla-scripts/pxe-cz.sh | head -1` = `#!/bin/bash`.
|
|
- `pdbedit -L | grep ^clonezilla:`; `smbclient //172.16.9.1/clonezilla -U clonezilla%<pw> -c ls`
|
|
works, `smbclient //172.16.9.1/winpeapps -U clonezilla%<pw> -c ls` is
|
|
refused (NT_STATUS_ACCESS_DENIED): the account opens only its share.
|
|
- Blancco Releases page: add and remove a test entry still works.
|
|
1. Back up as 6501, 64-bit Secure Boot client (pxetest-client, raise RAM to
|
|
3-4 GiB as for Blancco: the live system plus the squashfs need about
|
|
1.5 GiB). Put something on its 1G disk first (e.g. boot client2's WinPE
|
|
and `diskpart` a partition, or `qemu-img` a small NTFS/ext4 image).
|
|
Menu Down x3, Enter. At `Machine number:` press Enter on empty (asks
|
|
again), then type 6501. Expect: Clonezilla boots through the shim (no
|
|
Secure Boot error), no language/keyboard questions, no password on
|
|
screen, the share mounts, one disk so no disk question, image
|
|
6501-YYYY-MM-DD-HHMM (server time, Eastern) is saved, "Checking the saved
|
|
image", SUCCESS banner with serial and model, power off after 60 s.
|
|
2. Same as 6501 from the 32-bit BIOS client (`start.sh xp`, pxetest-xp):
|
|
`cpuid --ext 29` fails on its qemu32 CPU and :cz_auto32 boots
|
|
clonezilla-i686. Give its IDE disk content first, as for step 1. Expect pxe-meta.txt bits=32, firmware=bios,
|
|
clonezilla=clonezilla-live-3.2.0-5-i686. Also type `65 01` once:
|
|
Clonezilla says the number is not valid and asks again.
|
|
3. Webapp (Tools > Clonezilla backups): both images under 6501, newest
|
|
first, serial and model from the VM's DMI (QEMU: serial empty unless
|
|
`<sysinfo>` sets one; set `<entry name='serial'>VMSER1</entry>`), size,
|
|
disks/partitions, Clonezilla version, 64/32-bit, Check = Checked.
|
|
Download .tar of one image and `tar tvf` it.
|
|
4. Restore to a second, LARGER blank disk: attach a blank 4G disk to the
|
|
client (`virsh attach-disk ... --config`, then boot). Menu Down x4,
|
|
machine 6501. Expect only 6501's images, newest first; pick one; the
|
|
disk list shows both disks with model and size; pick the 4G one; type
|
|
YES. Clonezilla runs restoredisk with -k1 -r: afterwards `sfdisk -l`
|
|
(Clonezilla shell, s at the end prompt) shows the partitions scaled to
|
|
4G and the filesystem grown. Picking the 1G source disk for a 4G image
|
|
(repeat with the disks swapped) must be refused as SMALLER.
|
|
5. Mismatch flag: back up the second client (different `<sysinfo>` serial)
|
|
also as 6501. The page shows "Serial mismatch" on 6501 and marks the odd
|
|
serial; Move to another machine... (e.g. 6502) clears it, and restore of
|
|
6502 lists the moved image.
|
|
6. Retention: Settings > Keep last 1, Apply retention... lists the older
|
|
6501 image only; Delete removes it, the newest stays.
|
|
|