use std::thread;
use std::time::{Duration, Instant};
use indicatif::ProgressBar;
use crate::config::{GuestOs, Result, TestbedError, VmProfile};
pub fn wait_for_ssh(profile: &VmProfile, timeout_secs: u64) -> Result<()> {
let port = profile.ssh_port;
let deadline = Instant::now() + Duration::from_secs(timeout_secs);
let pb = ProgressBar::new_spinner();
pb.set_message(format!("Waiting for SSH on port {port}..."));
pb.enable_steady_tick(Duration::from_millis(200));
while Instant::now() < deadline {
if std::net::TcpStream::connect(("127.0.0.1", port)).is_ok() {
pb.finish_with_message(format!("SSH ready on 127.0.0.1:{port}"));
return Ok(());
}
thread::sleep(Duration::from_secs(2));
}
pb.finish_with_message("SSH wait timed out");
Err(TestbedError::SshFailed {
port,
source: anyhow::anyhow!("SSH not available after {timeout_secs}s"),
})
}
pub fn wait_for_winrm(profile: &VmProfile, timeout_secs: u64) -> Result<()> {
let port = profile.winrm_port.ok_or_else(|| {
TestbedError::WinrmNotReachable { port: 0 }
})?;
let deadline = Instant::now() + Duration::from_secs(timeout_secs);
let pb = ProgressBar::new_spinner();
pb.set_message(format!("Waiting for WinRM on port {port}..."));
pb.enable_steady_tick(Duration::from_millis(200));
while Instant::now() < deadline {
if std::net::TcpStream::connect(("127.0.0.1", port)).is_ok() {
pb.finish_with_message(format!("WinRM ready on 127.0.0.1:{port}"));
return Ok(());
}
thread::sleep(Duration::from_secs(2));
}
pb.finish_with_message("WinRM wait timed out");
Err(TestbedError::WinrmNotReachable { port })
}
pub fn wait_for_vm(profile: &VmProfile, timeout_secs: u64) -> Result<()> {
wait_for_ssh(profile, timeout_secs)?;
if profile.os == GuestOs::Windows {
thread::sleep(Duration::from_secs(5));
wait_for_winrm(profile, timeout_secs)?;
}
Ok(())
}