Template
Fix mita RPC socket path and rate-limit heal recovery.
This commit is contained in:
@@ -103,7 +103,7 @@ else:
|
||||
application_path = os.path.dirname(__file__)
|
||||
|
||||
DATA_FILE = os.path.join(application_path, 'data.json') # legacy JSON; used only for one-shot import / export
|
||||
CURRENT_VERSION = "v2.6.8"
|
||||
CURRENT_VERSION = "v2.6.9"
|
||||
RELEASES_REPO_URL = repo_url()
|
||||
RELEASES_API_LATEST = api_latest_url()
|
||||
BIN_DIR = os.environ.get('TUNNEL_BIN_DIR', os.path.join(application_path, 'bin'))
|
||||
|
||||
+44
-35
@@ -21,7 +21,9 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
MIERU_RELEASE = '3.28.0'
|
||||
GITHUB_RELEASE = f'https://github.com/enfein/mieru/releases/download/v{MIERU_RELEASE}'
|
||||
MITA_SOCK = '/var/run/mita.sock'
|
||||
# Official mita UDS (v3.x). Older docs sometimes mention /var/run/mita.sock.
|
||||
MITA_SOCK = '/var/run/mita/mita.sock'
|
||||
MITA_SOCK_LEGACY = '/var/run/mita.sock'
|
||||
# Official package persists applied config here. If this file has portBindings
|
||||
# but no users, `mita run` (systemd) auto-starts the proxy and FATAL-exits
|
||||
# with "socks5 server listening failed: no user found", crashing the daemon.
|
||||
@@ -246,10 +248,14 @@ class MieruManager:
|
||||
self.ssh.run_sudo_command(
|
||||
f"systemctl stop {self.SERVICE_NAME} 2>/dev/null || true; "
|
||||
f"systemctl reset-failed {self.SERVICE_NAME} 2>/dev/null || true; "
|
||||
f"rm -f {_q(MITA_SOCK)} /var/run/mita/*.sock "
|
||||
f"{_q(MITA_CONFIG_PB)} {_q(MITA_CONFIG_JSON)} 2>/dev/null || true",
|
||||
f"rm -f {_q(MITA_SOCK)} {_q(MITA_SOCK_LEGACY)} /var/run/mita/*.sock "
|
||||
f"{_q(MITA_CONFIG_PB)} {_q(MITA_CONFIG_JSON)} 2>/dev/null || true; "
|
||||
f"mkdir -p /var/run/mita /etc/mita 2>/dev/null || true",
|
||||
timeout=60,
|
||||
)
|
||||
# systemd StartLimitBurst: wait out "Start request repeated too quickly".
|
||||
time.sleep(6)
|
||||
|
||||
clients = self._ensure_bootstrap_clients(self._read_clients())
|
||||
self._write_clients(clients)
|
||||
meta = self._read_metadata()
|
||||
@@ -258,18 +264,27 @@ class MieruManager:
|
||||
self._write_file(self.config_path, json.dumps(config, indent=2))
|
||||
|
||||
self.ssh.run_sudo_command(
|
||||
f"systemctl reset-failed {self.SERVICE_NAME} 2>/dev/null || true; "
|
||||
f"systemctl start {self.SERVICE_NAME}",
|
||||
timeout=60,
|
||||
)
|
||||
if not self._wait_for_rpc(timeout=45):
|
||||
journal, _, _ = self.ssh.run_sudo_command(
|
||||
f"journalctl -u {self.SERVICE_NAME} -n 40 --no-pager 2>&1",
|
||||
timeout=30,
|
||||
)
|
||||
raise RuntimeError(
|
||||
'mita daemon still not ready after heal. '
|
||||
f'journal: {(journal or "").strip()[-500:]}'
|
||||
if not self._wait_for_rpc(timeout=60):
|
||||
# Second attempt after another rate-limit window.
|
||||
self.ssh.run_sudo_command(
|
||||
f"systemctl reset-failed {self.SERVICE_NAME} 2>/dev/null || true; "
|
||||
f"systemctl restart {self.SERVICE_NAME}",
|
||||
timeout=60,
|
||||
)
|
||||
time.sleep(3)
|
||||
if not self._wait_for_rpc(timeout=45):
|
||||
journal, _, _ = self.ssh.run_sudo_command(
|
||||
f"journalctl -u {self.SERVICE_NAME} -n 50 --no-pager 2>&1",
|
||||
timeout=30,
|
||||
)
|
||||
raise RuntimeError(
|
||||
'mita daemon still not ready after heal. '
|
||||
f'journal: {(journal or "").strip()[-600:]}'
|
||||
)
|
||||
out, err, code = self._mita_cli(
|
||||
['apply', 'config', _q(self.config_path)],
|
||||
timeout=60,
|
||||
@@ -284,7 +299,8 @@ class MieruManager:
|
||||
def _ensure_daemon(self, log=None):
|
||||
"""Ensure mita systemd unit is up and RPC socket answers."""
|
||||
self.ssh.run_sudo_command(
|
||||
f"systemctl enable {self.SERVICE_NAME} 2>/dev/null || true",
|
||||
f"systemctl enable {self.SERVICE_NAME} 2>/dev/null || true; "
|
||||
f"mkdir -p /var/run/mita /etc/mita 2>/dev/null || true",
|
||||
timeout=30,
|
||||
)
|
||||
# Official package expects the operating user in group `mita`.
|
||||
@@ -308,37 +324,30 @@ class MieruManager:
|
||||
timeout=60,
|
||||
)
|
||||
if not self._wait_for_rpc(timeout=45):
|
||||
# Crash loop / stale socket — wipe broken store and recover.
|
||||
if self._daemon_needs_heal():
|
||||
self._heal_mita_store(log)
|
||||
else:
|
||||
self.ssh.run_sudo_command(
|
||||
f"systemctl stop {self.SERVICE_NAME} 2>/dev/null || true; "
|
||||
f"rm -f {_q(MITA_SOCK)} /var/run/mita/*.sock 2>/dev/null || true; "
|
||||
f"systemctl start {self.SERVICE_NAME}",
|
||||
timeout=60,
|
||||
)
|
||||
if not self._wait_for_rpc(timeout=45):
|
||||
# Last resort: heal even if journal didn't match yet.
|
||||
self._heal_mita_store(log)
|
||||
# Crash loop / wrong socket / rate-limit — wipe store and recover.
|
||||
self._heal_mita_store(log)
|
||||
if log is not None:
|
||||
log.append('mita daemon is active')
|
||||
|
||||
def _wait_for_rpc(self, timeout=30):
|
||||
deadline = time.time() + timeout
|
||||
sock_check = (
|
||||
f"(test -S {_q(MITA_SOCK)} || test -S {_q(MITA_SOCK_LEGACY)}) && echo ok"
|
||||
)
|
||||
while time.time() < deadline:
|
||||
sock_out, _, sock_code = self.ssh.run_sudo_command(
|
||||
f"test -S {_q(MITA_SOCK)} && echo ok"
|
||||
# Prefer CLI status: if it answers IDLE/RUNNING, RPC is up
|
||||
# regardless of which sock path we expected.
|
||||
status_out, _, status_code = self.ssh.run_sudo_command(
|
||||
'mita status 2>&1',
|
||||
timeout=20,
|
||||
)
|
||||
text = (status_out or '').upper()
|
||||
if status_code == 0 and ('IDLE' in text or 'RUNNING' in text):
|
||||
return True
|
||||
sock_out, _, sock_code = self.ssh.run_sudo_command(sock_check)
|
||||
if sock_code == 0 and 'ok' in (sock_out or ''):
|
||||
status_out, _, status_code = self.ssh.run_sudo_command(
|
||||
'mita status 2>&1',
|
||||
timeout=20,
|
||||
)
|
||||
text = (status_out or '').upper()
|
||||
if status_code == 0 and ('IDLE' in text or 'RUNNING' in text):
|
||||
return True
|
||||
# Socket exists but CLI still races — brief pause.
|
||||
time.sleep(1)
|
||||
continue
|
||||
time.sleep(1.5)
|
||||
return False
|
||||
|
||||
|
||||
Reference in New Issue
Block a user