Highlights
14 customer-reported fixes bundled into a single hotfix release covering keystore install bugs, two cross-hypervisor migration paths (PVE → XCP-ng + ESXi → PVE), Site Recovery state cleanup, OIDC opt-in for internal IdPs, and a sweep of dashboard / migration / clone-modal UI polish.
🔐 Critical — fresh-install boot-loop fix
#417 — deploy.sh was writing the v0.9.10 master key at /etc/pegaprox/secret.key as 0600 root:pegaprox, so the systemd service (running as pegaprox) couldn't read its own key and looped on PermissionError: [Errno 13]. Fix in three places:
- Fresh installs now create the key as
0640 root:pegaprox(group-readable for the service). - On upgrade, an existing key at
0600/0400is auto-bumped to0640— existing v0.9.10/.1/.2 installs self-heal on the nextupdate.sh. pegaprox/core/keystore.py_enforce_permsaccepts0600OR0640, hard-rejects anything looser.
Plus deploy.sh and update.sh now honour a PEGAPROX_BRANCH env-var, so PEGAPROX_BRANCH=Testing curl ... | sudo -E bash actually clones Testing instead of always main.
Workaround for existing installs hitting the boot-loop before this patch:
sudo chmod 640 /etc/pegaprox/secret.key
sudo systemctl restart pegaprox📦 Cross-hypervisor migration
- #411 — v2p disk copy now captures bash-script
stdout+stderronrc != 0and logs the last ~10 lines to the task log. "Copy failed!" finally becomes actionable. Plus a chmod literal-string bug fixed for symmetry. - #398 + #400 — PVE → XCP-ng:
qemu-img convert ... /dev/stdoutswapped to-to bypass the ftruncate-EINVAL bail, and qcow2 detection now matches the.qcow2suffix alone so qcow2-on-LVM block devices stop being labeled raw. - #414 — Cross-cluster migration pre-flight warns about
unused*disk references that PVE keeps after a Detach, before they blow up the migration with a cryptic "storage does not support vm images" from the target.
🛡️ Site Recovery
#413 — Boot-recovery sweep for stuck rows. If PegaProx crashed mid-failover, site_recovery_events rows at status='running' and the matching site_recovery_plans at running/testing would haunt the UI forever as live tasks. They now get cleaned at app start: events → aborted with {reason: pegaprox_restart} details, plans → failed so the state machine re-arms cleanly.
🔐 OIDC
#412 — Opt-in oidc_allow_private_ip config knob for self-hosted IdPs at 10.x / 192.168.x / 172.16-31.x. Cloud metadata endpoints (169.254.x.x, fd00:ec2::, etc.) stay blocked. UI toggle in the OIDC settings panel with translations for all 7 supported languages (DE / EN / FR / ES / PT / KO / IT).
📊 Dashboard / VM workflows
- #415 — Cross-cluster migration target-node dropdown now shows real CPU / RAM percentages instead of empty
%. - #416 — Clone VM target-node dropdown snapshot-frozen at mount so the auto-refresh poll stops reshuffling entries while you're picking one.
- #419 — Node Network In/Out columns finally non-zero (PVE's
/cluster/resources?type=nodedoesn't return netin/netout — we now pull from/nodes/<n>/rrddata). - #385 — VM bridge dropdown drops
OVSIntPortentries on OVS-backed PVE (those are L3 access ports, not bridges; PVE's own UI doesn't show them either). - #365 — Generate-MAC button honours Datacenter → Options → MAC address prefix (
BC:24:11and 1- / 2-octet variants) instead of always rolling02:xx:xx:xx:xx:xx.
🛠️ Operator quality-of-life
- #357 — Three env vars for log control:
PEGAPROX_LOG_LEVEL,PEGAPROX_FILE_LOG_LEVEL,PEGAPROX_DISABLE_FILE_LOG. For operators shipping logs to a central collector. - Support-bundle now falls back to
journalctl -u pegaprox --since '24 hours ago'when nopegaprox.logfile exists. Most systemd / LXC-appliance installs route straight to journald — the bundle gives the actual log slice now instead of "Log file not found".
💎 Platinum Sponsors
- netwolk GmbH — Swiss managed-services partner
- Expertize.nl — Dutch Proxmox specialists
Sponsor PegaProx → opencollective.com/pegaprox | pegaprox.com/#sponsor
Upgrade: in-app updater, bash update.sh, or docker compose pull && docker compose up -d.
Docker: ghcr.io/pegaprox/pegaprox:v0.9.10.3 (linux/amd64 + linux/arm64).