f
This commit is contained in:
91
TUI.py
91
TUI.py
@@ -5,6 +5,8 @@ from __future__ import annotations
|
||||
import json
|
||||
import re
|
||||
import sys
|
||||
import subprocess
|
||||
import asyncio
|
||||
from pathlib import Path
|
||||
from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple
|
||||
|
||||
@@ -438,6 +440,8 @@ class PipelineHubApp(App):
|
||||
self._pipeline_running = False
|
||||
self._pipeline_worker: Any = None
|
||||
self._selected_row_index: int = 0
|
||||
self._zt_server_proc: Optional[subprocess.Popen] = None
|
||||
self._zt_server_last_config: Optional[str] = None
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# Layout
|
||||
@@ -499,6 +503,93 @@ class PipelineHubApp(App):
|
||||
if self.worker_table:
|
||||
self.worker_table.add_columns("ID", "Type", "Status", "Details")
|
||||
|
||||
self.set_interval(5.0, self._manage_zerotier_server)
|
||||
|
||||
def on_unmount(self) -> None:
|
||||
if hasattr(self, "_zt_server_proc") and self._zt_server_proc:
|
||||
try:
|
||||
self._zt_server_proc.terminate()
|
||||
self._zt_server_proc.wait(timeout=2)
|
||||
except Exception:
|
||||
try:
|
||||
self._zt_server_proc.kill()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
async def _manage_zerotier_server(self) -> None:
|
||||
"""Background task to start/stop the ZeroTier storage server based on config."""
|
||||
try:
|
||||
cfg = load_config()
|
||||
except Exception:
|
||||
return
|
||||
|
||||
zt_conf = cfg.get("networking", {}).get("zerotier", {})
|
||||
serve_target = zt_conf.get("serve")
|
||||
port = zt_conf.get("port") or 999
|
||||
api_key = zt_conf.get("api_key")
|
||||
|
||||
# Config hash to detect changes
|
||||
config_id = f"{serve_target}|{port}|{api_key}"
|
||||
if config_id == self._zt_server_last_config:
|
||||
# Check if proc is still alive
|
||||
if self._zt_server_proc:
|
||||
if self._zt_server_proc.poll() is not None:
|
||||
# Crashed?
|
||||
self._zt_server_proc = None
|
||||
self.notify("ZeroTier Host Server stopped unexpectedly", severity="warning")
|
||||
else:
|
||||
return
|
||||
elif not serve_target:
|
||||
return
|
||||
|
||||
# Stop existing if config changed
|
||||
if self._zt_server_proc:
|
||||
self.notify("Stopping ZeroTier Host Server (config change)...")
|
||||
self._zt_server_proc.terminate()
|
||||
self._zt_server_proc.wait()
|
||||
self._zt_server_proc = None
|
||||
|
||||
self._zt_server_last_config = config_id
|
||||
|
||||
if not serve_target:
|
||||
return
|
||||
|
||||
# Resolve path
|
||||
storage_path = None
|
||||
folders = cfg.get("store", {}).get("folder", {})
|
||||
for name, block in folders.items():
|
||||
if name.lower() == serve_target.lower():
|
||||
storage_path = block.get("path") or block.get("PATH")
|
||||
break
|
||||
|
||||
if not storage_path:
|
||||
# Fallback to direct path
|
||||
storage_path = serve_target
|
||||
|
||||
if not Path(storage_path).exists():
|
||||
return
|
||||
|
||||
# Start server
|
||||
cmd = [sys.executable, str(REPO_ROOT / "scripts" / "remote_storage_server.py"),
|
||||
"--storage-path", str(storage_path),
|
||||
"--port", str(port)]
|
||||
if api_key:
|
||||
cmd += ["--api-key", str(api_key)]
|
||||
|
||||
try:
|
||||
# Run in a way that doesn't create a visible window on Windows if possible,
|
||||
# though for scripts it's fine.
|
||||
self._zt_server_proc = subprocess.Popen(
|
||||
cmd,
|
||||
stdout=subprocess.DEVNULL,
|
||||
stderr=subprocess.DEVNULL,
|
||||
cwd=str(REPO_ROOT)
|
||||
)
|
||||
self.notify(f"ZeroTier Host: Sharing '{serve_target}' on port {port}")
|
||||
except Exception as e:
|
||||
self.notify(f"Failed to start ZeroTier server: {e}", severity="error")
|
||||
self._zt_server_proc = None
|
||||
|
||||
# Initialize the store choices cache at startup (filters disabled stores)
|
||||
try:
|
||||
from cmdlet._shared import SharedArgs
|
||||
|
||||
Reference in New Issue
Block a user