fix: persist should_be_connected state to disk, restore on manager restart

This commit is contained in:
2026-05-04 07:15:31 +00:00
parent bff5ffac1c
commit dddeb26946
+28 -9
View File
@@ -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()