Per the 2026-08-15 skills.sh and autoskills.sh scans, both flagged wordpress/agent-skills' wp-plugin-development module (Automattic-origin, now WordPress-org-hosted) as high-value source material for iWP's plugin skill: nonce+capability dual-check discipline, late escaping, prepared SQL, cron idempotency, and uninstall-vs-deactivation guardrails. Adapted (not copied) against real iWP plugin code in wp-plugins/: - nonce+capability must-both framing, cited against class-iwp-cache-db-cleanup.php's actual AJAX handler - late-escaping and wp_unslash()/explicit-key superglobal reading - %i identifier-placeholder version gate (WP 6.2+, most iWP plugins floor at 6.0 or lower) - new "Admin settings" section documenting the real Settings-API vs. AJAX-dashboard split across the suite, since the source's generic Settings-API-first prescription doesn't match roughly half of iWP's plugins - new cron idempotency section citing the existing wp_next_scheduled() guard already used consistently in iwp-cache/iwp-woosales/iwp-booking - new uninstall-vs-deactivation section flagging that only 3 of ~15 plugins ship uninstall.php despite most creating options/tables - new release-packaging checklist tied to iWP's actual IWP_Updater version-wiring convention (header/constant/updater param must agree) Provenance noted inline with source URL. Left out the source's generic architecture/Settings-API prescription and its detect_plugins.mjs script (skill's house style is prose-only, no bundled scripts). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
11 KiB
name: proxmox-admin description: Use when administering a Proxmox VE host or cluster via CLI (qm, pct, pvesm, pvecm, pveam, pvesh) — inspecting, creating, or mutating VMs, containers, storage, networking, or cluster state. Safety-first: read-only discovery and explicit target validation before any mutating command, a destructive-command tier list, and real gotchas from hands-on fleet use (reset-vs-reboot tradeoff, Tailscale hostname collisions, storage free-space checks). license: MIT source: adapted from https://github.com/bastos/skills/tree/main/proxmox-admin (MIT) — command taxonomy and CLI coverage — plus this fleet's own direct hands-on Proxmox operations across two hosts, which supplied the safety framing, the real gotchas below, and a correction to the source's quick-reference style (see "Why this skill differs from the source" at the bottom)
Proxmox VE Administration
Proxmox VE is a server virtualization platform built on Debian, managing
KVM virtual machines (qm) and LXC containers (pct) plus storage
(pvesm), clustering (pvecm), templates (pveam), and the API shell
(pvesh). This skill covers CLI-based administration.
Not for: Web UI-only workflows (use the CLI equivalents below and in
references/command-reference.md).
Fleet-specific values (actual VMIDs, storage pool names, bridge/VLAN
IDs, node names) live in this fleet's own docs/server-*.md files, not
here. Every command below uses a placeholder (<vmid>, <node>,
<storage>, <bridge>) — resolve the real value from live discovery
commands or fleet docs before running anything, never by guessing or
reusing an example number from this file or from upstream documentation.
SAFETY FIRST — the order every task follows
- Read-only discovery first, always. Before touching a single VM or container, know what actually exists and what state it's in.
- Validate the target explicitly. Never assume a VMID, node name, or
storage name is correct — confirm it via
qm config/pct config/qm listimmediately before acting on it, every time, even if you "already know" the ID from earlier in the conversation. - Know which tier a command is in before running it. Destructive-tier commands (see below) should never run unattended — expect to be blocked by this environment's own permission classifier, and treat that as correct behavior to work with, not around.
Read-only discovery commands (run these before anything else)
qm list # all VMs on this node: ID, name, status
qm config <vmid> # full config of one VM — confirm identity before acting
qm status <vmid> # current run state
pct list # all containers on this node
pct config <ctid> # full config of one container
pct status <ctid>
pvesm status # storage pools: type, active, TOTAL/USED/AVAIL
pvecm status # cluster quorum/membership (no-op, harmless, on single-node too)
pvecm nodes # cluster node list
pvesh get /cluster/resources # everything, via the API shell — useful for cross-node views
Run the relevant subset of these before every task in this skill, not just once at the start of a session — state changes, and a VMID that was stopped five minutes ago may be running now.
Never trust a VMID or hostname without confirming it first
qm list gives you IDs and names; qm config <vmid> gives you the full
picture (disks, storage backing, network, memory). Always run qm config <vmid> (or pct config <ctid>) immediately before any mutating
command against that ID, even if the ID was already established earlier
in the same task — configs can change between when you last checked and
when you act, and a copy-pasted or misremembered ID silently targeting
the wrong guest is a much worse failure mode than a few extra seconds of
discovery.
The Tailscale hostname-collision gotcha
Confirmed real risk, hit twice in this session across the vulture
and ginger hosts: a bare Tailscale MagicDNS hostname (e.g. ssh <hostname>) can resolve to the wrong physical host if there's a
stale or duplicate device name registered in the tailnet. This is
dangerous specifically because it fails silently — the SSH connection
succeeds, a shell prompt comes back, and everything looks normal; you
just end up running Proxmox commands against a different host's guests
than the one you meant.
Before running any command against what you believe is a specific host (and especially before anything in the destructive tier below), verify the connection actually went where you think:
ssh -v <host> 2>&1 | grep "Connecting to"
If a hostname's identity is ever in doubt, skip MagicDNS entirely and connect by the host's direct Tailscale IP instead — an IP can't collide the way a device name can.
Snapshot vs. backup — know which one you need
These are not interchangeable, and confusing them is a common source of false confidence before a destructive operation:
- Snapshot (
qm snapshot,qm rollback,qm listsnapshot,qm delsnapshot) — fast, live, stored on the same storage backend as the disk it snapshots. Good for "undo the last five minutes of change" during an upgrade or config edit. Does not protect you if the underlying storage itself fails, fills up, or gets deleted — the snapshot dies with it. - Backup (
vzdump, restored viaqmrestore/pct restore) — a full archive, ideally written to storage genuinely separate from the guest's own disk. Slower, but survives storage-level failure and is what you actually want before anything in the destructive tier below.
Rule of thumb: before any destructive-tier command, you want a real backup on separate storage, not just a same-storage snapshot. A snapshot is a convenience for reversible experiments, not a safety net for irreversible ones.
Reset vs. reboot — the real tradeoff learned this session
qm reboot <vmid>sends a graceful ACPI shutdown-then-restart request into the guest. If the guest is hung, has no ACPI daemon running, or is otherwise unresponsive, this can hang or time out waiting indefinitely — it depends entirely on the guest cooperating.qm reset <vmid>is a hard reset — functionally identical to yanking power. It was used exactly once this session, deliberately, as the real fallback whenrebootwasn't a safe option — but only after first confirming the filesystems inside the guest were already cleanly unmounted. A hard reset against a guest with dirty/mounted filesystems risks the same corruption a real power loss would.
Do not reach for reset just because reboot seems slow. Check what
the guest is actually doing first — console (qm monitor <vmid>), guest
agent (qm agent <vmid> ping), or a direct login — and only escalate to
a hard reset once you've confirmed a clean-unmount state (or have
independently decided the guest's disk state doesn't matter, e.g. it's
about to be destroyed anyway).
Storage checks before any disk-affecting operation
pvesm status reports both which storage pools exist and their
free space (TOTAL/USED/AVAIL columns) — check both, not just
"does the storage exist." This matters concretely for restores: this
fleet's real VM disks run 200GB+, and a large qmrestore can fail
partway through — or silently fill the target storage and start
affecting other guests sharing it — if free space wasn't checked first.
Confirm pvesm status shows enough headroom on the target storage
before starting any restore, clone, or disk-resize operation, not just
before the operation you're focused on.
Destructive-command tier list — expect to be blocked, and that's correct
This environment's own permission classifier already blocks
qmrestore and other VM-creating/mutating commands, requiring explicit
human confirmation before they run. This is real, enforced behavior in
this session's environment, not a hypothetical policy. Treat it as a
guardrail to design around, not a friction to route past — if a
destructive-tier command gets blocked, stop, explain to the human
exactly what the command would do and why it's in this tier, and let
them decide. Do not look for an equivalent path that avoids the
prompt (a raw pvesh API call doing the same mutation, hand-editing
/etc/pve/qemu-server/<vmid>.conf directly, chaining lower-privilege
commands to reach the same end state) — that defeats the guardrail's
purpose rather than satisfying it.
Never run these without explicit human confirmation first:
- Any
*destroy*:qm destroy,pct destroy(with or without--purge) — deletes the guest and its disks, generally unrecoverable without a separate backup - Any restore that creates or overwrites a guest:
qmrestore,pct restore - Any storage mutation:
pvesm add,pvesm remove - Any cluster mutation:
pvecm create,pvecm add,pvecm delnode,pvecm expected(force-quorum — a single-node recovery action with real risk of split-brain if used carelessly on a healthy cluster) - Any migration:
qm migrate,pct migrate— moves a guest between nodes, can fail mid-flight, and affects a second node's state qm template <vmid>— converting a VM to a template is irreversibleqm reset <vmid>— lower severity than destroy, but still surface it given the hang-vs-corruption tradeoff above; confirm clean-unmount status even where the environment doesn't hard-block it- Any bulk/loop pattern (batch-create N containers, batch-destroy, scripted mass reconfiguration) — higher risk than the single-target equivalent because the blast radius multiplies silently and a mid-loop failure can leave a mix of applied and unapplied state
Generally fine to run directly (read-only or narrowly-scoped,
reversible): qm list/config/status, pct list/config/status,
pvesm status, pvecm status/nodes, pvesh get ..., qm agent <vmid> ping/get-osinfo, qm start/shutdown/stop on a guest whose
identity you've just confirmed, and snapshot creation (still confirm the
target first — a snapshot against the wrong VMID is a wasted, confusing
action even if not a destructive one).
Full command reference
See references/command-reference.md for the complete qm/pct/
pvesm/pvecm/pveam/backup/troubleshooting command tables, adapted
from the upstream source with all example VMIDs, storage names, and
bridge names replaced by placeholders.
Why this skill differs from the source
The upstream bastos/skills@proxmox-admin skill this was adapted from is
a solid 427-line command taxonomy, but it presents everything —
including qm destroy, pct destroy, storage mutation, and cluster
operations — in flat quick-reference style with no confirmation, target-
validation, or backup guardrails, and its examples hardcode specific
VMIDs/storage/bridge names as if they were universal defaults to copy.
This version keeps the command coverage but restructures around what
this session's actual hands-on Proxmox work across two hosts (vulture,
ginger) surfaced as the real operating discipline: discovery before
mutation, explicit target confirmation, a real destructive-tier list that
matches this environment's own enforced permission classifier, and three
gotchas (Tailscale hostname collisions, reset-vs-reboot, storage
free-space checks) that cost real time or carried real risk this session.