Dokumentation
Installieren. Bedienen. Prüfen.
Deutscher Einstieg und vollständige Befehls- und Konfigurationsreferenz aus den Repository-READMEs.
Proxmox Manager
Sprache: English | Deutsch
Proxmox Manager verwaltet Proxmox-VMs und -Container mit einem eigenständigen Bash-Skript. Die optionale Speicher- und Wartungsoberfläche verwendet Python 3 und die Standardbibliothek; der Bash-Kern kann ohne sie installiert werden. Die vollständige Befehls- und Konfigurationsreferenz steht im englischen README.
Installation
Auf einem Proxmox-Host als Administrator aus einem passenden Checkout:
git clone https://github.com/TimInTech/proxmox-manager.git
cd proxmox-manager
./install_dependencies.sh
Der Installer fragt interaktiv nach dem optionalen Modul und installiert ohne Terminal standardmäßig nur den Kern. Zur ausdrücklichen Installation des Moduls:
./install_dependencies.sh --with-maintenance
pman --maintenance
Die Oberfläche gibt es auf Deutsch (Standard) und Englisch. Im Terminal fragt der
Installer zuerst (Language / Sprache [de/en]); ohne Terminal gibst du
--lang en oder --lang de an. Die Wahl steht in /etc/pman/language und bleibt bei
Updates erhalten; PMAN_LANG=en pman --maintenance überschreibt sie für einen Lauf.
Der Installer installiert keine zusätzlichen APT-Pakete. Für die Oberfläche ist
Python 3.9 oder neuer mit curses sowie ein UTF-8-Terminal erforderlich.
Wartungsoberfläche
M oder m öffnet im Hauptmenü die Host-Wartung; im Aktionsmenü eines Gastes
öffnet dieselbe Taste die Wartung für genau den gewählten CT oder die VM.
Pfeiltasten wählen eine Aktion, Enter startet eine Diagnose oder öffnet Details.
Bild auf/ab blättert die Ausgabe, Esc führt zurück oder bricht eine Bestätigung
ab, und q beendet die
Ansicht. Tab wechselt beim CT den Scanpfad. Die Anzeige passt sich dem Terminal
an und berücksichtigt NO_COLOR.
Host-Wartungsmenü
Die eigenen Adapter zeigen unter anderem Storage, Dateisysteme und SMART-Daten.
CT und VM bieten ausschließlich auf den gewählten Gast bezogene Diagnosen und
bestätigungspflichtiges TRIM; für Debian-/Ubuntu-CTs ist auch eine Bereinigung
des APT-Paketcache verfügbar. Gestoppte Gäste werden nicht automatisch gestartet.
Jede Änderung verlangt eine eigene Bestätigung; --force umgeht sie nicht.
Ein Abbruch laufender Änderungen ist kein Rollback.
Das Host-Menü enthält außerdem die Proxmox VE Helper-Scripts (Community)
(https://community-scripts.org, MIT-Lizenz, Repository
community-scripts/ProxmoxVE). Acht ausgewählte Werkzeuge laufen als fremder
Code, der weder von pman noch von Proxmox stammt, mit eigenen interaktiven
Dialogen; sie können Host-Einstellungen oder dort ausgewählte Gäste ändern. Die
Werkzeuge sind nach Absicht gruppiert, und jedes trägt seine Gefahrenstufe als
Text: [LESEN] (Diagnose; Disk Health installiert nur auf Nachfrage Pakete), [ÄNDERT] (verändert Host oder Gäste) oder
[LÖSCHT] (entfernt Daten oder Pakete, kein Papierkorb); Farbe ist nur ein
zusätzlicher Hinweis. Vor dem Bestätigungsschirm prüft das Modul den aktuellen
Upstream und lädt die festgelegte Revision herunter. Der Schirm zeigt die genaue
Quell-URL, den Befehl, den Hinweis „läuft als root auf diesem Host“ sowie
Revision und Prüfsumme. Mit v lässt sich das geprüfte Skript ansehen; nach j
werden genau diese Bytes gestartet. Die Prüfung wird unmittelbar vor dem Start
wiederholt. Geänderte, fehlende oder nicht erreichbare Quellen verhindern den
Start; die Meldung nennt dann die Datei sowie geprüfte und aktuelle Revision.
Die Prüfung und die Downloads können bei Zeitlimits im ungünstigsten Fall etwa
eine Minute dauern; die Oberfläche ist währenddessen blockiert. Die optionale
Upstream-Telemetrie wird nicht bereitgestellt. Auswirkungen vor der Bestätigung
sorgfältig prüfen.
Darstellung: NO_COLOR=1 schaltet jede Farbe ab, PMAN_ASCII=1 ersetzt Linien-
und Pfeilzeichen durch ASCII (automatisch auch bei TERM=linux), und
PMAN_HYPERLINKS=1|0 erzwingt klickbare OSC-8-Links oder schaltet sie ab (die
URL steht immer auch als Klartext da).
Bekannte Grenzen: Ein UTF-8-Terminal wird benötigt. Ein laufender CT-Scan kann bis zu 55 Sekunden weiterlaufen, auch wenn die Oberfläche den Abbruch angefordert hat. Community-Helper zeigen eigene Dialoge und ihre erneute Live-Quellprüfung kann während der Netzwerkanfrage kurzzeitig die Oberfläche blockieren. Ein Abbruch ist kein Rollback. Details stehen in docs/maintenance.md.
Deinstallation des Moduls
./install_dependencies.sh --uninstall-maintenance
Der Bash-Kern bleibt installiert; private Diagnosezustände bleiben erhalten. Für den Rückweg auf die vorherige Modulversion nutze im passenden Checkout:
./install_dependencies.sh --rollback-maintenance
Tests
Auf einem Entwicklungsrechner ohne Proxmox-Host laufen die Mock- und TUI-Tests mit:
python3 -B -m unittest discover -s tests/maintenance
bash tests/run.sh
Die echten Proxmox-Aktionen brauchen einen Testhost. Siehe Wartungsdokumentation.
Weitere Nutzung
pman öffnet die VM-/CT-Tabelle, pman --list und pman --json geben den
Bestand aus. pman --health zeigt den Zustand und pman --check führt den
optionalen Alarm-Check aus. Konfiguration, Befehle und Beispiele erläutert das
englische README. Lizenz: MIT.
📖 Community & Tutorials
Check out how others are using proxmox-manager:
- 🇵🇱 Proxmox Manager – Co to jest, jak działa, instalacja i obsługa A detailed walkthrough and review by askomputer.pl featuring usage examples and screenshots (in Polish).
📸 Screenshots
| Main menu — VM/CT table | Action menu — status with health line |
|---|---|
| Live status for all VMs & containers | Start, stop, console, snapshots; Status adds CPU / MEM / DISK |
Health view — pman --health |
Cron check — pman --check |
| CPU / MEM / DISK %, uptime and level per guest | WARN → RESOLVED with Nagios exit codes |
| ntfy push — web app | E-mail alert |
| Same message on phone, desktop or browser | Plain-text mail via the local sendmail |
Optional maintenance interface — host storage and maintenance menu
🎯 Features
| Feature | Details | |
|---|---|---|
| 🩺 | Health Monitoring | CPU / RAM / disk per guest, uptime and OK / WARN / CRIT — pman --health, key h in the TUI, Health: line in the status action |
| 🔔 | Alerts | pman --check for cron: thresholds, stopped onboot guests, unexpected stops and failed tasks; ntfy / e-mail only when something changes (opt-in) |
| 📋 | List & Status | All VMs and containers with live status — [+] running · [-] stopped · [~] paused · [?] unknown |
| ⚡ | Start / Stop / Restart | Confirmation prompt for destructive actions. Proxmox error details on failure. Stop is a graceful shutdown (ACPI / guest agent); Proxmox force-stops the guest after the configurable timeout |
| 🖥️ | Console Access | LXC shell via pct enter or QEMU terminal via qm terminal. Verifies running state before entering |
| 🌐 | IP Address Lookup | Shows current IPv4 addresses for running VMs and CTs — VM via QEMU Guest Agent, CT via pct exec |
| 📦 | Snapshot Management | List, create, rollback, delete — with name validation and snapshot preview before destructive actions |
| 🖱️ | SPICE Integration | Enable SPICE for VMs and retrieve .vv connection files. Auto-launches virt-viewer when installed |
| 🤖 | Automation-Ready | --json output, --filter by status, --name ERE filter, --force mode, structured logging via LOG_FILE |
| ⚙️ | Config File | Persistent allowlisted defaults via /etc/pmanrc or ~/.pmanrc — CLI flags always win |
🔔 Quick start: alerts in 3 steps
Run as root on the Proxmox node after installing pman.
1 — Pick a channel in /etc/pmanrc
touch /etc/pmanrc && chmod 600 /etc/pmanrc
cat >>/etc/pmanrc <<'EOF'
NTFY_URL="https://ntfy.sh/pman-alerts-CHANGE-ME" # hard-to-guess topic name
# HEALTH_MAIL_TO="admin@example.com" # optional, uncomment once sendmail works
EOF
Anyone who knows a public ntfy.sh topic can read it — treat the name like a password, or use a protected topic with a token. For e-mail, most home servers need a smarthost first — see relaying through an external SMTP provider.
2 — Send a test message
--test-notify uses every channel configured in /etc/pmanrc. Leave the
e-mail line commented out until sendmail delivers, otherwise the test fails on
the mail step instead of proving ntfy works.
pman --test-notify
pman --check --dry-run; echo "exit $?" # what would be sent, nothing saved
Subscribe to the same topic in the ntfy
app or at https://ntfy.sh/<your-topic>
in the browser; the test message shows up there.
3 — Let cron check every 5 minutes
cat >/etc/cron.d/pman-health <<'EOF'
PATH=/usr/sbin:/usr/bin:/sbin:/bin
*/5 * * * * root /usr/local/bin/pman --check >/dev/null 2>&1
EOF
The first run only records a baseline. From then on, you get one message per
change — new or escalated problems, improvements and RESOLVED:
Details, thresholds and limitations: Health monitoring & alerts.
🏗️ How It Works
A single proxmox-manager.sh script — no build step, no service, config
optional. Runs on-demand as root directly on the Proxmox VE node; alerts run
from cron.
User / Automation cron (*/5)
│ │
▼ ▼
┌───────────────────────────────────────────────────────┐
│ pman (proxmox-manager.sh) │
│ │
│ ┌──────────┐ ┌─────────────┐ ┌──────────────────┐ │
│ │ --list │ │ interactive │ │ --health │ │
│ │ --json │ │ TUI │ │ --check ─────────┼──┼──▶ ntfy / e-mail
│ │ --filter │ │ │ │ state: /var/lib │ │ (on change)
│ └────┬─────┘ └──────┬──────┘ └────────┬─────────┘ │
└───────┼───────────────┼──────────────────┼────────────┘
│ │ │
▼ ▼ ▼
┌───────────────────────────────────────────────────────┐
│ qm (VMs) · pct (CTs) · pvesh (usage, tasks) │ ← Proxmox CLI
└───────────────────────────────────────────────────────┘
│
▼
┌───────────────────────────────────────────────────────┐
│ Proxmox VE Host (local) │
│ QEMU Virtual Machines · LXC Containers │
└───────────────────────────────────────────────────────┘
✅ Core: no network calls (unless alerts are configured) · ✅ No background process · ✅ Bash ≥ 4.0 · ✅ PVE 7.x / 8.x / 9.x
🚀 Installation
Requirements: Proxmox VE host · Bash ≥ 4.0 · Root privileges · qm / pct
/ pvesh and python3 (all bundled with PVE) · optional: sendmail (e.g.
postfix) for e-mail alerts
Step 1 — Clone
git clone https://github.com/TimInTech/proxmox-manager.git
cd proxmox-manager
Step 2 — Run directly
chmod +x proxmox-manager.sh
./proxmox-manager.sh
Step 3 — Or register as pman system-wide (optional, requires root)
./install_dependencies.sh
The installer defaults to the core in noninteractive mode and asks whether to add
the maintenance module in a terminal. It does not automatically install optional
packages such as virt-viewer, jq or development tools.
./install_dependencies.sh --with-maintenance
pman --maintenance
The maintenance interface speaks German (default) or English. A terminal
installation asks first (Language / Sprache [de/en]); without a terminal pass
--lang en or --lang de. The choice is stored in /etc/pman/language and kept on
upgrades; PMAN_LANG=en pman --maintenance overrides it for one run.
Installs an atomic, root-owned copy at /usr/local/bin/pman so later edits to
the checkout cannot change the privileged executable.
🛠️ Usage
| Command | Description |
|---|---|
pman |
Interactive TUI — VM/CT table with full action menus |
pman --list |
Plain-text table output — useful for logging or quick checks |
pman --json |
Machine-readable JSON array for automation & jq |
pman --filter running |
Filter output by status: running | stopped | paused |
pman --name web |
Filter by VM/CT name (ERE substring-match; combinable with --filter) |
pman --force |
Skip supported core confirmation prompts; maintenance confirmations remain mandatory |
pman --timeout 30 |
Graceful shutdown timeout before force stop, in seconds (default: 60) |
pman --no-clear |
Don't clear screen in interactive mode |
pman --once |
Run a single interactive refresh cycle (useful for TTY recording) |
pman --maintenance |
Optional arrow-key storage/maintenance TUI for the host; guest menus open the selected CT/VM |
pman --health |
Health overview: CPU / MEM / DISK %, uptime and level per guest (--list, --json combinable) |
pman --check |
Health check for cron: alerts on changes, exit 0 OK · 1 WARN · 2 CRIT · 3 UNKNOWN |
pman --check --dry-run |
Show the check result and the message that would be sent; nothing is sent or saved |
pman --test-notify |
Send a test message through all configured channels |
pman --version |
Print version and exit |
pman -h, --help |
Show usage information and exit |
Interactive mode
pman
Displays a table of all VMs/containers. Enter a VMID to open the action menu.
[+] running [-] stopped [~] paused [?] unknown
Press h for the health overview · r to refresh · q to quit
Optional maintenance interface
Press M or m in the main menu for host maintenance, or in a guest action
menu for that selected CT or VM. Arrow keys select an action, Enter opens it,
Page Up/Down scrolls output, Esc goes back or cancels a confirmation, and q
exits. Tab switches the CT scan directory. The display adapts to terminal
size and honors NO_COLOR; a UTF-8 terminal is required.
Native diagnostics use the selected scope; native guest changes require explicit
confirmation and never start stopped guests. --force cannot bypass confirmation.
The host-only Proxmox VE Helper-Scripts (Community) menu
(https://community-scripts.org, MIT licence, repository
community-scripts/ProxmoxVE) launches eight selected third-party tools. They
are not written by pman or Proxmox and can change host settings or guests chosen
inside the helper. Tools are grouped by intent and each carries a hazard level
as text: [LESEN] (diagnosis; Disk Health only installs packages if you agree to its prompt), [ÄNDERT] (changes the host or guests) or
[LÖSCHT] (removes data or packages, no recycle bin); colour is only an extra
cue. Before the confirmation screen pman checks the live source and downloads the
pinned revision; the screen shows the exact source URL, the command, the notice
that the script runs as root on this host and the pinned revision and checksum.
v shows the verified script, and exactly those bytes are started after j.
The check is repeated right before launch; changed, missing or unreachable
sources block execution and the message names the file and the reviewed and
current revision. The optional upstream telemetry component is omitted. See
maintenance documentation for limits, source checks,
rollback and removal.
Display options: NO_COLOR=1 removes all colour, PMAN_ASCII=1 replaces box and
arrow glyphs with ASCII (also automatic on TERM=linux), and PMAN_HYPERLINKS=1|0
forces OSC 8 clickable links on or off (the URL is always printed as plain text).
To remove only the optional module, run:
./install_dependencies.sh --uninstall-maintenance
To switch back to the previous installed module release, run:
./install_dependencies.sh --rollback-maintenance
Both operations retain the Bash core. The module may need a UTF-8 terminal. A cancelled CT scan can continue in the guest until its 55-second timeout, and community source checks may block the UI for up to about one minute while the live checks and pinned source downloads wait for their network timeouts. Cancelling a running change is not a rollback; see maintenance documentation.
JSON output
pman --json | jq '.[] | select(.status == "running")'
[
{"id": 100, "type": "VM", "status": "running", "symbol": "[+]", "name": "web-server"},
{"id": 101, "type": "CT", "status": "stopped", "symbol": "[-]", "name": "db-container"}
]
SPICE remote desktop
The SPICE integration generates a .vv connection file for any VM. If
virt-viewer is installed, it is launched
automatically:
# Install virt-viewer (Debian / Proxmox host)
apt install virt-viewer
When virt-viewer is not installed, the path to the generated .vv file is
printed together with the install hint. The SPICE bind address defaults to
127.0.0.1 and can be overridden via PROXMOX_MANAGER_SPICE_ADDR (env var or
~/.pmanrc).
Health monitoring & alerts
pman --health shows every guest on the local node (templates skipped) with
CPU, memory and disk usage, uptime and a health level; --list prints plain
text, --json machine-readable data (null where a value is not available).
The same data backs the h key in the TUI and the Health: line of the status
action.
pman --check is meant for cron. It evaluates:
| Check | Level | Notes |
|---|---|---|
| CPU | WARN / CRIT | Must stay above the threshold for HEALTH_CPU_RUNS runs in a row |
| Memory, disk | WARN / CRIT | Immediately. VM disk usage needs the QEMU guest agent, otherwise n/a |
| (guest stops) | — | CPU / memory / disk alerts of a stopped guest are resolved |
Stopped with onboot=1 |
CRIT | Configured to start at boot but not running (WARN if stopped by a task) |
| Stopped unexpectedly | WARN | Was running at the last check; its latest task is no stop/shutdown/suspend/migrate/destroy/backup |
| Failed task | WARN / CRIT | Any node task that ended not OK since the last run (WARNINGS → WARN) |
Thresholds (percent; 0 disables that level):
| Key | Default | Key | Default |
|---|---|---|---|
HEALTH_CPU_WARN |
85 | HEALTH_CPU_CRIT |
95 |
HEALTH_MEM_WARN |
90 | HEALTH_MEM_CRIT |
95 |
HEALTH_DISK_WARN |
85 | HEALTH_DISK_CRIT |
95 |
HEALTH_CPU_RUNS |
3 | HEALTH_IGNORE_IDS |
(empty) e.g. 105,210 |
A notification is sent only when something changes: new or escalated problems,
improvements and RESOLVED (with duration). All changes of one run go into one
message. The first run only records a baseline, so old failed tasks are not
reported. State is kept in HEALTH_STATE_DIR (default /var/lib/pman, mode
0700); if every channel fails, the unsent changes stay pending and are sent by
the next run. Exit codes: 0 OK · 1 WARN · 2 CRIT · 3 UNKNOWN (usage,
config, lock or pvesh error) — the output is a Nagios-style summary line plus
one line per problem.
ntfy — push to phone/desktop via ntfy (public or self-hosted):
# /etc/pmanrc
NTFY_URL="https://ntfy.sh/pman-alerts-CHANGE-ME" # use a hard-to-guess topic
NTFY_TOKEN_FILE="/etc/pman/ntfy.token" # optional, for protected topics
# store the token in a private file (never inline in pmanrc)
install -d -m 700 /etc/pman
install -m 600 /dev/null /etc/pman/ntfy.token && nano /etc/pman/ntfy.token
The token file and its directory must not be writable by others; a token
requires an https:// URL (http:// plus a token is a configuration error).
E-mail uses the local sendmail (postfix, which PVE installs for its own
notifications, works out of the box when it can relay):
# /etc/pmanrc
HEALTH_MAIL_TO="admin@example.com" # comma separated, no spaces
HEALTH_MAIL_FROM="pman@pve.example.com" # optional
Subject and body match the ntfy message (plain text, Auto-Submitted: auto-generated):
Relaying through an external SMTP provider
Most home servers cannot deliver mail themselves: the provider blocks port 25 or the receiving side rejects a dynamic IP. Postfix then needs a smarthost. The example below uses Gmail submission; any provider works the same way, only host and port change.
1 — Authentication. Providers with two-factor authentication do not accept the account password over SMTP. Create an app password instead (Google: Account → Security → App passwords) and write it to a private file — enter it yourself, so it never ends up in a shell history or a script:
apt install libsasl2-modules # SASL client, not installed by default
umask 077
read -rsp "app password: " P; echo
printf '[smtp.gmail.com]:587 you@example.com:%s\n' "$P" >/etc/postfix/sasl_passwd
unset P
postmap /etc/postfix/sasl_passwd
chmod 600 /etc/postfix/sasl_passwd /etc/postfix/sasl_passwd.db
App passwords are shown in groups of four — enter them without the spaces.
2 — Postfix. sender_canonical rewrites the envelope sender, because
providers only accept mail from the authenticated account:
postconf -e "relayhost = [smtp.gmail.com]:587" \
"smtp_sasl_auth_enable = yes" \
"smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd" \
"smtp_sasl_security_options = noanonymous" \
"smtp_sasl_tls_security_options = noanonymous" \
"smtp_tls_security_level = encrypt" \
"smtp_tls_CAfile = /etc/ssl/certs/ca-certificates.crt" \
"sender_canonical_classes = envelope_sender" \
"sender_canonical_maps = regexp:/etc/postfix/sender_canonical" \
"inet_protocols = ipv4"
echo '/.+/ you@example.com' >/etc/postfix/sender_canonical
echo 'root: you@example.com' >>/etc/aliases && newaliases
systemctl restart postfix
inet_protocols = ipv4 matters on hosts without a working IPv6 route:
otherwise every delivery first fails with Network is unreachable and the mail
sits in the queue. The root alias makes sure Proxmox's own notifications
reach the same mailbox.
3 — Verify. Send a test message and read the log; Debian 13 has no
/var/log/mail.log, postfix logs to the journal:
pman --test-notify
journalctl -t postfix/smtp -n 5 --no-pager # look for status=sent
mailq # should be empty
Common failures: 535 5.7.8 or 534 5.7.9 Application-specific password required means the password is not an app password; status=deferred with
Network is unreachable is the IPv6 case above. Gmail always replaces the
From header with the authenticated account, so identify alerts by their
subject, or send them to a plus address such as you+pman@example.com and
filter on the recipient.
Test the channels, then add the cron job (set PATH, cron's default lacks
/usr/sbin):
pman --test-notify
pman --check --dry-run; echo "exit $?"
# /etc/cron.d/pman-health
PATH=/usr/sbin:/usr/bin:/sbin:/bin
*/5 * * * * root /usr/local/bin/pman --check >/dev/null 2>&1
Limitations: a shutdown from inside a guest has no Proxmox task and is reported as "stopped unexpectedly"; in a cluster, run the cron job on every node (each checks only its own guests); failed tasks are read from the last 200 node tasks.
Configuration
proxmox-manager checks the following files at startup (in this order):
| File | Scope |
|---|---|
/etc/pmanrc |
System-wide (all users) |
~/.pmanrc |
Per-user (overrides system-wide) |
CLI flags are applied last and always win over config file values.
# ~/.pmanrc — example
STOP_TIMEOUT=120 # shutdown timeout before force stop (default: 60)
LOG_FILE="/var/log/proxmox-manager.log" # structured log file (empty = disabled)
PROXMOX_MANAGER_SPICE_ADDR="spice.example.invalid" # SPICE bind address
HEALTH_MEM_WARN=80 # health thresholds, see "Health monitoring & alerts"
NTFY_URL="https://ntfy.sh/pman-alerts-CHANGE-ME"
Configuration files are parsed as data, not executed as shell code. Accepted
keys: STOP_TIMEOUT, LOG_FILE, PROXMOX_MANAGER_SPICE_ADDR,
HEALTH_CPU_WARN, HEALTH_CPU_CRIT, HEALTH_MEM_WARN, HEALTH_MEM_CRIT,
HEALTH_DISK_WARN, HEALTH_DISK_CRIT, HEALTH_CPU_RUNS, HEALTH_IGNORE_IDS,
HEALTH_STATE_DIR, NTFY_URL, NTFY_TOKEN_FILE, HEALTH_MAIL_TO and
HEALTH_MAIL_FROM; anything else is ignored with a warning. Health settings are
validated only by --health, --check and --test-notify, so a typo never
blocks the TUI. Because the file may name alert targets, keep it private: chmod 600 /etc/pmanrc. When enabled, LOG_FILE must be an absolute, non-symlinked
regular file owned by the current user with mode 0600; its parent directory
must also be owner-controlled and not group/world-writable.
Shell Completions
# Bash (system-wide)
sudo cp completions/pman.bash /etc/bash_completion.d/pman
# Zsh
mkdir -p ~/.zsh/completions
cp completions/pman.zsh ~/.zsh/completions/_pman
🔐 Security
- Root required:
qmandpctneed elevated privileges — there's no workaround. - No credentials stored: Relies entirely on Proxmox host authentication.
- Network access: notifications are opt-in. The optional maintenance module
also checks public source metadata and fetches pinned community scripts on
request. The ntfy token is read from a
0600file, passed tocurlvia stdin and never sent over plain http. - CI hardening: ShellCheck on every push · Gitleaks scan for accidental secrets.
📋 Changelog
🆕 v2.14.0 — 2026-10-28
Optional arrow-key storage and maintenance module, scoped CT/VM actions, explicit confirmations, source provenance and daily metadata-only checks.
v2.13.2 — 2026-10-21
Stop is a graceful shutdown (
qm|pct shutdown --timeout --forceStop 1); Proxmox force-stops only after--timeout. Previouslyqm|pct stopcut the power immediately. Tests now cover stop and restart.
v2.13.1 — 2026-09-26
README: health monitoring and alerts with screenshots · SMTP relay setup
v2.13.0 — 2026-09-19
Health view (
--health, keyh) ·--checkfor cron with ntfy / e-mail alerts on changes · exit codes 0/1/2/3 ·--test-notify
v2.12.1 — 2026-09-19
Action and snapshot menus draw a closed frame · README screenshots regenerated
v2.12.0 — 2026-09-19
| Issue | Change |
|---|---|
| #33 | TUI frames aligned by visible width; long guest names grow the NAME column (truncated at terminal width); correct PVE version and compact uptime in the header |
| #31 | Security hardening: config files parsed as allowlisted data (no source), private log files, atomic root-owned pman install, SHA-pinned CI |
| #30 | Snapshot names validated against Proxmox rules; SPICE .vv files use the real bind address/port |
| #28 | New IP info menu item to show current IPv4 addresses for running VMs and CTs |
v2.11.1 — 2026-05-04
| Issue | Change |
|---|---|
| #21 | Full Proxmox stderr written to LOG_FILE; only first line shown on stdout |
| #22 | Config file support: /etc/pmanrc and ~/.pmanrc loaded before CLI flags |
| #23 | Numbered snapshot selection for rollback and delete (free-text fallback) |
| #24 | validate_menu_choice() helper — unified error format for all menu inputs |
| #25 | --name PATTERN flag — ERE substring filter on VM/CT name, combinable with --filter |
| #26 | virt-viewer auto-launched from SPICE info; fallback hint when not installed |
| #28 | New IP info menu item to show current IPv4 addresses for running VMs and CTs |
v2.9.0 — 2026-04-09
--filter STATUS·--timeout SECSwith force-stop fallback ·--forcemode · 29 unit tests · Bash & Zsh shell completions
🧪 Testing
# Lint
shellcheck proxmox-manager.sh
# Unit tests (no real Proxmox needed — uses mock stubs)
tests/run.sh
141 tests covering validate_vmid, validate_snapshot_name, ip_info,
--filter, CLI flags, config parsing, the health view, the --check engine and
notifications (mocked pvesh, curl, sendmail; no network, no root).
🤝 Contributing
Contributions welcome — keep it simple, keep it Bash.
- Fork & create a feature branch:
git checkout -b feat/your-change - Keep external dependencies at zero. Run
shellchecklocally. - Commit with conventional format:
feat(vm): add suspend action - Open a Pull Request.
Do not commit: generated files, scan outputs, binary files, or large test data.
📜 License
MIT License — see LICENSE for full text.