Flag guests that no backup job covers
The guest table marks with "!" each guest that Proxmox's not-backed-up list returns. The frame's bottom border shows the count, e.g. "mainframe · 2 without backup job". This uses Proxmox's own answer, so it also counts jobs that select guests by pool. If the coverage call fails, the guests are still listed and a warning says the coverage is unknown. Closes #9 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit was merged in pull request #20.
This commit is contained in:
1 parent
5a3ca5a216
commit
520de16cc6
5 files changed
+97
-6
No files matched your search
@@ -49,6 +49,7 @@ class Fake:
|
||||
self.use_error = None
|
||||
self.use_hook = None
|
||||
self.guests_by_context = {}
|
||||
self.unprotected, self.unprotected_error = set(), None
|
||||
self.list_hook = None
|
||||
# delivery A (guest info screen)
|
||||
self.net_configs = {} # vmid -> extra config keys (netN, ipconfigN)
|
||||
@@ -103,6 +104,11 @@ class Fake:
|
||||
self.status_calls.append(guest["vmid"])
|
||||
return self.live_status.get(guest["vmid"], guest["status"])
|
||||
|
||||
def not_backed_up(self):
|
||||
if self.unprotected_error:
|
||||
raise self.unprotected_error
|
||||
return set(self.unprotected)
|
||||
|
||||
def contexts(self):
|
||||
self.contexts_calls += 1
|
||||
if self.contexts_error:
|
||||
@@ -195,6 +201,7 @@ def fake(monkeypatch):
|
||||
"backup_now",
|
||||
"bridges",
|
||||
"set_net",
|
||||
"not_backed_up",
|
||||
):
|
||||
monkeypatch.setattr(cli, name, getattr(f, name), raising=False)
|
||||
for name in ("list_guests", "guest_config", "disks", "action", "set_resources",
|
||||
@@ -2108,3 +2115,39 @@ async def test_info_resources_reload_after_edit(fake, monkeypatch):
|
||||
await settle(app, pilot)
|
||||
assert isinstance(app.screen, appmod.InfoScreen)
|
||||
assert resource_rows(app)["CPU"].startswith("8 cores")
|
||||
|
||||
|
||||
# --- #9: flag guests that no backup job covers --------------------------------------
|
||||
|
||||
|
||||
def first_cell(app, vmid):
|
||||
return str(app.query_one("#guests", DataTable).get_row(str(vmid))[0])
|
||||
|
||||
|
||||
async def test_unprotected_guests_are_marked_and_counted(fake):
|
||||
fake.unprotected = {100}
|
||||
app = make_app()
|
||||
async with app.run_test(size=SIZE) as pilot:
|
||||
await settle(app, pilot)
|
||||
assert first_cell(app, 100) == "!"
|
||||
assert first_cell(app, 108) == ""
|
||||
subtitle = str(app.query_one("#guests_section").border_subtitle)
|
||||
assert "mainframe" in subtitle and "1 without backup job" in subtitle
|
||||
|
||||
|
||||
async def test_no_count_when_every_guest_is_covered(fake):
|
||||
app = make_app()
|
||||
async with app.run_test(size=SIZE) as pilot:
|
||||
await settle(app, pilot)
|
||||
assert str(app.query_one("#guests_section").border_subtitle) == "mainframe"
|
||||
assert first_cell(app, 100) == "" and first_cell(app, 108) == ""
|
||||
|
||||
|
||||
async def test_backup_coverage_failure_still_lists_guests(fake):
|
||||
fake.unprotected_error = cli.CliError("Error: boom")
|
||||
app = make_app()
|
||||
async with app.run_test(size=SIZE) as pilot:
|
||||
await settle(app, pilot)
|
||||
assert app.query_one("#guests", DataTable).row_count == 2
|
||||
assert any(sev == "warning" for _, sev in app.seen) # coverage unknown, said so
|
||||
assert app.is_running
|
||||
Reference in new issue
Block a user