The RHEL-family qemu-guest-agent package starts the agent with an allow-list that omits guest-exec, guest-exec-status and guest-file-* (FILTER_RPC_ARGS in /etc/sysconfig/qemu-ga; older packages spelled the same restriction as BLOCK_RPCS or BLACKLIST_RPC). The agent answered "The command guest-exec has been disabled for this instance", so running scripts in a VM, assigning extra IP addresses and growing the filesystem after a disk resize did not work on Rocky Linux, AlmaLinux, CentOS Stream and Fedora guests. - patch-cloud-images.sh: clear all three variants while building the mirror (UNBLOCK_RPC=0 opts out) and add an ONLY filter to rebuild only part of the catalog. Three `[ ... ] && ...` statements that aborted the script under set -e are now plain ifs -- the one before mirrors.json generation killed every run that passed BASE_URL - builtin.py: point the five RHEL-family amd64 entries at the rebuilt mirror release 2026-08-22 with their new checksums. Ubuntu and Debian images are unaffected and stay in the previous releases, so older panel versions keep working - client.py: annotate the Proxmox error with what to clear inside the guest, the raw message names neither the file nor the variable - WIKI, CHANGELOG: document the restriction and the unblock command
Backend Tests
Smoke / unit tests for the FastAPI backend, focused on the security-critical
modules: app.crypto, app.auth, app.rbac.
Layout
backend/
├── pytest.ini # pytest config (testpaths=tests, markers, addopts)
├── requirements-dev.txt # test deps (-r requirements.txt + pytest …)
└── tests/
├── conftest.py # env setup + reusable fixtures
├── test_crypto.py # Fernet field-encryption helpers
├── test_auth.py # password hashing, JWT, IP parsing, perm helpers
└── test_rbac.py # PermissionEngine + registry
How conftest.py keeps tests hermetic
The application reads configuration at import time:
app.config.Settingsis apydantic-settingsmodel that auto-loads.envfrom the current working directory.app.dbconstructs the SQLAlchemy engine on import.
tests/conftest.py therefore, before any app.* import:
- Sets
DATABASE_URL,SECRET_KEY,ADMIN_PASSWORD,LOG_LEVELto safe test values viaos.environ.setdefault. - Generates a fresh
FERNET_KEYso encrypt/decrypt round-trips succeed. - Adds
backend/tosys.path. chdirs to a temp directory so the developer's local.env(which contains keys not declared onSettings) is not picked up. Without this step pydantic raisesextra_forbidden.
No real Postgres connection is opened — SQLAlchemy connects lazily, and these tests never issue a query.
Running locally
There is no system-wide Python on this host, so use the same Python image as CI:
docker run --rm -v "$PWD/backend:/app" -w /app python:3.12-slim bash -c '
pip install -r requirements-dev.txt &&
python -m pytest -p no:warnings
'
Run a single test:
python -m pytest tests/test_auth.py::TestJWT -v
CI
GitHub Actions runs the suite on every push / PR to main that touches
backend/** — see .github/workflows/backend-tests.yml.
Coverage is reported to the job log and uploaded as an artifact.
Adding more tests
- Pure / domain logic (no DB): use the
fake_user_factory/fake_role_factoryfixtures inconftest.py. They produceSimpleNamespaceobjects that satisfy duck-typed access inauth.pyandrbac/engine.py. - Touches the DB: build out a SQLite-backed fixture (override
app.db.enginewithsqlite:///:memory:andBase.metadata.create_all). Not required for the current smoke layer. - API endpoints: spin up
TestClient(app)onceget_dband any external Proxmox / SSH dependencies are dependency-overridden.
Markers
Defined in pytest.ini:
@pytest.mark.smoke— quickest sanity checks.@pytest.mark.unit— pure unit tests.@pytest.mark.integration— multi-module integration.
Run only smoke tests:
python -m pytest -m smoke