Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 23 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ jobs:
echo "No shell scripts found."
exit 0
fi
shellcheck -x "${files[@]}"
shellcheck -x "${files[@]}" maintenance/pman-maintenance

- name: Download, verify, and run shfmt
env:
Expand All @@ -50,7 +50,28 @@ jobs:
--output "${shfmt_path}"
printf '%s %s\n' "${SHFMT_SHA256}" "${shfmt_path}" | sha256sum --check --strict
chmod 0755 "${shfmt_path}"
"${shfmt_path}" -d proxmox-manager.sh
"${shfmt_path}" -d proxmox-manager.sh install_dependencies.sh maintenance/pman-maintenance tools/build-release.sh

- name: Run tests
run: bash tests/run.sh

maintenance:
name: Maintenance Python ${{ matrix.python }}
runs-on: ubuntu-latest
strategy:
matrix:
python: ['3.9', '3.13']
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6
with:
python-version: ${{ matrix.python }}
- name: Native adapter, source-check and installer tests
run: python3 -B -m unittest discover -s tests/maintenance -v
- name: Build and verify release bundle
run: |
bash tools/build-release.sh dist
cd dist
sha256sum -c SHA256SUMS
5 changes: 4 additions & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,14 @@ jobs:
with:
persist-credentials: false

- name: Build core and optional module assets
run: bash tools/build-release.sh dist

