Compute PBS retention depth

This commit is contained in:
2026-05-31 07:40:42 +02:00
parent d249f257b8
commit 95ef28065a
4 changed files with 42 additions and 4 deletions
+1 -1
View File
@@ -216,7 +216,7 @@ Collection reads PBS prune jobs through `/config/prune` and displays:
- schedule; - schedule;
- active/inactive state; - active/inactive state;
- columns `Last`, `Hourly`, `Daily`, `Weekly`, `Monthly`, `Yearly`; - columns `Last`, `Hourly`, `Daily`, `Weekly`, `Monthly`, `Yearly`;
- `max-depth`. - computed depth, corresponding to the sum of configured `keep-last`, `keep-hourly`, `keep-daily`, `keep-weekly`, `keep-monthly` and `keep-yearly` values.
A namespace missing in PBS is displayed as `/`, meaning the root namespace. A namespace missing in PBS is displayed as `/`, meaning the root namespace.
+1 -1
View File
@@ -216,7 +216,7 @@ La collecte lit les prune jobs PBS via `/config/prune` et affiche :
- planification ; - planification ;
- etat actif/inactif ; - etat actif/inactif ;
- colonnes `Derniere`, `Horaire`, `Jour`, `Semaine`, `Mois`, `Annee` ; - colonnes `Derniere`, `Horaire`, `Jour`, `Semaine`, `Mois`, `Annee` ;
- profondeur `max-depth`. - profondeur calculee, correspondant a la somme des valeurs `keep-last`, `keep-hourly`, `keep-daily`, `keep-weekly`, `keep-monthly` et `keep-yearly` renseignees.
Une namespace absente dans PBS est affichee comme `/`, c'est-a-dire la namespace racine. Une namespace absente dans PBS est affichee comme `/`, c'est-a-dire la namespace racine.
+16 -1
View File
@@ -438,10 +438,25 @@ def retention_policy_row(policy: object) -> list[object]:
getattr(policy, "keep_weekly", None), getattr(policy, "keep_weekly", None),
getattr(policy, "keep_monthly", None), getattr(policy, "keep_monthly", None),
getattr(policy, "keep_yearly", None), getattr(policy, "keep_yearly", None),
getattr(policy, "max_depth", None), display(retention_policy_depth(policy)),
] ]
def retention_policy_depth(policy: object) -> int | None:
values = [
getattr(policy, "keep_last", None),
getattr(policy, "keep_hourly", None),
getattr(policy, "keep_daily", None),
getattr(policy, "keep_weekly", None),
getattr(policy, "keep_monthly", None),
getattr(policy, "keep_yearly", None),
]
kept_versions = [value for value in values if isinstance(value, int)]
if not kept_versions:
return None
return sum(kept_versions)
def add_backup_jobs(story: list[object], styles: dict[str, ParagraphStyle], report_data: ReportData) -> None: def add_backup_jobs(story: list[object], styles: dict[str, ParagraphStyle], report_data: ReportData) -> None:
rows: list[list[object]] = [["ID", "Storage", "Horaire", "Actif", "Mode", "Selection", "Exclusion"]] rows: list[list[object]] = [["ID", "Storage", "Horaire", "Actif", "Mode", "Selection", "Exclusion"]]
for job in report_data.backup_jobs: for job in report_data.backup_jobs:
+24 -1
View File
@@ -26,6 +26,7 @@ from pve_backup_report.report_pdf import format_last_backup
from pve_backup_report.report_pdf import format_size from pve_backup_report.report_pdf import format_size
from pve_backup_report.report_pdf import pbs_datastore_usage_row from pve_backup_report.report_pdf import pbs_datastore_usage_row
from pve_backup_report.report_pdf import pbs_access_user_row from pve_backup_report.report_pdf import pbs_access_user_row
from pve_backup_report.report_pdf import retention_policy_depth
from pve_backup_report.report_pdf import retention_policy_row from pve_backup_report.report_pdf import retention_policy_row
from pve_backup_report.report_pdf import add_table_of_contents from pve_backup_report.report_pdf import add_table_of_contents
from pve_backup_report.report_pdf import unique_report_path from pve_backup_report.report_pdf import unique_report_path
@@ -171,10 +172,32 @@ def test_retention_policy_row_splits_columns() -> None:
8, 8,
3, 3,
1, 1,
0, "29",
] ]
def test_retention_policy_depth_sums_keep_values() -> None:
policy = PbsRetentionPolicy(
policy_id="prune-prod",
server_name="PBS01",
keep_last=1,
keep_hourly=2,
keep_daily=14,
keep_weekly=8,
keep_monthly=3,
keep_yearly=1,
max_depth=0,
)
assert retention_policy_depth(policy) == 29
def test_retention_policy_row_displays_unspecified_depth_without_keep_values() -> None:
policy = PbsRetentionPolicy(policy_id="prune-empty", server_name="PBS01", max_depth=0)
assert retention_policy_row(policy)[-1] == "non renseigne"
def test_find_snapshot_summary_matches_storage_namespace_and_guest() -> None: def test_find_snapshot_summary_matches_storage_namespace_and_guest() -> None:
guest = Guest(vmid=100, name="srv", guest_type="qemu") guest = Guest(vmid=100, name="srv", guest_type="qemu")
item = BackupCoverage( item = BackupCoverage(