fix(backup): the safety backup's audit row names who restored (#5820)
CI / lint (push) Successful in 2s
CI / integration (push) Successful in 1m28s
CI / unit (push) Successful in 1m39s
CI / publish (push) Successful in 1m10s

On the live restore the "before restore" backup.made row read user
"unknown": _safety_backup recorded it with no username. It now carries
the person who started the restore.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-15 11:32:08 -04:00
co-authored by Claude Opus 5.5
parent e445c83e67
commit 8569b3d674
2 changed files with 6 additions and 6 deletions
+3 -3
View File
@@ -102,7 +102,7 @@ async def _run(app, path: Path, name: str, *, username: str, replace_all: bool,
safety_name = ""
if safety:
STATE.step = "Saving a safety backup of Steward as it stands"
safety_name = await _safety_backup(app)
safety_name = await _safety_backup(app, username)
STATE.step = "Restoring"
plugin_dirs = [Path(d) for d in app.config["PLUGIN_DIRS"]]
if replace_all:
@@ -162,7 +162,7 @@ def _backup_key(path: Path) -> str:
raise BackupError(f"{path.name} isn't a Steward backup.") from None
async def _safety_backup(app) -> str:
async def _safety_backup(app, username: str) -> str:
"""A backup of Steward as it stands, before anything is replaced: on
/data/backups always, and on the bucket when one is set. Its run is in
Recent backups like any other."""
@@ -182,7 +182,7 @@ async def _safety_backup(app) -> str:
await put_file(target, made.name, made.path)
else:
entry["error"] = "Kept on /data/backups only: no bucket is set up."
await _record(app, entry, None, "")
await _record(app, entry, None, username) # the audit row names who restored
_prune()
return made.name
+3 -3
View File
@@ -65,8 +65,8 @@ def _stub(monkeypatch, tmp_path, *, restore_error=None, key="k-backup"):
from steward.core import audit
seen = {"audits": [], "restarts": 0}
async def safety(app):
seen["safety"] = True
async def safety(app, username):
seen["safety"] = username
return "steward-20261015T140000Z.tar"
async def in_place(path, url, plugin_dirs=None):
@@ -97,7 +97,7 @@ async def _restore(tmp_path):
async def test_a_restore_saves_a_safety_backup_puts_the_key_in_place_and_restarts(monkeypatch, tmp_path):
seen = _stub(monkeypatch, tmp_path)
await _restore(tmp_path)
assert seen["safety"] and seen["restarts"] == 1
assert seen["safety"] == "admin" and seen["restarts"] == 1 # its audit row names who restored
assert (tmp_path / "secret.key").read_text() == "k-backup"
[(action, detail)] = seen["audits"]
assert action == "backup.restored"