fix: persist should_be_connected state to disk, restore on manager restart
This commit is contained in:
+28
-9
@@ -19,9 +19,27 @@ RDP_PASSWORD = os.environ.get("RDP_PASSWORD", "")
|
||||
RDP_DOMAIN = os.environ.get("RDP_DOMAIN", "")
|
||||
RDP_SECURITY = os.environ.get("RDP_SECURITY", "")
|
||||
|
||||
STATE_FILE = "/tmp/rdp_state.json"
|
||||
|
||||
_lock = threading.Lock()
|
||||
_proc: subprocess.Popen | None = None
|
||||
_should_be_connected = False # set True on /connect, False on /disconnect
|
||||
_should_be_connected = False
|
||||
|
||||
|
||||
def _save_state():
|
||||
try:
|
||||
with open(STATE_FILE, "w") as f:
|
||||
json.dump({"should_be_connected": _should_be_connected}, f)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
|
||||
def _load_state() -> bool:
|
||||
try:
|
||||
with open(STATE_FILE) as f:
|
||||
return json.load(f).get("should_be_connected", False)
|
||||
except Exception:
|
||||
return False
|
||||
|
||||
|
||||
def _build_args():
|
||||
@@ -57,7 +75,6 @@ def _launch():
|
||||
|
||||
|
||||
def _monitor_loop():
|
||||
"""Auto-reconnect if xfreerdp crashes while session should be active."""
|
||||
while True:
|
||||
time.sleep(5)
|
||||
with _lock:
|
||||
@@ -69,9 +86,7 @@ def _monitor_loop():
|
||||
_launch()
|
||||
|
||||
|
||||
threading.Thread(target=_monitor_loop, daemon=True).start()
|
||||
def _anti_idle_loop():
|
||||
"""Move mouse inside xfreerdp window every 30s — works on any remote OS."""
|
||||
env = {**os.environ, "DISPLAY": DISPLAY}
|
||||
toggle = False
|
||||
while True:
|
||||
@@ -87,29 +102,27 @@ def _anti_idle_loop():
|
||||
)
|
||||
win_id = r.stdout.decode().strip().splitlines()[0] if r.stdout.strip() else ""
|
||||
if win_id:
|
||||
# Чередуем позицию — tiny mouse jiggle внутри окна xfreerdp
|
||||
x, y = (960, 540) if toggle else (970, 550)
|
||||
subprocess.run(
|
||||
["xdotool", "mousemove", "--window", win_id, str(x), str(y)],
|
||||
env=env, capture_output=True, timeout=5,
|
||||
)
|
||||
toggle = not toggle
|
||||
subprocess.run(
|
||||
["xdotool", "key", "--window", win_id, "--clearmodifiers", "shift"],
|
||||
env=env, capture_output=True, timeout=5,
|
||||
)
|
||||
log.debug("anti_idle mousemove window=%s pos=%s,%s", win_id, x, y)
|
||||
toggle = not toggle
|
||||
log.debug("anti_idle jiggle window=%s pos=%s,%s", win_id, x, y)
|
||||
else:
|
||||
log.debug("anti_idle: xfreerdp window not found")
|
||||
except Exception as e:
|
||||
log.debug("anti_idle error: %s", e)
|
||||
|
||||
|
||||
threading.Thread(target=_monitor_loop, daemon=True).start()
|
||||
threading.Thread(target=_anti_idle_loop, daemon=True).start()
|
||||
|
||||
|
||||
|
||||
|
||||
class Handler(BaseHTTPRequestHandler):
|
||||
def log_message(self, fmt, *args):
|
||||
pass
|
||||
@@ -141,6 +154,7 @@ class Handler(BaseHTTPRequestHandler):
|
||||
if self.path == "/connect":
|
||||
with _lock:
|
||||
_should_be_connected = True
|
||||
_save_state()
|
||||
if _proc is not None and _proc.poll() is None:
|
||||
self._json(200, {"ok": True, "pid": _proc.pid, "already": True})
|
||||
return
|
||||
@@ -149,6 +163,7 @@ class Handler(BaseHTTPRequestHandler):
|
||||
elif self.path == "/disconnect":
|
||||
with _lock:
|
||||
_should_be_connected = False
|
||||
_save_state()
|
||||
if _proc is not None:
|
||||
_proc.terminate()
|
||||
try:
|
||||
@@ -165,5 +180,9 @@ class Handler(BaseHTTPRequestHandler):
|
||||
if __name__ == "__main__":
|
||||
if not RDP_HOST:
|
||||
log.warning("RDP_HOST not set — connect calls will fail")
|
||||
if _load_state():
|
||||
log.info("restoring state: reconnecting xfreerdp")
|
||||
_should_be_connected = True
|
||||
_launch()
|
||||
log.info("manager started on :7001")
|
||||
HTTPServer(("0.0.0.0", 7001), Handler).serve_forever()
|
||||
|
||||
Reference in New Issue
Block a user