Tested against live aether-lab host. Fixes:
1. Repo detection: PVE 9 uses .sources (deb822) format, not .list files.
Now checks both formats, reads Enabled: field for deb822 enterprise
repos, and greps for pve-no-subscription across all formats.
2. Available disk detection: zpool status shows partition names
(nvme0n1p3), not whole-disk names. Now strips partition suffix to
get parent disk, correctly excluding system pool disks. Also detects
existing partition tables (linux_raid_member, etc.) on available
disks and warns about them.
3. WireGuard detection: empty output from "wg show" piped through
"head -1" produced empty string (not "none"), which was parsed as
active. Now explicitly checks for empty output.
4. Storage apply: detects and warns about disks with existing
partitions, offers to wipe before ZFS pool creation. Default pool
name changed to "vm-storage" (since "local-zfs" is the system pool).
5. Repo apply: handles both .list and .sources formats for disabling
enterprise repos. Generates correct deb822 format for PVE 9 when
adding no-subscription repo.
6. Fixed invalid syntax: "for f in ... 2>/dev/null; do" is not valid
bash -- removed the redirect, file existence is checked with -f.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Three bugs that caused the script to exit silently or behave wrong:
1. SSH detection used a double-quoted string with nested Python/awk
containing $ and " characters that bash tried to expand locally.
Switched to a quoted heredoc (<<'DETECT') so the entire remote
script is passed literally.
2. dry_run_guard had return values swapped: returned 0 (success) when
NOT in dry-run, causing apply functions to skip real work. Now
returns 0 when DRY_RUN=true so "if dry_run_guard; then return; fi"
correctly short-circuits.
3. Multiple "[[ test ]] && action" patterns outside if-conditions
return 1 when the test is false, triggering set -e to abort.
Converted all to "if [[ test ]]; then action; fi" form.
Also fixed Python any() pattern: "any(...) and print('yes')" never
prints "no" — replaced with print("yes" if any(...) else "no").
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The script now does a comprehensive single-pass detection of the host
state (repos, nag patch, packages, bridge, forwarding, NAT, storage,
WireGuard, firewall, API role/pool/token) and displays a status dashboard
showing what's done vs. what needs attention. Only pending items are
offered for configuration. Already-done steps are skipped automatically.
Partial states are handled too: e.g. bridge exists but NAT not active,
or repos switched but nag popup still present.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
New hetzner/ directory with step-by-step Proxmox setup guide (networking,
WireGuard, firewall, storage, API tokens) and an interactive helper script
that automates all steps over SSH.
New incusos/targets/ layout with per-host connection configs and lab
definitions for beelink and hetzner targets. No changes to incusos-proxmox
itself -- uses existing --proxmox flag.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>