|
@@ -11,10 +11,15 @@ use tracing::warn;
|
|
|
|
|
|
|
|
use crate::config::{Config, Node};
|
|
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.
|
|
|
pub async fn ssh_session(config: &Config, node: &Node) -> Result<client::Handle<VerifyingHandler>> {
|
|
pub async fn ssh_session(config: &Config, node: &Node) -> Result<client::Handle<VerifyingHandler>> {
|
|
|
let key = load_secret_key(&config.ssh_key_path)?;
|
|
let key = load_secret_key(&config.ssh_key_path)?;
|
|
|
- let ssh_config = russh::client::Config::default();
|
|
|
|
|
|
|
+ let ssh_config = russh::client::Config {
|
|
|
|
|
+ inactivity_timeout: Some(CONNECT_TIMEOUT),
|
|
|
|
|
+ ..Default::default()
|
|
|
|
|
+ };
|
|
|
let expected_key = Arc::new(std::sync::Mutex::new(node.host_key.clone()));
|
|
let expected_key = Arc::new(std::sync::Mutex::new(node.host_key.clone()));
|
|
|
|
|
|
|
|
if expected_key.lock().unwrap().is_none() {
|
|
if expected_key.lock().unwrap().is_none() {
|
|
@@ -25,8 +30,17 @@ pub async fn ssh_session(config: &Config, node: &Node) -> Result<client::Handle<
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
let handler = VerifyingHandler { expected_key };
|
|
let handler = VerifyingHandler { expected_key };
|
|
|
- let mut session =
|
|
|
|
|
- russh::client::connect(Arc::new(ssh_config), (node.ssh_ip.as_str(), 22), handler).await?;
|
|
|
|
|
|
|
+ let mut session = tokio::time::timeout(
|
|
|
|
|
+ CONNECT_TIMEOUT,
|
|
|
|
|
+ russh::client::connect(Arc::new(ssh_config), (node.ssh_ip.as_str(), 22), handler),
|
|
|
|
|
+ )
|
|
|
|
|
+ .await
|
|
|
|
|
+ .context(format!(
|
|
|
|
|
+ "SSH connect to {}:{} timed out after {}s",
|
|
|
|
|
+ node.ssh_ip,
|
|
|
|
|
+ 22,
|
|
|
|
|
+ CONNECT_TIMEOUT.as_secs()
|
|
|
|
|
+ ))??;
|
|
|
|
|
|
|
|
session
|
|
session
|
|
|
.authenticate_publickey(
|
|
.authenticate_publickey(
|