- name: Create GitHub Release
env:
GH_TOKEN: ${{ github.token }}
run: |
gh release create "$GITHUB_REF_NAME" proxmox-manager.sh \
gh release create "$GITHUB_REF_NAME" dist/* \
--verify-tag \
--title "$GITHUB_REF_NAME" \
--notes ""
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,8 @@ CLAUDE.md
# Misc local artifacts
*.bak
*.tmp

# Optional maintenance Python caches and release assets
__pycache__/
*.py[cod]
dist/
21 changes: 21 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,27 @@ Versions follow [Semantic Versioning](https://semver.org/).

---

## [2.14.0] - 2026-10-27

### Maintenance module 1.0.3

- Refine the optional maintenance TUI with responsive action/detail views,
clearer status and contextual keys, safe confirmation paging, and terminal
restoration coverage.
- Check community source metadata before confirmation; pinned hashes and a
second live check remain required immediately before launch.
- Fix community back-entry details and discard keys queued while a worker runs.

- Add an optional Python/curses storage and maintenance module with a small Bash
dispatcher (`--maintenance`, main-menu `m`, and guest-menu `m`).
- Add host storage/SMART diagnostics, scoped CT/VM adapters, confirmed TRIM and
Debian/Ubuntu CT package-cache cleanup. No automatic guest starts or broad cleanup.
- Install the module independently with versioned atomic deployment and rollback;
base installation no longer installs unrelated optional packages automatically.
- Track declared Community Scripts reference revisions with a daily metadata-only
checker. Execute native local adapters, never downloaded upstream code.
- Add independent module bundles/checksums and Python/installer regression tests.

## [Unreleased]

## [2.13.2] - 2026-10-21
Expand Down
94 changes: 94 additions & 0 deletions README.de.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
# Proxmox Manager

**Sprache: [English](README.md) | 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](README.md).

## Installation

Auf einem Proxmox-Host als Administrator aus einem passenden Checkout:

```bash
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:

```bash
./install_dependencies.sh --with-maintenance
pman --maintenance
```

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`.

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 ausgewählte **Community Scripts**. Sie laufen als
Upstream-Code mit eigenen interaktiven Dialogen und können Host-Einstellungen
oder dort ausgewählte Gäste ändern. Vor der Bestätigung prüft das Modul den
aktuellen Upstream; vor dem Start prüft es erneut und kontrolliert die Git-Blob-Prüfsummen der festgelegten
Revisionen. Geänderte, fehlende oder nicht erreichbare
Quellen verhindern den Start. Die erneute Prüfung und 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.

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](docs/maintenance.md).

## Deinstallation des Moduls

```bash
./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:

```bash
./install_dependencies.sh --rollback-maintenance
```

## Tests

Auf einem Entwicklungsrechner ohne Proxmox-Host laufen die Mock- und TUI-Tests
mit:

```bash
python3 -B -m unittest discover -s tests/maintenance
bash tests/run.sh
```

Die echten Proxmox-Aktionen brauchen einen Testhost. Siehe [Wartungsdokumentation](docs/maintenance.md).

## 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](README.md). Lizenz: [MIT](LICENSE).
77 changes: 68 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
**Language: English | [Deutsch](README.de.md)**

<!-- markdownlint-disable MD033 MD041 -->
<div align="center">

Expand All @@ -8,16 +10,21 @@
║ ██████╔╝ ██╔████╔██║ ███████║ ██╔██╗ ██║ ║
║ ██╔═══╝ ██║╚██╔╝██║ ██╔══██║ ██║╚██╗██║ ║
║ ██║ ██║ ╚═╝ ██║ ██║ ██║ ██║ ╚████║ ║
║ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═══╝ v2.13.2 ║
║ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═══╝ v2.14.0 ║
║ ║
║ Proxmox VM/CT Manager · Single Bash · No Dependencies ║
╚══════════════════════════════════════════════════════════╝
```

**Single-file Bash tool for managing Proxmox VMs and containers.**
No daemons. No agents. No dependencies beyond what ships with Proxmox VE.
The core needs no daemon or guest agent installation and no dependencies beyond
what ships with Proxmox VE. The optional maintenance module adds a daily, disableable
public source-metadata check; its diagnostic and maintenance actions use local commands.

**New in v2.14.0:** optional storage and maintenance TUI (Python standard library),
installed separately with `--with-maintenance`. See [maintenance module](docs/maintenance.md).

**New in v2.13.2:** ⚡ **Stop** now shuts guests down cleanly (`qm|pct shutdown`,
**v2.13.2:** ⚡ **Stop** now shuts guests down cleanly (`qm|pct shutdown`,
force stop only after the timeout) instead of pulling the plug.
**v2.13.0:** 🩺 health view per guest and 🔔 ntfy / e-mail alerts from a
cron check — [set up alerts in 3 steps](#-quick-start-alerts-in-3-steps).
Expand Down Expand Up @@ -170,7 +177,7 @@ from cron.
└───────────────────────────────────────────────────────┘
```

> ✅ No network calls (unless alerts are configured) · ✅ No background process ·
> ✅ Core: no network calls (unless alerts are configured) · ✅ No background process ·
> ✅ Bash ≥ 4.0 · ✅ PVE 7.x / 8.x / 9.x

---
Expand Down Expand Up @@ -201,6 +208,15 @@ chmod +x proxmox-manager.sh
./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.

```bash
./install_dependencies.sh --with-maintenance
pman --maintenance
```

Installs an atomic, root-owned copy at `/usr/local/bin/pman` so later edits to
the checkout cannot change the privileged executable.

Expand All @@ -215,10 +231,11 @@ the checkout cannot change the privileged executable.
| `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 all confirmation prompts (for unattended scripts) |
| `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 |
Expand All @@ -240,6 +257,42 @@ Displays a table of all VMs/containers. Enter a VMID to open the action menu.

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 Community Scripts menu launches selected upstream tools, which may
change host settings or guests chosen inside the helper. Before confirmation it
checks the live source; it repeats the check and verifies pinned Git blob hashes
before launch. Changed, missing or unreachable sources block execution. The
optional upstream telemetry component is omitted. Review the shown impact before
confirming. See [maintenance documentation](docs/maintenance.md) for limits,
source checks, rollback and removal.

To remove only the optional module, run:

```bash
./install_dependencies.sh --uninstall-maintenance
```

To switch back to the previous installed module release, run:

```bash
./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](docs/maintenance.md).

### JSON output

```bash
Expand Down Expand Up @@ -490,17 +543,23 @@ cp completions/pman.zsh ~/.zsh/completions/_pman
- **Root required:** `qm` and `pct` need elevated privileges — there's no
workaround.
- **No credentials stored:** Relies entirely on Proxmox host authentication.
- **No outbound traffic unless notifications are configured:** alerts via ntfy /
e-mail are opt-in; the ntfy token is read from a `0600` file, passed to `curl`
via stdin and never sent over plain http.
- **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 `0600` file, passed to `curl` via stdin
and never sent over plain http.
- **CI hardening:** ShellCheck on every push · Gitleaks scan for accidental
secrets.

---

## 📋 Changelog

### 🆕 [v2.13.2](CHANGELOG.md) — 2026-10-21
### 🆕 [v2.14.0](CHANGELOG.md) — 2026-10-27

> Optional arrow-key storage and maintenance module, scoped CT/VM actions,
> explicit confirmations, source provenance and daily metadata-only checks.

### [v2.13.2](CHANGELOG.md) — 2026-10-21

> **Stop** is a graceful shutdown (`qm|pct shutdown --timeout --forceStop 1`);
> Proxmox force-stops only after `--timeout`. Previously `qm|pct stop` cut the
Expand Down
2 changes: 1 addition & 1 deletion completions/pman.bash
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ _pman() {
prev="${COMP_WORDS[COMP_CWORD-1]}"
}

local all_flags="--list --json --filter --name --no-clear --once --timeout --force --health --check --dry-run --test-notify --version --help"
local all_flags="--list --json --filter --name --no-clear --once --timeout --force --maintenance --health --check --dry-run --test-notify --version --help"

case "$prev" in
--filter)
Expand Down
1 change: 1 addition & 0 deletions completions/pman.zsh
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ _pman() {
'--timeout[Shutdown timeout in seconds before force stop]:seconds:(10 30 60 120 300)' \
'--name[Filter by VM/CT name (ERE substring-match)]:pattern:' \
'--force[Skip all confirmation prompts]' \
'--maintenance[Open optional host maintenance module]' \
'--health[Show CPU/memory/disk health of local VMs/CTs]' \
'--check[Run health checks for cron (exit 0/1/2/3)]' \
'--dry-run[With --check: print result and message, send nothing]' \
Expand Down
Loading
Loading