Initialize Synology bind directories explicitly and preserve failed bootstrap journals

This commit is contained in:
Pigway
2026-10-08 00:54:15 +08:00
parent e927df9c62
commit b78b998bb8
3 changed files with 155 additions and 27 deletions
+72
View File
@@ -321,3 +321,75 @@ def test_bootstrap_recovery_cleans_only_owned_prepared_transaction(tool, monkeyp
tool.recover()
assert tool.state["status"] == "failed"
assert ("cleanup",) in calls and ("rm", "lock-id") in calls
@pytest.mark.parametrize("status", ["failed", "prepared", "success"])
def test_retry_journal_only_failed_matching_empty_bootstrap(tool, monkeypatch, status):
prepare(tool, monkeypatch)
record = {
"kind": "bootstrap",
"status": status,
"candidate": tool.bootstrap_config(),
}
def run(*args, **kw):
if args[:2] == ("volume", "ls"):
return SimpleNamespace(stdout=tool.env["PROD_STATE_VOLUME"].encode())
return SimpleNamespace(
stdout=json.dumps(
[{"Labels": {"frameflow.deploy.project": tool.env["PROD_PROJECT"]}}]
).encode()
)
monkeypatch.setattr(tool, "run", run)
monkeypatch.setattr(tool, "state_io", lambda: json.dumps(record).encode())
if status == "failed":
assert tool.bootstrap_check() is None
record["candidate"]["services"]["pigway-frame-flow"]["volumes"][0]["source"] = (
"/foreign/data"
)
with pytest.raises(ValueError):
tool.bootstrap_check()
def test_synology_initialization_mounts_only_existing_parents_and_creates_leaves(
tool, monkeypatch, tmp_path
):
calls = []
monkeypatch.setattr(tool, "run", lambda *a, **kw: calls.append((a, kw)))
tool.initialize_directories()
args, kw = calls[0]
assert "-v" not in args and "--network" in args
assert [args[i + 1] for i, value in enumerate(args) if value == "--mount"] == [
"type=bind,source=/confirmed,target=/parent-data",
"type=bind,source=/confirmed,target=/parent-config",
]
code = args[args.index("-c") + 1]
import subprocess
import sys
paths = [str(tmp_path / "data"), str(tmp_path / "config")]
# Keep the production permission operations in the script; replace only UID for local test.
code = code.replace("os.chown(p,10333,10333)", "None")
result = subprocess.run(
[sys.executable, "-c", code],
input=json.dumps(paths).encode(),
capture_output=True,
)
assert result.returncode == 0
assert all(
(tmp_path / name).stat().st_mode & 0o777 == 0o750 for name in ("data", "config")
)
(tmp_path / "data" / "keep").write_text("must survive")
result = subprocess.run(
[sys.executable, "-c", code],
input=json.dumps(paths).encode(),
capture_output=True,
)
assert (
result.returncode != 0
and (tmp_path / "data" / "keep").read_text() == "must survive"
)
tool.env["PROD_DATA_DIR"] = "/data"
with pytest.raises(ValueError, match="NAS root"):
tool.initialize_directories()