302 lines
9.8 KiB
Markdown
302 lines
9.8 KiB
Markdown
# Operations
|
|
|
|
[Version francaise](../fr/exploitation.md)
|
|
|
|
## Docker Execution
|
|
|
|
Docker is the recommended operating mode. The container runs a one-shot command, writes logs to stdout/stderr, generates the PDF report and exits.
|
|
|
|
### Preparation
|
|
|
|
```sh
|
|
cp .env.example .env
|
|
mkdir -p reports
|
|
```
|
|
|
|
In `.env`, adjust PVE/PBS access and keep the following for Docker execution:
|
|
|
|
```env
|
|
REPORT_OUTPUT_DIR=/reports
|
|
```
|
|
|
|
The Docker Compose service mounts `./reports` to `/reports`, making PDFs available on the host in the `reports/` directory.
|
|
|
|
### Build the Image
|
|
|
|
```sh
|
|
docker compose build
|
|
```
|
|
|
|
The image installs Python dependencies and the system libraries required by WeasyPrint.
|
|
|
|
### Configuration Check
|
|
|
|
```sh
|
|
docker compose run --rm pve-backup-report --check-config
|
|
```
|
|
|
|
### API Connectivity Test
|
|
|
|
```sh
|
|
docker compose run --rm pve-backup-report --check-api
|
|
```
|
|
|
|
This command tests `/nodes`, `/storage`, `/cluster` and the endpoint configured in `PVE_BACKUP_JOBS_ENDPOINT`.
|
|
|
|
If `/cluster/backup` returns `HTTP 403 - Permission check failed (/, Sys.Audit)`, the token works but lacks the `Sys.Audit` privilege on `/`.
|
|
|
|
### PDF Report Generation
|
|
|
|
```sh
|
|
docker compose run --rm pve-backup-report --generate-pdf
|
|
```
|
|
|
|
The report is created in `REPORT_OUTPUT_DIR`. The filename contains a timestamp and never overwrites previous reports.
|
|
|
|
Example file generated on the host:
|
|
|
|
```text
|
|
reports/rapport-sauvegardes-pve-2026-05-09-020000.pdf
|
|
```
|
|
|
|
### Docker Diagnostic Commands
|
|
|
|
Inventory:
|
|
|
|
```sh
|
|
docker compose run --rm pve-backup-report --dump-inventory
|
|
```
|
|
|
|
Coverage:
|
|
|
|
```sh
|
|
docker compose run --rm pve-backup-report --dump-coverage
|
|
```
|
|
|
|
Report data as JSON:
|
|
|
|
```sh
|
|
docker compose run --rm pve-backup-report --dump-report-data
|
|
```
|
|
|
|
This output is a technical preview of the report model. Raw sensitive fields are filtered, but the JSON contains operational information such as VM/CT names, VMIDs, PVE notes, servers, datastores, namespaces, PBS users and backup metadata. Treat it as internal data and do not share it outside the authorized operations/audit scope.
|
|
|
|
PBS datastore usage:
|
|
|
|
```sh
|
|
docker compose run --rm pve-backup-report --dump-pbs-storage-usages
|
|
```
|
|
|
|
PBS users used by PVE storages:
|
|
|
|
```sh
|
|
docker compose run --rm pve-backup-report --dump-pbs-users
|
|
```
|
|
|
|
Diagnostic for a missing latest backup:
|
|
|
|
```sh
|
|
docker compose run --rm pve-backup-report --debug-last-backup-vmid <VMID>
|
|
```
|
|
|
|
Running `docker compose run --rm pve-backup-report` without arguments does not generate a PDF. To produce the report, use `--generate-pdf` explicitly.
|
|
|
|
## Direct CLI Execution
|
|
|
|
This mode is useful for development or diagnostics outside the container.
|
|
|
|
Local installation:
|
|
|
|
```sh
|
|
python3 -m venv .venv
|
|
. .venv/bin/activate
|
|
python -m ensurepip --upgrade
|
|
pip install -r requirements.txt
|
|
pip install -e .
|
|
```
|
|
|
|
PDF generation uses WeasyPrint. Outside Docker, the host must provide the system libraries required by WeasyPrint.
|
|
With WeasyPrint 62.x, keep the `pydyf>=0.10,<0.11` constraint to avoid PDF generation errors related to the internal `pydyf` API.
|
|
|
|
Installed commands:
|
|
|
|
```sh
|
|
pve-backup-report --check-config
|
|
pve-backup-report --check-api
|
|
pve-backup-report --dump-inventory
|
|
pve-backup-report --dump-coverage
|
|
pve-backup-report --dump-report-data
|
|
pve-backup-report --dump-pbs-storage-usages
|
|
pve-backup-report --dump-pbs-users
|
|
pve-backup-report --generate-pdf
|
|
```
|
|
|
|
Without editable installation:
|
|
|
|
```sh
|
|
PYTHONPATH=src python3 -m pve_backup_report --check-config
|
|
PYTHONPATH=src python3 -m pve_backup_report --check-api
|
|
PYTHONPATH=src python3 -m pve_backup_report --dump-inventory
|
|
PYTHONPATH=src python3 -m pve_backup_report --dump-coverage
|
|
PYTHONPATH=src python3 -m pve_backup_report --dump-report-data
|
|
PYTHONPATH=src python3 -m pve_backup_report --dump-pbs-storage-usages
|
|
PYTHONPATH=src python3 -m pve_backup_report --dump-pbs-users
|
|
PYTHONPATH=src python3 -m pve_backup_report --generate-pdf
|
|
```
|
|
|
|
In direct local execution, `REPORT_OUTPUT_DIR` can remain `reports/` or point to another directory accessible by the current user.
|
|
|
|
The same `.env` file can be used in Docker and local execution. The Docker value `REPORT_OUTPUT_DIR=/reports` remains valid in the container with the `./reports:/reports` mount. Outside Docker, if `/reports` is not accessible, the application automatically uses the local `reports/` directory and logs the fallback.
|
|
|
|
It is still possible to explicitly force a local path:
|
|
|
|
```env
|
|
REPORT_OUTPUT_DIR=reports
|
|
```
|
|
|
|
## PBS Retention Policy
|
|
|
|
To populate the `Retention policy` table and the `VM/CT backup retention` tables, set the API variables for the relevant PBS:
|
|
|
|
```env
|
|
PBS01_NAME=display-name
|
|
PBS01_API_URL=https://backup.example.invalid:8007
|
|
PBS01_API_TOKEN_ID=
|
|
PBS01_API_TOKEN_SECRET=
|
|
PBS01_VERIFY_TLS=true
|
|
```
|
|
|
|
For multiple PBS servers, duplicate this block with `PBS02_*`, `PBS03_*`, `PBS04_*`, etc. The report creates retention sections for each configured PBS.
|
|
|
|
Collection reads prune jobs from configured PBS servers through `/config/prune`. If a PBS is unavailable, if its token lacks sufficient rights, or if no policy is returned, the report continues and adds a `pbs_retention` anomaly.
|
|
|
|
Collection also reads snapshots from each configured PBS datastore. Namespaces declared in PVE PBS storages are queried on each PBS, including a secondary PBS that does not directly receive backups from PVE but contains synchronized backups. These data feed the `VM/CT backup retention <PBS>` tables, including VM/CT still visible on PBS but absent from the PVE inventory. They are marked `Not active on PVE` in the report.
|
|
If a PVE namespace does not exist on a tested PBS datastore, the possible `HTTP 400 - Bad Request` returned by PBS is ignored for that non-root namespace to avoid an expected anomaly.
|
|
|
|
Retention tables are split by namespace and also display the datastore, because the same namespace can exist on multiple datastores on the same PBS.
|
|
They also display the expected version count and a delta compared with visible snapshot count. This calculation depends on an active retention policy matching the same PBS server, datastore and namespace.
|
|
|
|
The report also collects datastore status from each configured PBS to display total, used and free space.
|
|
The garbage collector status of each PBS datastore is also collected. If the garbage collector is running, a warning is displayed only under retention tables for the relevant PBS/datastore.
|
|
|
|
## Daily Scheduling
|
|
|
|
Recommended scheduling on Debian 13 can be done with a systemd timer or cron. The container and CLI are designed for one-shot execution: the command generates the report and exits.
|
|
|
|
### Cron with Docker Compose
|
|
|
|
Example host crontab to run the report every day at 02:00:
|
|
|
|
```cron
|
|
SHELL=/bin/sh
|
|
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
|
|
|
|
0 2 * * * cd /srv/pve-backup-report && /usr/bin/flock -n /tmp/pve-backup-report.lock /usr/bin/docker compose run --rm pve-backup-report --generate-pdf >> /var/log/pve-backup-report.log 2>&1
|
|
```
|
|
|
|
Important points:
|
|
|
|
- adapt `/srv/pve-backup-report` to the real repository path;
|
|
- keep `REPORT_OUTPUT_DIR=/reports` in `.env` for Docker;
|
|
- verify that the host `reports/` directory exists and is accessible;
|
|
- use `flock` to avoid two simultaneous generations if an execution takes longer than expected;
|
|
- redirect stdout/stderr to a log file or to the host supervision system.
|
|
|
|
To test the exact scheduled command:
|
|
|
|
```sh
|
|
cd /srv/pve-backup-report
|
|
/usr/bin/flock -n /tmp/pve-backup-report.lock /usr/bin/docker compose run --rm pve-backup-report --generate-pdf
|
|
```
|
|
|
|
### Cron Calling the Script Directly
|
|
|
|
Example with the project's virtual environment:
|
|
|
|
```cron
|
|
SHELL=/bin/sh
|
|
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
|
|
|
|
0 2 * * * cd /srv/pve-backup-report && /usr/bin/flock -n /tmp/pve-backup-report.lock /srv/pve-backup-report/.venv/bin/pve-backup-report --generate-pdf >> /var/log/pve-backup-report.log 2>&1
|
|
```
|
|
|
|
In this mode:
|
|
|
|
- `cd` to the repository allows loading the default `.env` file;
|
|
- `REPORT_OUTPUT_DIR` can remain `/reports`, `reports/`, or point to an absolute path accessible by the cron user;
|
|
- the cron user must have read access to `.env` and write access to the report directory;
|
|
- WeasyPrint system libraries must be installed on the host.
|
|
|
|
To test the exact scheduled command:
|
|
|
|
```sh
|
|
cd /srv/pve-backup-report
|
|
/usr/bin/flock -n /tmp/pve-backup-report.lock /srv/pve-backup-report/.venv/bin/pve-backup-report --generate-pdf
|
|
```
|
|
|
|
Adjust the schedule to avoid high-load periods or maintenance windows.
|
|
|
|
## Daily Verification
|
|
|
|
After execution, check:
|
|
|
|
- presence of a new PDF;
|
|
- command return code;
|
|
- container logs;
|
|
- anomalies section;
|
|
- list of VM/CT without backup.
|
|
|
|
## Evidence Retention
|
|
|
|
For audit use, keep reports in a backed-up location.
|
|
|
|
Recommendations:
|
|
|
|
- persistent storage outside the container;
|
|
- limited write permissions;
|
|
- read access for authorized people only;
|
|
- retention aligned with internal policy;
|
|
- system clock synchronized by NTP.
|
|
|
|
## Recommended Exit Codes
|
|
|
|
| Code | Meaning |
|
|
| --- | --- |
|
|
| `0` | Report generated without blocking error. |
|
|
| `1` | Configuration error. |
|
|
| `2` | PVE authentication impossible. |
|
|
| `3` | PVE API unavailable. |
|
|
| `4` | PDF write error. |
|
|
| `5` | Unexpected error. |
|
|
|
|
An execution with non-blocking anomalies can return `0` if the report is generated and anomalies are visible in the PDF.
|
|
|
|
## Monitoring
|
|
|
|
Monitor at least:
|
|
|
|
- absence of today's report;
|
|
- command failure;
|
|
- increase in the number of VM/CT without backup;
|
|
- recurring anomalies;
|
|
- PVE token expiration or revocation.
|
|
|
|
## Log Rotation
|
|
|
|
Logs must remain on stdout/stderr to integrate with Docker.
|
|
|
|
Rotation is handled by Docker or by the operating platform.
|
|
|
|
## Restore and Audit
|
|
|
|
This report proves the observed configuration at execution time.
|
|
|
|
It does not by itself prove that a restore is possible.
|
|
|
|
For stronger evidence, complement this project with:
|
|
|
|
- checks of latest job executions;
|
|
- verification of snapshots present in PBS;
|
|
- periodic restore tests;
|
|
- signature or immutable storage of reports.
|