use std::time::Duration;
use isoloom_manifest::Step;
use super::Cx;
use super::step::{Hold, once};
use crate::Result;
use crate::error::Error;
use crate::events::WarningCode;
use crate::ssh::Wait;
const RETRY: Duration = Duration::from_secs(5);
const SSH_FAILED: i32 = 255;
pub(crate) async fn run(cx: &Cx<'_>, list: &str, step: &Step, observe: &mut (dyn FnMut(&str) + Send), wait: &Wait) -> Result<()> {
let deadline = tokio::time::Instant::now() + wait.limit;
let mut said = false;
loop {
let mut ended = once(cx, list, step, observe, Hold::UntilOutput).await?;
let unreachable = ended.exit.code == Some(SSH_FAILED) && !ended.printed;
if !unreachable {
ended.show_held(cx, step, observe);
return ended.result(cx, step);
}
if tokio::time::Instant::now() >= deadline {
return Err(Error::Unreachable {
step: step.id.to_string(),
login: wait.login.clone(),
after_s: wait.limit.as_secs(),
reason: cx.events.mask(ended.tail.join(" ").trim()),
});
}
if !said {
let note = format!("{} doesn't answer over SSH yet; trying again for up to {}s", wait.login, wait.limit.as_secs());
cx.events.warning(WarningCode::Retrying, ¬e);
said = true;
}
tokio::time::sleep(RETRY).await;
}
}