Skip to Content

PMIVerse terminal control panel

pmiverse opens a keyboard-driven browser for the shared operational package: databases, backups, repository updates, Odoo version migrations, installed runtime and module-upgrade services, testing, linting, translation, and deployment. It uses Python's standard library, including curses; no additional Python packages are required. Use Python 3.11 or newer with curses support and a normal terminal.

Deploy and start

From the server's checkout, install commands for your own account:

/srv/pmiverse/_pmiconfig/scripts/integration/install_cli_shortcuts.sh --user
source ~/.bashrc
pmiverse

The deployment script links pmiverse and restore-db into ~/.local/bin, installs Bash completion, and adds PATH/completion setup to ~/.bashrc. It refuses conflicting command files or links. Repeating installation refreshes completion without duplicating shell setup. --python /path/to/python records a different dashboard interpreter in the user's Bash setup. Existing operational scripts retain their own shebangs and runtime configuration.

--system instead links into /usr/local/bin and installs completion under /etc/bash_completion.d; run the installer with the required administrative authority. With a nondefault system-mode interpreter, set PMIVERSE_PYTHON in each user's environment. The installer installs no dependencies or services.

Before deployment, run directly:

PMIVERSE_PYTHON=/path/to/python /srv/pmiverse/_pmiconfig/tools/pmiverse-cli

Remote use runs the same checkout on the target server:

ssh -t demo-host pmiverse
  • Up/Down or j/k selects a command; / filters names, groups, and descriptions.
  • ? displays usage, available options, and an example without executing scripts.
  • o opens the command's local runbook, with scrolling and page navigation.
  • Enter opens the selected command's option form. Up/Down or Tab moves between named fields; the selected field's help appears below the controls.
  • Space toggles checkboxes. Enter opens choice lists, edits literal values, or edits lists of paths and arguments. e enters a database or service value manually instead of choosing a suggestion. Database aliases/names and backup instance/host suggestions come from inventory; service suggestions come from installed unit files. Suggestions do not query PostgreSQL or start services.
  • File and directory editors support Tab to browse, arrows to move the cursor, Ctrl-U to clear, Enter to save, and Escape to discard the edit. List editors add/edit individual items; saving a blank item removes it. Escape cancels the list edit; choose Save list to apply it.
  • F5 or the always-visible Review & run button validates required fields and incompatible choices, then displays the selected values and complete command. Enter runs the reviewed operation; Escape returns to the form with its values preserved. Escape from the form cancels it without execution. Commands with no options still have an explicit review screen.
  • Commands run in the terminal with their normal prompts and output. The panel returns after completion and reports the exit status. Ctrl-C is handed to the foreground command; its own recovery and cancellation behavior applies.
  • d inspects database inventory on demand. Return and press d again to refresh.
  • q exits. pmiverse --read-only disables all command launches, including help invocations through the execution interface; offline help and runbooks remain available.

Each form value is a literal argument, so spaces in paths and names need no shell quoting. Test forms have a separate Additional pytest arguments list: enter one argument per item (for example -q and --maxfail=1). The panel inserts the runner/pytest separator. Shell expansion, pipelines, redirections, and command substitution are not evaluated. Arguments are not saved by the panel. Use password-file options rather than entering secrets. Required database targets are not populated from examples. Optional blank fields preserve script defaults.

Direct commands and completion

pmiverse --list
pmiverse --describe test-addon
pmiverse --run test-addon -- --help
pmiverse --run test-addon -- --addon-tests /path/addon/tests --database test_demo
pmiverse --run test-repo -- --repo /path/repo --keep-db
pmiverse --run migrate -- --help
pmiverse --run service -- --unit pmisuite18-update.service --action cat

Direct --run is explicit execution, without the dashboard confirmation, and returns the program's exit status. The -- separator belongs to the dispatcher; everything following it is passed literally to the selected command. A second -- can separate pytest arguments as required by the underlying test runner.

