fix(gitea): add full backup restore drill receipt path

This commit is contained in:
ogt
2026-07-10 09:45:12 +08:00
parent 97312fa37a
commit 7fd76b3bcf
6 changed files with 387 additions and 8 deletions

View File

@@ -12,6 +12,7 @@ def test_backup_gitea_writes_full_server_component_receipts() -> None:
assert "write_gitea_full_backup_receipt" in text
assert "awoooi_gitea_full_backup_component_receipt" in text
assert "awoooi_gitea_full_backup_restore_drill_performed" in text
assert "awoooi_gitea_full_backup_secret_value_collected" in text
assert "awoooi_gitea_full_backup_production_restore_performed" in text
assert "gitea dump -c /data/gitea/conf/app.ini" in text
@@ -34,6 +35,11 @@ def test_backup_gitea_receipt_contract_stays_no_secret_no_restore() -> None:
assert "awoooi_gitea_full_backup_secret_value_collected" in text
assert "awoooi_gitea_full_backup_production_restore_performed" in text
assert "awoooi_gitea_full_backup_restore_drill_performed" in text
assert (
'restore_drill_performed{host=\\"${host}\\",service=\\"${service_label}\\"} 0'
in text
)
assert (
'secret_value_collected{host=\\"${host}\\",service=\\"${service_label}\\"} 0'
in text

View File

@@ -0,0 +1,99 @@
from __future__ import annotations
import subprocess
import zipfile
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
SCRIPT = ROOT / "gitea-full-backup-restore-drill.sh"
def _write_dump(path: Path, *, include_lfs: bool = True) -> None:
entries = {
"gitea-db.sql": "-- redacted fixture\n",
"repos/wooo/awoooi.git/HEAD": "ref: refs/heads/main\n",
"custom/conf/app.ini": "[server]\nAPP_NAME=fixture\n",
"data/packages/package.bin": "package fixture\n",
"data/attachments/attachment.bin": "attachment fixture\n",
"custom/hooks/pre-receive": "#!/bin/sh\n",
}
if include_lfs:
entries["data/lfs/objects/aa/bb/object"] = "lfs fixture\n"
with zipfile.ZipFile(path, "w") as archive:
for name, content in entries.items():
archive.writestr(name, content)
def test_gitea_full_backup_restore_drill_writes_non_production_receipt(
tmp_path: Path,
) -> None:
dump = tmp_path / "gitea-dump.zip"
textfile = tmp_path / "gitea_full_backup_restore_drill.prom"
_write_dump(dump)
result = subprocess.run(
[
"bash",
str(SCRIPT),
"--dump-zip",
str(dump),
"--write-textfile",
"--textfile",
str(textfile),
"--host",
"110",
],
text=True,
capture_output=True,
check=True,
)
assert "GITEA_FULL_BACKUP_RESTORE_DRILL_OK=1" in result.stdout
assert "SECRET_VALUES_COLLECTED=0" in result.stdout
assert "PRODUCTION_RESTORE_PERFORMED=0" in result.stdout
rendered = textfile.read_text(encoding="utf-8")
assert (
'awoooi_gitea_full_backup_restore_drill_performed{host="110",service="gitea",'
in rendered
)
assert 'drill_scope="structural_metadata_only"' in rendered
assert 'production_restore="false"' in rendered
assert '} 1' in rendered
assert (
'awoooi_gitea_full_backup_secret_value_collected{host="110",service="gitea",'
in rendered
)
assert (
'awoooi_gitea_full_backup_production_restore_performed{host="110",service="gitea",'
in rendered
)
def test_gitea_full_backup_restore_drill_fails_closed_when_component_missing(
tmp_path: Path,
) -> None:
dump = tmp_path / "gitea-dump.zip"
textfile = tmp_path / "gitea_full_backup_restore_drill.prom"
_write_dump(dump, include_lfs=False)
result = subprocess.run(
[
"bash",
str(SCRIPT),
"--dump-zip",
str(dump),
"--write-textfile",
"--textfile",
str(textfile),
],
text=True,
capture_output=True,
)
assert result.returncode == 1
assert "GITEA_FULL_BACKUP_RESTORE_DRILL_OK=0" in result.stdout
assert "ERROR=component_coverage_gap" in result.stdout
rendered = textfile.read_text(encoding="utf-8")
assert 'component="lfs_objects",drill_scope="structural_metadata_only"} 0' in rendered
assert 'production_restore_performed{host="110",service="gitea",' in rendered