13 Commits

Author SHA1 Message Date
Максимов Владимир Сергеевич cb0a5db3b5 Merge PR #174: nonblocking SSH and circuit breaker
# Conflicts:
#	translations/en.json
#	translations/fa.json
#	translations/fr.json
#	translations/ru.json
#	translations/zh.json
2026-09-14 12:40:26 +03:00
leonidorlov-hash 1248ce68c0 feat(servers): configurable SSH circuit-breaker base cooldown
Per-server setting ssh_cooldown_base (default 30s, range 5-300) for the
SSH circuit breaker introduced with the event-loop fix. Editable in the
server management modal with a 'leave it alone when healthy' hint, and
shown in the host tuning modal. get_ssh applies edits to the pooled
connection without dropping it.
2026-09-13 23:48:10 +03:00
leonidorlov-hash 53f908733c fix(ssh): lower transport keepalive 30s -> 15s
Long-lived pooled transports were dying between polls on servers behind
stricter NAT/firewall state timeouts, forcing a full SSH handshake on
nearly every poll cycle.
2026-09-13 23:48:10 +03:00
leonidorlov-hash e7740ffbb0 fix(ssh): exponential-backoff circuit breaker per server
Consecutive connect failures now grow the cooldown 30s -> 60s -> 120s,
capped at 300s, and the first successful connect resets the streak.
connect() itself records failures, so the reconnect-and-retry path in
_run_command_locked feeds the breaker too; fail-fast 'backing off Ns'
behavior is unchanged.
2026-09-13 23:44:40 +03:00
leonidorlov-hash 42146681d1 fix(ssh): feed the sudo password via channel stdin, never the command line 2026-09-11 01:01:11 +03:00
hell 2cb442fe04 fix(ssh): say what happened when a command dies with the transport
Paramiko raises a bare EOFError/SSHException when the transport goes away
mid-command, and `str(exc)` on those is an empty string. run_command passes
that empty string on as the failure reason, and the managers interpolate it
straight into their messages - about 30 `{err}` sites across managers/ - so a
dropped connection surfaces as "Failed to configure container: " with nothing
after the colon, and in the log as "Command exited with code -1: ".

The SSH layer now falls back to the exception type when the message is empty,
and labels the read failure explicitly: "SSH connection lost while running the
command (EOFError)". Three call sites: the two reconnect paths and the
stdout/stderr read.

Seen in practice where a panel manages a host that rate-limits SSH (ufw's
`limit` on port 22): a burst of connections gets dropped mid-command and every
resulting error message was blank.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-08 22:25:44 +07:00
leonidorlov-hash e9536a775a fix(ssh): serialize command/SFTP execution on pooled connections (#125)
The pooled SSHManager is shared between request handlers and background
threads (traffic sync, conn monitor). When one side's exec failed, its
reconnect closed the shared client while the other side was mid-command:
'NoneType open_session', EOFError in open_sftp, a burst of 500s, then
30s of fast-fail from the connect cooldown.

Add an RLock around exec_command and all SFTP operations (RLock because
run_command retries by re-entering itself). Lock ordering is
exec -> conn, connect/disconnect never take the exec lock, so no
deadlock. Failed execs now serialize the reconnect too: other threads
simply wait and then run on the fresh transport.
2026-09-05 00:13:43 +03:00
leonidorlov-hash c215b5fdab fix(ssh): retry once on connect timeout (tolerates random SYN loss) 2026-08-30 07:44:14 +03:00
leonidorlov-hash a662a029ab fix(ssh): pooled connections ignore legacy per-request disconnect() 2026-08-30 07:44:14 +03:00
leonidorlov-hash 2ff82196ef fix(ssh): ensure_connected in SFTP methods too 2026-08-30 07:44:14 +03:00
leonidorlov-hash 772ce96cd4 fix(ssh): devops hardening of the connection pool
- per-manager lock around connect/disconnect: UI handler and background
  monitor can no longer race a half-built transport
- transport keepalive 30s: NAT/firewalls won't silently drop idle tunnels
- one reconnect+retry when exec fails on a dead-but-'active' transport
  instead of surfacing a spurious error to the UI
2026-08-30 07:44:14 +03:00
leonidorlov-hash eb87c2153c perf(ssh): reuse long-lived SSH connections + cache config reads
- SSHManager.ensure_connected(): keep the transport alive, reconnect only
  when it died; run_command auto-heals the connection
- app.py: pool SSHManager per (host, port, username) instead of a fresh
  TCP+SSH handshake for every API call - the main cause of UI timeouts on
  high-latency servers (each 6s refresh paid a 1-2s handshake)
- awg_manager: 10s TTL cache for config path resolution and server config
  reads (was: the same awg0.conf cat'ed 3-4x per refresh); caches are
  invalidated on save_server_config
2026-08-30 07:44:14 +03:00
Public relations & Virtual technology 29def95df8 v1.4.3
Add SOCKS5 support
Add AdGuard Home integration
Add node status and latency tracking
Add drag-and-drop server management
Upgrade Xray from v1.8 to v26.3.27 with backward compatibility
Fix Telemt dependency installation
Extend Telegram bot to support all protocols
Improve server cleanup process
Enhance API structure (system routes moved to a separate group)
Add JWT token generation for external integrations
2026-05-04 16:01:06 +03:00