In Bash, press Tab twice after pmiverse -- to discover global options. After pmiverse --run or pmiverse --describe, completion lists catalog names. After pmiverse --run test-addon -- --, it suggests that command's options. Other forwarded operands offer file completion; target names are entered explicitly. Completion reads only the command catalog, without sourcing inventory or querying a server. Existing direct-script completions remain available. PMICONFIG_DIR selects a nonstandard checkout for completion.

Database inventory

pmiverse --databases
pmiverse --instance primary --databases
pmiverse --config /path/to/trusted/pmiverse.conf --databases

The active configuration defaults to $PMIREGISTRY_DIR/config/pmiverse.conf, with PMIREGISTRY_DIR defaulting to /srv/pmiverse/_pmiregistry. PMIVERSE_CONF and then --config override it. The generic _pmiconfig template is not a fallback.

Configuration is trusted executable Bash, loaded in a separate process with a timeout. This is not a sandbox for untrusted configuration. Only the database and instance registry fields are exported to the dashboard. Missing or invalid configuration does not prevent command browsing.

Inspection selects instances matching the local OS short hostname, optionally filtered by --instance. If no instance matches and no explicit --instance was requested, development and restore hosts compare the full database registry against the default libpq connection. This view is labelled local-unregistered; configured databases absent there are Not present, which does not imply they are required on that host. An explicitly requested unmatched instance remains an error. No instance settings from another host are reused for the fallback.

Each registered local instance is queried independently using its PostgreSQL host/port/user fields, with existing nonempty PG environment variables taking precedence as in the backup resolver. Effective connection selectors are shown. Empty selectors use libpq defaults, which can select a remote endpoint; the dashboard does not assert that the PostgreSQL process is local.

Queries use psql without password prompts or startup files, a connection timeout, statement timeout, and total process timeout. Existing libpq authentication is used. No elevation or database writes occur. Results distinguish Present, Missing, Extra, Elsewhere, and Unknown. Failure yields Unknown, never Missing. Versions come from configuration and are not discovered Odoo versions. System/template databases are excluded. JSON output from --databases preserves endpoint scope.

Inventory selection does not inject PostgreSQL variables or targets into any operation. Review the command's own arguments, configuration, and defaults. --config is forwarded as PMIVERSE_CONF; commands that do not consume that setting continue to use their documented configuration. --instance filters inspection only; pass an operation's own --instance after the dispatcher --.

Operational boundaries

The panel delegates validation, locks, transaction handling, and recovery to the existing scripts. A command being listed does not mean its prerequisites are installed or that it is suitable for a selected database. Preview support and preview side effects are documented per command; the panel never invents dry-run flags. It does not elevate privileges, install packages, or deploy templates.

service controls only explicitly named, already-installed pmisuite*.service units. It supports status, cat, show, start, stop, and restart. Inspect the installed unit and drop-ins before starting an upgrade: its database/module targets come from that unit, and upgrade services may stop the runtime and leave it stopped. Review the service runbook for maintenance ordering. Restarting runtime services after an upgrade remains an explicit action.

Legacy registry restore wrappers retain their legacy guarantees; displaying them does not add the generic restore tool's staging, locking, or rollback behavior.

Catalog ownership

data/commands.csv owns shared command names, groups, executable paths, summaries, runbook paths, examples, and completion options. Update it alongside CLI changes. tools/pmiverse_forms.py owns field types, labels, parameter help, positional operands, required values, and validation rules. tools/pmiverse_form_ui.py renders these controls, selectors, path browsers, and the final review screen. Maintain these definitions with the actual CLI contracts; an unknown option without reviewed form metadata is refused instead of falling back to raw command-line entry. The direct --run CLI remains available for automation. The reserved nonfunctional policy checker and implementation-only libraries are excluded. The panel also discovers executable top-level .sh backup, restore, and fetch wrappers in _pmiregistry/scripts/ under registry- names.

An optional _pmiregistry/data/commands.csv can add installation-specific commands using the same header and paths relative to that repository. Duplicate names and paths escaping the owning repository are refused. Catalogs are trusted inputs; merely browsing them does not execute their programs. Keep private inventory, credentials, runtime output, and operation history out of shared catalogs.