fix: SSH keepalive + auto-reconnect for SFTP and terminal
- Add transport.set_keepalive(30) to all SSH connections - Add SFTPSession.reconnect() method - Auto-reconnect in _refresh_remote with retry on failure - Auto-reconnect before upload/download operations - Guard all remote navigation methods with connection checks - ShellSession.connected wrapped in try/except - Terminal: reset reconnect counter on send failure, increase max to 5 - Terminal: trigger reconnect on send to dead session Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -45,6 +45,9 @@ def _connect_client(server: dict, key_path: str, timeout: int = 15) -> paramiko.
|
||||
try:
|
||||
kwargs["key_filename"] = key_path
|
||||
client.connect(**kwargs)
|
||||
transport = client.get_transport()
|
||||
if transport is not None:
|
||||
transport.set_keepalive(30)
|
||||
return client
|
||||
except paramiko.AuthenticationException:
|
||||
log.debug(f"Key auth failed for {server.get('alias', '?')}, trying password")
|
||||
@@ -68,6 +71,9 @@ def _connect_client(server: dict, key_path: str, timeout: int = 15) -> paramiko.
|
||||
kwargs["look_for_keys"] = False
|
||||
kwargs["allow_agent"] = False
|
||||
client.connect(**kwargs)
|
||||
transport = client.get_transport()
|
||||
if transport is not None:
|
||||
transport.set_keepalive(30)
|
||||
return client
|
||||
|
||||
raise Exception(f"No auth method for {server.get('alias', 'unknown')}")
|
||||
@@ -92,11 +98,14 @@ class ShellSession:
|
||||
|
||||
@property
|
||||
def connected(self) -> bool:
|
||||
return (
|
||||
self._channel is not None
|
||||
and self._channel.get_transport() is not None
|
||||
and self._channel.get_transport().is_active()
|
||||
)
|
||||
try:
|
||||
return (
|
||||
self._channel is not None
|
||||
and self._channel.get_transport() is not None
|
||||
and self._channel.get_transport().is_active()
|
||||
)
|
||||
except Exception:
|
||||
return False
|
||||
|
||||
def connect(self):
|
||||
self._client = _connect_client(self.server, self.key_path)
|
||||
@@ -334,6 +343,12 @@ class SFTPSession:
|
||||
self._client = _connect_client(self.server, self.key_path)
|
||||
self._sftp = self._client.open_sftp()
|
||||
|
||||
def reconnect(self):
|
||||
"""Disconnect and re-establish SFTP session."""
|
||||
self.disconnect()
|
||||
time.sleep(0.2)
|
||||
self.connect()
|
||||
|
||||
def disconnect(self):
|
||||
if self._sftp:
|
||||
try:
|
||||
|
||||
Reference in New Issue
Block a user