diff --git a/Dockers/gluetun-pia-wireguard-rotator/rotate.py b/Dockers/gluetun-pia-wireguard-rotator/rotate.py index 6baf111..e16f7d0 100644 --- a/Dockers/gluetun-pia-wireguard-rotator/rotate.py +++ b/Dockers/gluetun-pia-wireguard-rotator/rotate.py @@ -10,7 +10,6 @@ import re import socket import subprocess import sys -import tempfile import time from concurrent.futures import ThreadPoolExecutor, as_completed from datetime import datetime @@ -283,8 +282,11 @@ def rotate_once() -> None: server, mode, latency_results = pick_server(state_path) log(f"Selected endpoint: {server.region} / {server.cn} / {server.ip} (mode={mode})") - with tempfile.TemporaryDirectory(prefix="pia-rotate-") as tmp: - tmp_conf = Path(tmp) / "wg0.conf" + # Write temp file on the same filesystem as the destination so os.replace works + # across Docker bind mounts (/tmp is often a different device than /config). + wg_path.parent.mkdir(parents=True, exist_ok=True) + tmp_conf = wg_path.with_name(wg_path.name + ".tmp") + try: log("Generating WireGuard config via native PIA client") pia.generate_wg_config( require_env("PIA_USER"), @@ -297,10 +299,11 @@ def rotate_once() -> None: if not re.search(r"^\[Interface\]", text, flags=re.MULTILINE): raise SystemExit("Generated config missing [Interface] section") - wg_path.parent.mkdir(parents=True, exist_ok=True) os.replace(tmp_conf, wg_path) wg_path.chmod(0o600) log(f"Wrote {wg_path}") + finally: + tmp_conf.unlink(missing_ok=True) restarted = parse_restart_containers() restart_containers(restarted)