Proxmox Auto Install Notes
Installation on WSL
sudo -i # to become root
echo "deb [arch=amd64] http://download.proxmox.com/debian/pve bookworm pve-no-subscription" > /etc/apt/sources.list.d/pve-install-repo.list
wget https://enterprise.proxmox.com/debian/proxmox-release-bookworm.gpg -O /etc/apt/trusted.gpg.d/proxmox-release-bookworm.gpg
apt update
apt install -y xorriso proxmox-auto-install-assistant
Answer File
Its a toml file and we use Tomlyn to load and save Models in C# to toml files.
format is like this:
[SECTION]
KEY = "VALUE"
KEY = [
"VALUE1",
"VALUE2"
]
it has these sections:
-
global
-
network
-
network.interface-name-pinning
-
network.interface-name-pinning.mapping
-
disk-setup
-
post-installation-webhook
-
first-boot
you can validate with
proxmox-auto-install-assistant validate-answer answer.toml
global
keyboard: de de-ch dk en-gb en-us es fi fr fr-be fr-ca fr-ch hu is it jp lt mk nl no pl pt pt-br se si tr
country: 2 letter code
fqdn option 1: HOSTNAME.DOMAIN
fqdn option 2: fqdn.source = "from-dhcp", fqdn.domain = "FALLBACKDOMAIN" → DHCP Server MUST supply a hostname
mailto: root user email
timezone: standard unix timezone, eg Europe/Zurich, or UTC
root-password: plain text (dont want), NOT use with hashed version
root-password-hashed: pre hashed with mkpasswd (via WSL on windows)
root-ssh-keys: optional ssh keys for root user
reboot-on-error: false (will halt on installation fail)
reboot-mode: reboot, (power-off doesnt make much sense)
network
either sets static from dhcp or all other options must be supplied
dhcp
source = "from-dhcp"
manual
source = "from-answer"
cidr = "x.x.x.x/N"
dns = "DNS IP ADDRESS"
gateway = "ROUTER IP ADDRESS"
filter: required for from-answer, not supported for from-dhcp. Uses dotted-key format with uppercase UDEV property names.
[network]
source = "from-answer"
cidr = "10.10.10.10/24"
dns = "10.10.10.1"
gateway = "10.10.10.1"
filter.ID_NET_NAME = "*"
Or to match by MAC-based name:
filter.ID_NET_NAME_MAC = "*AABBCCDDEEFF"
|
Note
|
MAC filter always has a * prefix because the interface name always has a prefix like "enx".
|
On Odroid devices, the first MAC is extracted from the serial number (which is a concatenation of all MACs, capped to 32 hex chars).
network.interface-name-pinning
enabled: true/false → controls if mapping section is used
network.interface-name-pinning.mapping
"MAC ADDRESS" = "INTERFACE NAME"
disk-setup
filesystem: ext4, xfs, zfs, btrfs → we want btrfs because snapshots make backups easy and small
disk-list: list of all disk devnames (eg sda, nvme0n) that should be added, ONLY that or filter
filter-match: "any" or "all" - required when using filter. "any" = match if any criterion matches, "all" = all must match.
filter.ID_SERIAL = "X" → can we get within winpe and write out
filter: uses dotted-key format with uppercase UDEV property names. Supports: ID_SERIAL, ID_MODEL, ID_VENDOR. Wildcards (*) supported.
[disk-setup]
filesystem = "btrfs"
filter-match = "any"
filter.ID_SERIAL = "SAMSUNG*"
zfs… options
lvm… options
btrfs… options ?
all support the optional options:
-
raid: raid0, raid1, raid10
-
hdsize: set max size in GB to be used of disk
-
compress: on, off, zlib, lzo, zstd (especially for btrfs)
post-installation-webhook
sends a post request with the system information to a url
url: post endpoint
cert-fingerprint: optional sha256 of the tls/ssl cert to verify endpoint
first-boot
optional, specify executable to run first time after boot, NETSetup ;)
source = "from-url" OR "from-iso"
ordering = "before-network" or "fully-up" → when to run the executable → then we can already auto create vms :D
url: where to download from, PUBLIC URL DIRECT DOWNLOAD (only for from-url)
cert-fingerprint: optional sha256 of the tls/ssl cert to verify endpoint (only for from-url)
from-iso details
The auto-installer reads the executable from /cdrom/proxmox-first-boot (max 1 MiB).
It must be baked into the ISO at build time with prepare-iso --on-first-boot <script>.
The installer copies it to /var/lib/proxmox-first-boot/proxmox-first-boot on the target,
enables a systemd service (proxmox-first-boot-{ordering}.service), and runs it once on first boot.
Source: pve-installer/proxmox-auto-installer/src/bin/proxmox-auto-installer.rs line 49,
pve-installer/Proxmox/Install.pm function setup_proxmox_first_boot_service.
NETSetup first-boot bootstrap (DONE)
A generic bootstrap script (netsetup-first-boot.sh) is baked into every prepared ISO.
It runs once on first boot (via PVE’s proxmox-first-boot-fully-up.service) and:
-
Downloads the NETSetup linux-x64 ELF binary from Dropbox
-
Copies machine-specific config from the SYSTEM partition (if USB still present)
-
Creates a systemd service + timer for periodic NETSetup runs (on boot + every 6h)
-
Runs
NETSetup installimmediately
The script is generic — machine identity comes from the running system (serial number, MAC, hostname from answer.toml).
Source: src/NETSetup/Resources/netsetup-first-boot.sh
C# side: WithFirstBootFromIso() in ProxmoxAutoInstallBuilder generates the [first-boot] section in answer.toml.
Called automatically by ToProxmoxAutoInstall() for all Proxmox configs.
Assistant Usage / ISO Creation
We want 1 iso to rule them all. We achieve this by modifying a regular iso only to look for the partition SYSTEM and in there for the answer file. The file must lie directly on partition root with name "answer.toml".
# 1. download current ISO from https://www.proxmox.com/en/downloads/proxmox-virtual-environment/iso
wget -O ISOPATH https://enterprise.proxmox.com/iso/proxmox-ve_9.1-1.iso
# 2. patch ISO: answer-file from SYSTEM partition + first-boot script baked in
proxmox-auto-install-assistant prepare-iso ISOPATH \
--fetch-from partition --partition-label SYSTEM \
--on-first-boot netsetup-first-boot.sh
Now you have the current iso to put into Dropbox Images, so we can later download using NETSetup.
Be sure to update the README.txt so its clear when and what are latest version.