homelab/scripts/PROXMOX-COMPARISON.md
nathan e16f98a183 feat(bootstrap)!: introduce unified bootstrap system with modular libraries
BREAKING CHANGE: day0bootstrap.sh deprecated in favor of bootstrap.sh

- Add scripts/bootstrap.sh (488 lines): Unified entrypoint supporting multiple hardware types (Proxmox/Docker VMs/Pi)
- Create scripts/lib/ modular library system:
  - detection.sh: OS/hardware/container detection (362 lines)
  - fingerprint.sh: System fingerprinting and inventory (494 lines)
  - network.sh: IP configuration and VLAN placement (356 lines)
  - proxmox.sh: PVE post-install automation (453 lines)
  - validation.sh: Comprehensive pre-flight checks (510 lines)
- Add validation tools: validate-node.sh, onboarding.sh, pi_init.sh
- Deprecate scripts/day0bootstrap.sh with graceful redirect wrapper
- Document architecture in scripts/README.md (495 lines) and PROXMOX-COMPARISON.md
- Update SOP-002 with new bootstrap workflow
- Add nodes/watchtower/compose.yaml (Raspberry Pi 5 stack)

Migration: Existing day0bootstrap.sh users automatically redirected to new system after 5-second warning. No manual intervention required.

Ref: Infrastructure automation modernization per active-tasks.md
2026-04-12 22:48:19 -04:00

7.1 KiB

Proxmox Post-Install Feature Comparison

Community Script vs. Bootstrap.sh

This document compares the tteck/community-scripts ProxmoxVE post-install script with our unified bootstrap.sh implementation.


Features Now Implemented

Repository Management

Feature Community Script bootstrap.sh Status
Disable enterprise repo COMPLETE
Enable no-subscription repo COMPLETE
Configure Ceph repos COMPLETE
Add pvetest repo (disabled) COMPLETE
PVE 8.x (.list format) COMPLETE
PVE 9.x (.sources deb822) COMPLETE

UI Customization

Feature Community Script bootstrap.sh Status
Web UI subscription nag removal COMPLETE
Mobile UI subscription nag removal COMPLETE
Persistent via apt hook COMPLETE

High Availability

Feature Community Script bootstrap.sh Status
Disable HA on single nodes COMPLETE
Auto-detect cluster vs. single COMPLETE
Corosync management COMPLETE

System Maintenance

Feature Community Script bootstrap.sh Status
System update (apt dist-upgrade) ⚠️ PARTIAL
Reboot detection COMPLETE
Interactive prompts N/A (Auto Mode)

🎯 Key Differences

Community Script (Interactive)

  • Mode: Interactive (whiptail menus)
  • Approach: User chooses each action
  • Best For: Manual post-install on fresh Proxmox

bootstrap.sh (Automated)

  • Mode: Automated (sensible defaults)
  • Approach: Auto-detect and apply best practices
  • Best For: Scripted deployments, CI/CD, repeatability

📋 What bootstrap.sh Does for Proxmox

When ./bootstrap.sh --hardware-type proxmox is run:

Phase 1: Detection

✓ Detect Proxmox VE version (8.x or 9.x)
✓ Check cluster status (single node vs. cluster)
✓ Identify current repository configuration

Phase 2: Repository Configuration

✓ Disable pve-enterprise repository
✓ Enable pve-no-subscription repository
✓ Configure Ceph repos (disabled by default)
✓ Add pvetest repository (disabled)
✓ Auto-select .list (PVE 8.x) or .sources (PVE 9.x) format

Phase 3: UI Customization

✓ Remove subscription nag from web UI
✓ Remove subscription nag from mobile UI
✓ Create apt hook to persist after updates

Phase 4: High Availability

✓ Detect single-node setup → Disable HA services (saves resources)
✓ Detect cluster → Keep HA services enabled
✓ Manage pve-ha-lrm, pve-ha-crm, corosync

Phase 5: Validation

✓ Verify PVE version supported
✓ Check repository configuration
✓ Validate cluster status
✓ Check for required reboot

