Plugin lifecycle: install, enable, disable, remove, the CLI
  • Python 71%
  • JavaScript 27.9%
  • CSS 1.1%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
2026-09-14 09:00:00 +02:00
apps.d Initial import 2026-09-14 09:00:00 +02:00
debian Initial import 2026-09-14 09:00:00 +02:00
pmx_cork_plugin_manager Initial import 2026-09-14 09:00:00 +02:00
tests Initial import 2026-09-14 09:00:00 +02:00
.gitignore Initial import 2026-09-14 09:00:00 +02:00
LICENSE Initial import 2026-09-14 09:00:00 +02:00
pyproject.toml Initial import 2026-09-14 09:00:00 +02:00
README.md Initial import 2026-09-14 09:00:00 +02:00

pmx-cork-plugin-manager

The plugin system for Proxmox VE. A plugin adds tabs and API routes without any PVE file being edited: the tabs are injected by the port 443 front and the routes are served alongside pveproxy, not inside it.

Enabling is per node. The registry lives in /etc/pve/local/, so each node carries its own, and the interface draws a plugin's tab only under the nodes that run it.

The services it runs in

The plugin manager is an add-on for pmx-cork-host, which provides the services it runs in:

  • pmx-cork-proxy (Unix socket /run/pmx-cork-proxy/proxy.sock, user www-data, behind the port 443 front): the API server for the web interface and for reads, authenticated with the PVE ticket and CSRF token the way pveproxy is.
  • pmx-cork-daemon (Unix socket /run/pmx-cork-daemon/daemon.sock, root): the privileged side for writes, such as applying patches, enabling and disabling plugins and building the bundle. Reachable only through the proxy; the socket directory is restricted to root and www-data.
  • pmx-cork-scheduler (root): runs the plugins' recurring jobs as its own service, the counterpart of pvescheduler. Not needed to serve the UI or the API.

The manager ships no units of its own. It plugs into the runtime through /etc/pmx-cork/apps.d/pmx-cork-plugin-manager.conf, which names the module pmx_cork_plugin_manager.app; the runtime reads that directory at boot and mounts the manager's API into the proxy and the daemon.

Plugins

The plugins are not part of this package. They ship in extensions/plugins/ as pmx-cork-plugin-manager-extensions:

Plugin Purpose
hardware_inventory CPU, RAM, storage, network, PCI, USB
sensors_monitor temperatures, fans, voltages, power (lm-sensors)
node_maintenance toggle a node's HA maintenance mode
ugreen_leds LED control for UGREEN NAS hardware
ugreen_fans fan control (it87/hwmon) with a temperature curve for UGREEN NAS hardware
example_plugin a documented template for new plugins

pve_patcher lives in the same directory and is deliberately not packaged (debian/rules drops it). It edits PVE's own JS in place, which is the one thing this suite exists to avoid, and its patch anchors are verbatim upstream source that any reflow breaks.

Custom plugins are installed as a ZIP through the web interface or the CLI, into /var/lib/pmx-cork-plugin-manager/plugins/.

Requirements

  • Proxmox VE 9 on Debian 13, Python 3.11 or newer
  • python3-pmx-cork-sdk: the SDK the plugins' api.py and ui.py use
  • python3-pmx-cork-tasks, python3-pmx-cork-dispatch, python3-pmx-cork-host: the layers beneath, and the services
  • python3-pmx-cork-ui: the UI core the manager's frontend runs in
  • the port 443 front (make front-install), since the proxy has no TCP listener
  • python3-pmx-cork-scheduler, recommended, for the plugins' recurring jobs

The manager itself carries the product logic only: the plugin loader, the routes, the bundle, the CLI and the registry in pmxcfs. Authentication, RBAC, validation and dispatch come from the runtime beneath it.

Installation

make deb-deps      # once: the build tools
make install       # builds the base packages and installs them with apt
make front-install  # the port 443 front, on every node
apt-get install -y ./dist-deb/python3-pmx-cork-ui_*.deb \
    ./dist-deb/pmx-cork-plugin-manager_*.deb \
    ./dist-deb/pmx-cork-plugin-manager-extensions_*.deb

Open the UI on https://<node>/. Port 8006 does not load the plugin manager. The full guide is docs/INSTALL.md.

The package drops its apps.d file and builds the JS/CSS bundle the runtime serves. The Python modules land under /usr/lib/python3/dist-packages/. The CLI, the package and the paths under /usr/share, /var/lib and /etc/pve/local all carry the same name, so there is one thing to look for.

After code changes: make deb && make install.

CLI

pmx-cork-plugin-manager plugin list
pmx-cork-plugin-manager plugin info <id>
pmx-cork-plugin-manager plugin install <zip> [--enable]
pmx-cork-plugin-manager plugin remove <id>
pmx-cork-plugin-manager plugin enable <id>
pmx-cork-plugin-manager plugin disable <id>

pmx-cork-plugin-manager bundle rebuild

pmx-cork-plugin-manager service start|stop|restart|status

The service subcommand acts on the proxy, the daemon and the scheduler, as the Makefile targets make start|stop|restart|status do.

Patching

Nothing installed by this package patches a PVE file. pve_patcher can, and that is why it stays in the source tree and out of the package: an engine, the patch sets under extensions/plugins/pve_patcher/patches/, a tab and an API under /pmx-cork/api/v1/plugins/pve_patcher/.... It wraps each replacement in markers, so a patch is idempotent and can be reverted, but its targets are not conffiles and nothing re-applies them: a pve-manager or proxmox-widget-toolkit upgrade replaces the files and the patches are simply gone.

Directories

Path Contents
/usr/lib/python3/dist-packages/ the Python modules, from apt
/usr/bin/pmx-cork-plugin-manager the CLI
/usr/share/pmx-cork-plugin-manager/plugins/ the bundled plugins (pve_patcher is not among them)
/var/lib/pmx-cork-plugin-manager/plugins/ installed plugins
/var/lib/pmx-cork-plugin-manager/state/ the route-generation marker the workers watch. The registry itself is in pmxcfs: /etc/pve/local/pmx-cork-plugin-manager/registry.json
/usr/share/pmx-cork/pmx-cork-plugin-manager/www/ the generated JS/CSS bundle and UI manifest (pmx-cork-plugin-manager bundle rebuild); served by the runtime under /pmx-cork/web/plugin-manager

Logs go to journald: journalctl -t pmx-cork-proxy and journalctl -t pmx-cork-daemon.

Writing a plugin

my_plugin/
├── plugin_info.json          # metadata
├── __init__.py
├── api.py                    # the backend, written with pmx-cork-sdk
├── ui.py                     # the config-panel tabs (pmx_cork_sdk.ui)
└── www/
    └── MainPanel.js          # the ExtJS component

The guide is docs/PLUGIN_DEVELOPMENT.md; a complete example is extensions/plugins/example_plugin.

Removing

make uninstall       # apt remove; data under /var/lib stays
make front-uninstall  # the port 443 front
make purge           # apt purge; also removes /var/lib/pmx-cork-plugin-manager

Purging removes /var/lib/pmx-cork-plugin-manager and this node's registry under /etc/pve/local/pmx-cork-plugin-manager/. There are no log files to remove. On a node where pve_patcher was run by hand, revert its patch sets before removing: they are edits in PVE's own files and nothing else takes them back.

License

AGPL-3.0-only. See LICENSE.