Quellcode durchsuchen

fix(ssh): separate ssh_session_follow with no inactivity timeout

The 5s inactivity_timeout on ssh_session (added in cb4c15e) fixed SSH
hangs on doctor checks but killed long-lived streaming commands like
 (docker logs -f) whenever output paused for >5s.

Extracted a private ssh_session_with_timeout helper and added:
- ssh_session() — keeps 5s connect + inactivity timeout (doctor health)
- ssh_session_follow() — connect timeout only, no inactivity timeout
  (used by run_ssh_follow for logs --follow and similar streams)
Alexander Korolev vor 4 Monaten
Ursprung
Commit
8f000e671a
1 geänderte Dateien mit 22 neuen und 3 gelöschten Zeilen
  1. 22 3
      src/ssh.rs

+ 22 - 3
src/ssh.rs

@@ -13,11 +13,29 @@ use crate::config::{Config, Node};
 
 const CONNECT_TIMEOUT: Duration = Duration::from_secs(5);
 
-/// Establishes an SSH session to a node using the config credentials.
+/// Establishes an SSH session to a node using the config credentials, with a 5s connect
+/// and inactivity timeout.  Use [`ssh_session_follow`] for long-lived streaming commands.
 pub async fn ssh_session(config: &Config, node: &Node) -> Result<client::Handle<VerifyingHandler>> {
+    ssh_session_with_timeout(config, node, Some(CONNECT_TIMEOUT)).await
+}
+
+/// Like [`ssh_session`] but with no inactivity timeout — suitable for long-lived
+/// streaming commands such as `docker logs -f`.
+pub async fn ssh_session_follow(
+    config: &Config,
+    node: &Node,
+) -> Result<client::Handle<VerifyingHandler>> {
+    ssh_session_with_timeout(config, node, None).await
+}
+
+async fn ssh_session_with_timeout(
+    config: &Config,
+    node: &Node,
+    inactivity_timeout: Option<Duration>,
+) -> Result<client::Handle<VerifyingHandler>> {
     let key = load_secret_key(&config.ssh_key_path)?;
     let ssh_config = russh::client::Config {
-        inactivity_timeout: Some(CONNECT_TIMEOUT),
+        inactivity_timeout,
         ..Default::default()
     };
     let expected_key = Arc::new(std::sync::Mutex::new(node.host_key.clone()));
@@ -131,6 +149,7 @@ pub async fn run_ssh_with_retry(
 }
 
 /// Runs a command via SSH and streams output to stdout (for follow mode).
+/// Uses a session with no inactivity timeout so long-lived streams are not killed.
 pub async fn run_ssh_follow(
     config: &Config,
     node: &Node,
@@ -142,7 +161,7 @@ pub async fn run_ssh_follow(
         return Ok(());
     }
 
-    let session = ssh_session(config, node).await?;
+    let session = ssh_session_follow(config, node).await?;
     let mut channel = session.channel_open_session().await?;
     channel.exec(true, command.as_bytes()).await?;