Sites no longer need either MAC in site-vars.
pxe_nic_mac empty: before anything changes, the playbook runs
pxe-pick-nic --auto. It takes the one wired port with a link, accepts it
only if pxe-nic-check calls it isolated (no LLDP/CDP/802.1X, no other
DHCP server, at most 10 hosts heard in 65 s), and pins it. The choice is
saved in /etc/pxe-server/nic-pick.conf and never re-guessed at boot.
When it cannot tell (no link, two links, not isolated) nothing changes,
and the console banner says why and to run sudo pxe-pick-nic: pull the
imaging cable and plug it back in, and the port that blinked is the
imaging one. Both helpers are installed before the pick, so that works
after a refused first boot. The site's corp domains and allowed
switches are passed to the check.
corp_nic_mac empty: every other wired port (en*, eth*) is a catch-all
DHCP client, so GE can be plugged in at install or later.
- dnsmasq stays pinned with interface=pxe0. A new check refuses any
dhcp-range outside the imaging subnet, and proxy ranges.
- The catch-all ports ignore offers from 172.16.9.1.
- UFW allows SSH and 9009 by source on any interface, and keeps those
rules when the old any-interface rules are removed.
- pxe_nic_name must not look like en*/eth* in this mode.
pxe-netplan-apply.sh takes 3 or 5 args. Without a pinned GE NIC it:
- renames stray names (the old pxe0 after a re-pick, a leftover corp0)
to enx<mac>, so the catch-all takes them, and restores them on revert;
- checks that every NIC that had a DHCP address before has one after,
tracked by MAC.
With both MACs set (the WJ server), netplan, the dnsmasq pin and UFW
render byte-for-byte as before.
Tested in the pxetest VMs:
- Fresh install with no MACs and the GE link down: the imaging port was
picked and pinned as pxe0 with 172.16.9.1, and dnsmasq bound DHCP to
pxe0 only. GE plugged in afterwards got a lease, SSH worked, and the
guard reported pxe0 isolated.
- --auto refuses with two links.
- The interactive pick works by pulling and replugging the link.
- A 3-arg re-apply is UNCHANGED.
Unit tests (fake sysfs) cover the re-pick and pinned-to-catch-all renames.
- 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.
Boot menu: "Clonezilla: back up this PC" and "restore this PC" ask for the
machine number and boot Clonezilla (64-bit with Debian shim, or 32-bit
i686 by cpuid) with ocs_repository=smb3://clonezilla:<pw>@server/clonezilla/,
ocs_prerun fetching clonezilla-scripts/pxe-cz.sh and ocs_live_run running
it. The script validates the machine number, saves
<machine>-<YYYY-MM-DD-HHMM> (server time), writes pxe-meta.txt, runs
ocs-chkimg, and restores only that machine's images with -k1 -r after a
typed YES. The old entry is "Clonezilla: manual".
Playbook: clonezilla Samba user for the [clonezilla] share only, password
from clonezilla_smb_password (validated, filled into the menu
placeholder), scripts installed to the web root.
Webapp: Clonezilla backups page lists image folders and zips grouped by
machine number with serial/model/version/check, serial mismatch flag,
delete, move to another machine, streamed tar download, disk space bar
and an explicit keep-last-N retention with preview. Tests and a VM test
plan added.
Clonezilla Live runs a Debian-signed kernel whose modules (usb-storage,
uas, exfat) are signed by the same build key, so the menu now starts it
through Debian's Microsoft-signed shim with the iPXE shim command, the
same way Blancco uses Ubuntu's. prepare-boot-tools.sh extracts that shim
from the Clonezilla release (EFI/boot/bootx64.efi -> clonezilla/
shimx64.efi) and warns when the shim is not Microsoft-signed or the
kernel not Debian-signed.
Memtest86+ is unsigned and needed Secure Boot off; memory tests now use
the Dell built-in diagnostics (F12 at power-on, Diagnostics), noted in
the menu. The playbook removes the old memtest web dir. Nothing on the
menu needs Secure Boot off any more; the 'disable Secure Boot' screen
remains only as the fallback when a signed path fails.
- pxe-nic-check: count 802.1X only from an authenticator (EAPOL type 0
with EAP Request/Success/Failure). iPXE sends EAPOL-Start on every NIC
open and Windows sends Start/Response, so a PXE-booting bay made the
verdict 'ge' and the watch stopped dnsmasq for the floor.
- pxe-nic-check: join the STP/PAE/LLDP/CDP/PVST+ multicast groups on
every capture socket, so CDP-only ports are heard on a plain NIC.
- pxe-nic-check --watch: if dnsmasq was (re)started inside the window,
re-check (~6 s) before stopping it; skip when already stopped.
New --state-cmd and --print-imaging.
- pxe-nic-carrier (+ pxe-nic-carrier.service): networkd-dispatcher hook
for the imaging NIC only. Carrier loss stops dnsmasq; carrier gain
restarts it through its guard if it was running or the hook stopped it.
- pxe-dhcp-hook.sh: clear only SMB (tcp 445/139) conntrack entries and
sockets, not all traffic for the client, which raced iPXE's first
HTTP fetch.
- GetPxeScript.aspx: every boot line has a failure branch (iPXE 2.0
accepts an unsigned EFI kernel and fails at boot under Secure Boot,
which aborted the script).
- Tests: client EAPOL, packet_mreq packing, watch race, shell helpers on
stub PATH, lab scenarios eapol-client, br-eapol-client, race, carrier.
- autoinstall: dead mirror + fallback offline-install, so the installed
base is exactly the ISO's; late-commands run offline-apt-install.sh on
CIDATA packages/ (local apt repo, one transaction, errors fail the
install, log /var/log/offline-apt-install.log); first boot no longer
runs dpkg -i; real archive sources written back at the end.
- download-packages.sh --iso: unpacks the ISO's default install source
into a docker image (pxe-iso-base:<version>) and downloads there: all
updates of the base, the explicit list (zip included) and the newest
pool packages with their closure; writes Packages + explicit.list and
checks the set offline in a fresh base container (--network none).
- offline-apt-install.sh: new; also used by that check (--simulate).
- build-usb.sh: ships Packages, explicit.list and the script; refuses a
set without them.
- tests/vm: pxetest-client-nosb (Secure Boot off, e1000e, SATA), one
client at a time.
- Copy the whole webapp/ tree (minus __pycache__) in build-usb.sh and
build-proxmox-iso.sh, so config, services/, views/ and
blancco_evidence_monthly.py reach the server.
- sfdisk --append failure now aborts; the CIDATA partition is the one
starting exactly at the computed sector, and nothing that starts
before it is ever formatted (the old fallback hit the ISO's EFI
partition).
- Volume id and El Torito load sizes come from the ISO
(xorriso -report_el_torito as_mkisofs); grub.cfg must contain
autoinstall after patching.
- --image FILE SIZE|auto builds the same layout in a file without root
(mkfs.vfat -C + mtools, sfdisk on the file). Plus --payload-root,
--skip-enrollment/-bios/-drivers/-boot-tools, --yes.
- tests/vm: libvirt harness (pxetest-server, pxetest-client, isolated
pxetest-imaging network) with fetch-iso/build-image/create/start/
status/stop/destroy.
pxe-nic-check classifies each NIC from what it hears: LLDP/CDP/802.1X
from managed switches, foreign DHCP offers and their domain (one
DHCPDISCOVER on the imaging NIC; the GE NIC's networkd lease is read
instead), STP and ARP hosts for information. A kernel BPF filter keeps
bulk SMB traffic out of the capture loop; bridge ports are listened on
too, since LLDP and EAPOL stop at the port.
- dnsmasq drop-in runs --guard as ExecStartPre: exit 1 on a ge or
foreign-dhcp imaging verdict, fail open (loudly) on bugs or no link
- pxe-nic-check.timer runs --watch every 5 min: stops dnsmasq on a bad
imaging verdict, never starts it
- /run/pxe-nic-status.json (0644, atomic) for the webapp
- playbook installs it all and writes /etc/pxe-server/nic.conf from
pxe_imaging_mac, pxe_ge_mac, pxe_corp_domain_suffixes,
pxe_nic_allowed_switches
- unit tests plus a no-root network-namespace lab (veth pairs, a raw
socket DHCP/LLDP peer and real dnsmasq); docs/pxe-nic-guard.md has the
operator notes and the two floor tests