@@ -68,7 +68,7 @@ pub fn run_with_ssh(manager_conn: UnixStream) -> Result<(), Box<dyn std::error::
68 tracing::debug!(ssh_user = %ssh_user, "loaded instance config");
68 tracing::debug!(ssh_user = %ssh_user, "loaded instance config");
70 let _manager_conn = manager_conn;
70 let _manager_conn = manager_conn;
71− wait_for_vm_ipv4(&instance_dir, Duration::from_secs(120))?;
71+ wait_for_vm_ipv4(&instance_dir, Duration::from_secs(480))?;
73 let ip = load_or_create_instance_config(&instance_dir)?
73 let ip = load_or_create_instance_config(&instance_dir)?
@@ -242,19 +242,41 @@ fn wait_for_vm_ipv4(
242) -> Result<(), Box<dyn std::error::Error>> {
242) -> Result<(), Box<dyn std::error::Error>> {
243 let start = Instant::now();
243 let start = Instant::now();
244 let mut next_log_at = start + Duration::from_secs(10);
244 let mut next_log_at = start + Duration::from_secs(10);
245+ let mut next_status_check = start;
245 tracing::info!("waiting for vm ipv4");
246 tracing::info!("waiting for vm ipv4");
246 let status_path = instance_dir.join(STATUS_FILE_NAME);
247 let status_path = instance_dir.join(STATUS_FILE_NAME);
247 let mut last_status: Option<String> = None;
248 let mut last_status: Option<String> = None;
249+ let mut status_missing = true;
248 let mut once_hint = false;
250 let mut once_hint = false;
250 let config = load_or_create_instance_config(instance_dir)?;
252 let config = load_or_create_instance_config(instance_dir)?;
251 if config.vm_ipv4.is_some() {
253 if config.vm_ipv4.is_some() {
254+ let _ = fs::remove_file(&status_path);
252 return Ok(());
255 return Ok(());
254 if start.elapsed() > timeout {
257 if start.elapsed() > timeout {
258+ let _ = fs::remove_file(&status_path);
255 return Err("Timed out waiting for VM IPv4".into());
259 return Err("Timed out waiting for VM IPv4".into());
261+ let now = Instant::now();
262+ if now >= next_status_check {
263+ match fs::read_to_string(&status_path) {
265+ status_missing = false;
266+ let status = status.trim().to_string();
267+ if !status.is_empty() && last_status.as_deref() != Some(status.as_str()) {
268+ tracing::info!("[background]: {}", status);
269+ last_status = Some(status);
270+ next_log_at = now + Duration::from_secs(20);
274+ status_missing = true;
277+ next_status_check = now + Duration::from_millis(500);
257− if Instant::now() >= next_log_at {
279+ if now >= next_log_at {
258 let waited = start.elapsed();
280 let waited = start.elapsed();
259 if waited.as_secs() > 15 && !once_hint {
281 if waited.as_secs() > 15 && !once_hint {
260 tracing::info!(
282 tracing::info!(
@@ -262,16 +284,10 @@ fn wait_for_vm_ipv4(
263 once_hint = true;
285 once_hint = true;
265− if let Ok(status) = fs::read_to_string(&status_path) {
287+ if status_missing {
266− let status = status.trim().to_string();
267− if !status.is_empty() && last_status.as_deref() != Some(status.as_str()) {
268− tracing::info!("[background]: {}", status);
269− last_status = Some(status);
272 tracing::info!("still waiting for vm ipv4, {}s elapsed", waited.as_secs(),);
288 tracing::info!("still waiting for vm ipv4, {}s elapsed", waited.as_secs(),);
274− next_log_at += Duration::from_secs(10);
290+ next_log_at += Duration::from_secs(20);
276 thread::sleep(Duration::from_millis(200));
292 thread::sleep(Duration::from_millis(200));