Route automatic staging through qB data mounts

This commit is contained in:
2026-08-03 10:55:13 +00:00
parent 300210c17d
commit f3517bd21b
7 changed files with 80 additions and 28 deletions
+39 -6
View File
@@ -82,6 +82,34 @@ def require_regular_secret(path: Path) -> None:
raise CheckFailure(f"secret must be a non-empty mode-0600 regular file: {path}")
def route_local_path(syncthing: dict[str, Any]) -> str:
"""Resolve the fixed, future automatic ``routes/`` path in the client."""
api_root = PurePosixPath(syncthing["api_root"])
candidate = api_root / "routes"
overrides = syncthing.get("local_path_overrides", {})
if not isinstance(overrides, dict):
raise CheckFailure("syncthing.local_path_overrides must be a table")
matches: list[tuple[int, PurePosixPath, str]] = []
for raw_api, raw_local in overrides.items():
if not isinstance(raw_api, str) or not isinstance(raw_local, str):
raise CheckFailure("syncthing.local_path_overrides entries are invalid")
root = PurePosixPath(raw_api)
try:
relative = candidate.relative_to(root)
except ValueError:
continue
matches.append((len(root.parts), relative, raw_local))
if matches:
_, relative, local_root = max(matches, key=lambda item: item[0])
return str(Path(local_root).joinpath(*relative.parts))
try:
relative = candidate.relative_to(api_root)
except ValueError as exc:
raise CheckFailure("future route path is outside syncthing.api_root") from exc
return str(Path(syncthing["local_root"]).joinpath(*relative.parts))
def run_client_check(container: str, config: str, flag: str) -> None:
result = subprocess.run(
["docker", "exec", container, "archive-client", "--config", config, flag],
@@ -136,15 +164,20 @@ def main(argv: list[str] | None = None) -> int:
qbittorrent = docker_inspect(args.qbittorrent_container)
client_qb = map_path(client, qb["local_root"])
client_sync = map_path(client, sync["local_root"])
syncthing_api = map_path(syncthing, sync["api_root"])
client_route = map_path(client, route_local_path(sync))
syncthing_route = map_path(
syncthing, str(PurePosixPath(sync["api_root"]) / "routes")
)
qb_api = map_path(qbittorrent, qb["api_root"])
require_same_path("Syncthing api_root/local_root", syncthing_api, client_sync)
require_same_path(
"future Syncthing routes/local route mapping",
syncthing_route, client_route,
)
require_same_path("qBittorrent api_root/local_root", qb_api, client_qb)
if client_qb.destination != client_sync.destination:
if client_qb.destination != client_route.destination:
raise CheckFailure(
"qBittorrent and Syncthing roots use separate client bind mounts; "
"hard-link staging would be unavailable"
"qBittorrent and future route roots use separate client bind "
"mounts; hard-link staging would be unavailable"
)
for key in ("shared_token_file",):
require_regular_secret(map_path(client, config[key]).source)