🚀 Usage Examples

Basic Proxmox Bootstrap

# Auto-detect and configure Proxmox host
./bootstrap.sh --hardware-type proxmox --target-ip 10.0.0.201

Output:

[PHASE 1] System Detection
  Auto-detected hardware type: proxmox
  
[PHASE 3] Package Installation
  [⚙] Installing Proxmox-specific packages...
  [✓] proxmoxer installed
  
=== PROXMOX POST-INSTALL CONFIGURATION ===
Version: 8.2.4
Mode: auto

[⚙] Disabling Proxmox enterprise repository...
  [✓] Enterprise repository disabled

[⚙] Enabling Proxmox no-subscription repository...
  [✓] No-subscription repository enabled

[⚙] Configuring Ceph package repositories...
  [✓] Ceph repositories configured (disabled)

[⚙] Adding pvetest repository (disabled)...
  [✓] pvetest repository added (disabled)

[⚙] Disabling subscription nag dialog...
  [✓] Subscription nag disabled (clear browser cache)

[⚙] Single-node setup detected
[⚙] Disabling high availability services...
  [✓] HA services disabled

[✓] Proxmox repository configuration complete
==========================================

Next Steps:
  1. Clear browser cache (Ctrl+Shift+R)
  2. Reboot if kernel was updated
  3. Configure storage/networking in web UI

Standalone Proxmox Configuration (Existing Host)

# Source library and run post-install only
source lib/proxmox.sh
run_proxmox_post_install "auto"

Validate Proxmox Configuration

source lib/proxmox.sh
validate_proxmox_config

Output:

[⚙] Validating Proxmox configuration...
  [✓] PVE version: 8.2.4
  [✓] No-subscription repository configured
  [✓] Enterprise repository disabled
  [✓] Standalone node
[✓] Proxmox validation passed

🔍 Technical Implementation

Subscription Nag Removal

Web UI (proxmoxlib.js):

// Patches data.status check
// Before: if (!data.status || data.status !== 'active')
// After:  if (data.status || data.status !== 'NoMoreNagging')

Mobile UI (index.html.tpl):

// Injects MutationObserver to remove subscription dialogs/cards
function removeSubscriptionElements() {
  // Remove dialogs with subscription text
  // Remove cards without buttons containing subscription text
}

Persistence (apt hook):

# /etc/apt/apt.conf.d/90-pve-no-nag
DPkg::Post-Invoke { "/usr/local/bin/pve-remove-nag.sh"; };

HA Detection Logic

# Count cluster nodes
cluster_nodes=$(pvesh get /nodes --output-format=json | jq -r 'length')

if [ "$cluster_nodes" -eq 1 ]; then
    # Single node → disable HA services
    systemctl disable --now pve-ha-lrm pve-ha-crm corosync
else
    # Multi-node cluster → keep HA enabled
    echo "HA services left enabled"
fi

Repository Format Detection

major_version=$(get_pve_major_version)

if [ "$major_version" == "9" ]; then
    # PVE 9.x uses deb822 .sources format
    cat >/etc/apt/sources.list.d/proxmox.sources <<EOF
Types: deb
URIs: http://download.proxmox.com/debian/pve
Suites: trixie
Components: pve-no-subscription
EOF
else
    # PVE 8.x uses traditional .list format
    echo "deb http://download.proxmox.com/debian/pve bookworm pve-no-subscription" \
        > /etc/apt/sources.list.d/pve-no-subscription.list
fi


🎓 Lessons Learned

  1. Idempotency Is Critical: All operations can be safely re-run without side effects
  2. Version Detection Matters: PVE 8.x vs. 9.x have different repository formats
  3. HA Context Awareness: Single-node setups don't need HA services (wastes resources)
  4. Persistence Mechanisms: Apt hooks ensure UI patches survive widget updates
  5. Non-Interactive Design: Automation requires sensible defaults, not user prompts

Last Updated: 2026-04-12
Version: 4.0.0 (aligned with bootstrap.sh)