Compare commits
3 commits
b693ce7467
...
02762cc651
| Author | SHA1 | Date | |
|---|---|---|---|
| 02762cc651 | |||
| 08c7a5a59d | |||
| ebdb77144a |
2 changed files with 24 additions and 3 deletions
25
app.py
25
app.py
|
|
@ -12,7 +12,7 @@ from contextlib import asynccontextmanager
|
||||||
from contextvars import ContextVar
|
from contextvars import ContextVar
|
||||||
|
|
||||||
log = logging.getLogger("butler")
|
log = logging.getLogger("butler")
|
||||||
VERSION = "2.3.7"
|
VERSION = "2.3.8"
|
||||||
|
|
||||||
API_DIR = os.environ.get("API_KEY_DIR", "/data/api")
|
API_DIR = os.environ.get("API_KEY_DIR", "/data/api")
|
||||||
VAULT_CACHE_DIR = os.environ.get("VAULT_CACHE_DIR", "/data/vault-cache")
|
VAULT_CACHE_DIR = os.environ.get("VAULT_CACHE_DIR", "/data/vault-cache")
|
||||||
|
|
@ -2409,7 +2409,7 @@ def _media_tunnel_install_command(role: Literal["vps", "emby"], peer_public_key:
|
||||||
+lines.extend(["", "[Peer]", "PublicKey = {peer_public_key}", "AllowedIPs = {settings['peer']}"])
|
+lines.extend(["", "[Peer]", "PublicKey = {peer_public_key}", "AllowedIPs = {settings['peer']}"])
|
||||||
+if {settings['endpoint']!r}: lines.append("Endpoint = " + {settings['endpoint']!r})
|
+if {settings['endpoint']!r}: lines.append("Endpoint = " + {settings['endpoint']!r})
|
||||||
+if {settings['keepalive']!r}: lines.append("PersistentKeepalive = " + str({settings['keepalive']!r}))
|
+if {settings['keepalive']!r}: lines.append("PersistentKeepalive = " + str({settings['keepalive']!r}))
|
||||||
+candidate = root / "wg-media.conf.candidate"
|
+candidate = root / "wg-media-candidate.conf"
|
||||||
+candidate.write_text("\\n".join(lines) + "\\n")
|
+candidate.write_text("\\n".join(lines) + "\\n")
|
||||||
+os.chmod(candidate, 0o600)
|
+os.chmod(candidate, 0o600)
|
||||||
+check = subprocess.run(["wg-quick", "strip", str(candidate)], text=True, capture_output=True)
|
+check = subprocess.run(["wg-quick", "strip", str(candidate)], text=True, capture_output=True)
|
||||||
|
|
@ -2485,6 +2485,22 @@ def _media_tunnel_rollback_command(remove_keys: bool) -> str:
|
||||||
return f'sudo -n python3 -c "import base64;exec(base64.b64decode(\'{encoded}\'))"'
|
return f'sudo -n python3 -c "import base64;exec(base64.b64decode(\'{encoded}\'))"'
|
||||||
|
|
||||||
|
|
||||||
|
def _media_tunnel_key_cleanup_command() -> str:
|
||||||
|
script = '''import json
|
||||||
|
+from pathlib import Path
|
||||||
|
+root = Path("/app-config/wireguard-media")
|
||||||
|
+if not (root / "wg-media.conf").exists():
|
||||||
|
+ (root / "private.key").unlink(missing_ok=True)
|
||||||
|
+ (root / "public.key").unlink(missing_ok=True)
|
||||||
|
+ status = "new_keys_removed"
|
||||||
|
+else:
|
||||||
|
+ status = "kept_for_existing_config"
|
||||||
|
+print(json.dumps({"status": status}))
|
||||||
|
+'''.replace("\n+", "\n")
|
||||||
|
encoded = base64.b64encode(script.encode()).decode()
|
||||||
|
return f'sudo -n python3 -c "import base64;exec(base64.b64decode(\'{encoded}\'))"'
|
||||||
|
|
||||||
|
|
||||||
def _media_host_target(name: str) -> str:
|
def _media_host_target(name: str) -> str:
|
||||||
inventory = _find_inventory_host(name)
|
inventory = _find_inventory_host(name)
|
||||||
if not inventory:
|
if not inventory:
|
||||||
|
|
@ -2531,6 +2547,11 @@ def _deploy_sascha_media_tunnel() -> dict:
|
||||||
for target, created in reversed(configured):
|
for target, created in reversed(configured):
|
||||||
try: _ssh_json(target, _media_tunnel_rollback_command(created), 60)
|
try: _ssh_json(target, _media_tunnel_rollback_command(created), 60)
|
||||||
except Exception: pass
|
except Exception: pass
|
||||||
|
installed_targets = {target for target, _created in configured}
|
||||||
|
for target, key in ((vps, vps_key), (emby, emby_key)):
|
||||||
|
if target not in installed_targets and key.get("created"):
|
||||||
|
try: _ssh_json(target, _media_tunnel_key_cleanup_command(), 30)
|
||||||
|
except Exception: pass
|
||||||
raise
|
raise
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ def test_health_exposes_current_version():
|
||||||
with TestClient(app.app) as client:
|
with TestClient(app.app) as client:
|
||||||
response = client.get("/health")
|
response = client.get("/health")
|
||||||
assert response.status_code == 200
|
assert response.status_code == 200
|
||||||
assert response.json()["version"] == app.VERSION == "2.3.7"
|
assert response.json()["version"] == app.VERSION == "2.3.8"
|
||||||
|
|
||||||
|
|
||||||
def test_media_handoff_proxies_strict_category_contract(monkeypatch):
|
def test_media_handoff_proxies_strict_category_contract(monkeypatch):
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue