
Reinstalling a Proxmox VM Shouldn’t Be a Manual Job
I have run Proxmox VE since 2009.
Over those years, one job never got easier for me: reinstalling a guest.
Somebody wants a clean OS on an existing VM. Same VMID. Same IP. Same MAC, because something upstream cares about it. Fresh Debian, please.
The manual version looks like this:
- Find a current cloud image for that OS.
- Download it.
- Import it as the boot disk.
- Find a free IP address.
- Set up the network again.
Then the next guest. Then the next one.
None of these steps is hard. Together, they are a reliable way to make a mistake at 23:00.
So I built PMXSpan, a native desktop app for managing Proxmox VE clusters. I built it mostly for three jobs:
- automated VM and container reinstalls
- current cloud images, pulled directly from the vendors
- automatic IP assignment from its own IPAM
It does more than that. But those three are why it exists.
Templates Get Old
The usual answer is a VM template. Build it once, clone it forever.
The problem is “forever”.
A template you built six months ago boots with six months of missing updates. The first thing you do on the “fresh” guest is patch it.
I wanted every reinstall to start from the image the vendor publishes today.
An OS Image Catalog That Points at the Vendor
PMXSpan has an OS image catalog. Each entry is a URL to the vendor’s own cloud image, for example Debian’s latest bookworm image on cloud.debian.org.

VM images in qcow2, raw, vmdk or ova format are downloaded to an import storage and imported as the boot disk. Container templates go to a vztmpl storage.
Each entry also stores the image format, the OS type, the cloud-init user, an optional checksum and which nodes may use it. Custom cloud-init snippets stay on your computer. They are never exported or imported.
Config overrides exist, but they are deliberately narrow. CPU, memory, firmware and similar keys are accepted. Anything that touches disks, network, cloud-init, host access or container privileges is rejected.
A catalog entry should not be a back door into your host.
Catalogs import and export as JSON, so the same list can follow you between machines.
Rebuild, but Keep the Identity
This is the part I actually wanted.
A rebuild replaces the guest’s disks with a fresh copy of a template or a catalog image. It keeps:
- the VMID
- the name
- the resources
- the NICs, with their MAC addresses
- the IP addresses
- the pool
Anything that finds the guest by its VMID or IP keeps working: DNS records, monitoring checks, upstream firewall rules.

On the Manage tab, you pick a template VM or a catalog image, set a new password (or generate one), paste SSH keys, and decide two things: start the guest afterwards, and take a backup first.
Two details matter more than the button.
The image is downloaded before anything is touched. A failed download leaves the guest exactly as it was.
And the rebuild wipes the guest’s disks. PMXSpan says so in capitals, and the backup option sits right next to the button.
I’d rather have a tool that is blunt about destruction than one that is polite about it.
IPAM That Refuses to Guess
The third job was IP addresses.
PMXSpan keeps local IPv4 and IPv6 pools. The create wizard and rebuilds take addresses from them. No more looking for a free IP in a spreadsheet.

One rule I cared about: an explicitly requested IP is assigned exactly, or the operation fails. It is never silently replaced with another one.
Silent substitution is how a guest ends up on an address nobody documented.
Assignments list the IP, server, VMID, interface, hostname and when it was assigned. You can also reserve addresses for things outside Proxmox, like a switch.
History logs every address that was assigned, adopted, released, made main, reserved or unreserved, with who did it.
Drift compares IPAM with the live cluster. It finds:
- addresses still held for guests that are gone
- static addresses guests use that IPAM doesn’t know about
- main addresses that differ
- guests created by PMXSpan that have no IPAM record
Most of those come with a one-click fix: Adopt, Apply IPAM or Release.
An IPAM is only useful while it matches reality. Drift is how you find out when it stopped.
A Desktop App, on Purpose
PMXSpan is a native desktop app written in Rust, using egui and tokio. It talks directly to the Proxmox VE API.
No web server.
No database server.
No agents on your nodes.
Nothing new to install on the cluster, and nothing new to expose to the internet.
It does need credentials, so those got some attention:
- API token or password login, with TOTP two-factor support
- TLS options, including certificate fingerprint pinning
- a local vault encrypted with Argon2id (64 MiB) and XChaCha20-Poly1305 under a master password, locked after 30 idle minutes by default
For scheduled work there is a headless mode (--run-schedules) that runs without the window.
The repository also ships a mock Proxmox API (tools/mock_pve.py), so you can click through the interface without pointing it at a real cluster.
What Else Is in There
Managing several clusters from one window pulled in the rest:
- multiple clusters and server profiles
- a VM and container create wizard with auto-placement and cloud-init
- backup jobs and Proxmox Backup Server file restore
- snapshot schedules, timed power actions and usage alerts
- users, tokens, pools, ACLs, a tenant wizard and per-pool limits
- noVNC and xterm.js consoles, plus SPICE through virt-viewer
Where It Stands
PMXSpan is at version 0.6.0. It is not finished.
Not included yet: reverse DNS (PTR) management through external DNS backends.
The macOS build is not notarized yet, so macOS will warn you the first time you open it.
You Can Use It, Inspect It or Break It
PMXSpan is open source under the MIT license.
The repository is here: github.com/AGSQ11/PMXSpan
Builds are published through the project’s GitHub Releases:
| Platform | Download |
|---|---|
| Windows 10/11 (x64) | Setup.exe installer or portable zip |
| Debian, Ubuntu, Mint | .deb package |
| Any Linux (x86_64) | AppImage (needs FUSE 2) or tar.gz |
| macOS 11+ | .dmg (not notarized yet) |
Linux builds need glibc 2.31 or newer. Each release ships a SHA256SUMS.txt. Check it.
To build from source, you need Rust 1.88 or newer:
cargo build --release
If you rebuild guests for a living, I want your feedback. Open an issue for anything that breaks, anything missing, and any cloud image PMXSpan chokes on.
My Take
Reinstalling a guest is not a hard problem.
It is a repetitive one, and repetitive work is where mistakes live.
I wanted the boring version. Pick the image. Keep the identity. Get the IP right. Know that a failed download leaves the old guest alone.
That became PMXSpan.
Your guests stay normal Proxmox guests. Nothing runs on the nodes on PMXSpan’s behalf. Close the app, and the cluster doesn’t notice.
Good infrastructure tooling should make itself useful.
It should not make itself indispensable.
$ end of file
All field notes