@@ -130,6 +130,48 @@ fn distro_supports_bind_storage_ro(distro: &str) -> bool {
130130 !distro. starts_with ( DISTRO_CENTOS_9 )
131131}
132132
133+ /// Collect and print diagnostics useful for understanding host disk-space
134+ /// exhaustion. This is invoked when launching a VM fails, which we treat as an
135+ /// infrastructure failure (as opposed to a test failure). The most common cause
136+ /// of such failures in CI is the host filesystem running out of space, so we
137+ /// dump what is consuming it: container images, libvirt VMs/disks, the tmt log
138+ /// directory, and the runner's home directory.
139+ fn collect_infra_diagnostics ( sh : & Shell , base_log_dir : & Utf8Path ) {
140+ println ! ( "\n ========================================" ) ;
141+ println ! ( "Infrastructure diagnostics (VM launch failed)" ) ;
142+ println ! ( "========================================" ) ;
143+
144+ // Overall filesystem usage.
145+ println ! ( "\n --- df -h ---" ) ;
146+ let _ = cmd ! ( sh, "df -h" ) . run ( ) ;
147+
148+ // Container images are a frequent disk hog.
149+ println ! ( "\n --- podman images ---" ) ;
150+ let _ = cmd ! ( sh, "podman images" ) . ignore_status ( ) . run ( ) ;
151+
152+ // Libvirt VMs and their backing disks (bcvk may leave these around).
153+ println ! ( "\n --- bcvk libvirt list ---" ) ;
154+ let _ = cmd ! ( sh, "bcvk libvirt list" ) . ignore_status ( ) . run ( ) ;
155+
156+ // Per-VM log/console/journal captures under the tmt log directory.
157+ println ! ( "\n --- du -sh {base_log_dir} ---" ) ;
158+ let _ = cmd ! ( sh, "du -sh {base_log_dir}" ) . ignore_status ( ) . run ( ) ;
159+
160+ // Broad view of the runner's home directory, where caches, the tmt
161+ // workdir, and libvirt storage frequently accumulate. Use `du --max-depth=1`
162+ // on $HOME directly rather than a `$HOME/*` glob: the latter silently skips
163+ // hidden directories like ~/.cache and ~/.local, which is exactly where the
164+ // worst offenders tend to live. Pipe through `sort -h` for readability;
165+ // since xshell does not provide pipes, run it through a shell.
166+ if let Ok ( home) = std:: env:: var ( "HOME" ) {
167+ println ! ( "\n --- du -h --max-depth=1 {home} (sorted) ---" ) ;
168+ let script = "du -h --max-depth=1 \" $1\" 2>/dev/null | sort -h" ;
169+ let _ = cmd ! ( sh, "sh -c {script} sh {home}" ) . ignore_status ( ) . run ( ) ;
170+ }
171+
172+ println ! ( "========================================\n " ) ;
173+ }
174+
133175/// Wait for a bcvk VM to be ready and return SSH connection info
134176#[ context( "Waiting for VM to be ready" ) ]
135177fn wait_for_vm_ready ( sh : & Shell , vm_name : & str ) -> Result < ( u16 , String ) > {
@@ -523,10 +565,18 @@ pub(crate) fn run_tmt(sh: &Shell, args: &RunTmtArgs) -> Result<()> {
523565 . context ( "Launching VM with bcvk" ) ;
524566
525567 if let Err ( e) = launch_result {
568+ // A failure to *launch* the VM (as opposed to a test failing inside
569+ // a running VM) indicates an infrastructure problem on the host -
570+ // most commonly the filesystem running out of space. Continuing to
571+ // launch more VMs is pointless and only generates noise, so collect
572+ // diagnostics and abort the entire run immediately.
526573 eprintln ! ( "Failed to launch VM for plan {}: {:#}" , plan, e) ;
527- all_passed = false ;
528574 test_results. push ( ( plan. to_string ( ) , false , None ) ) ;
529- continue ;
575+ collect_infra_diagnostics ( sh, & base_log_dir) ;
576+ anyhow:: bail!(
577+ "Aborting test run: failed to launch VM for plan {} (infrastructure failure); see diagnostics above" ,
578+ plan
579+ ) ;
530580 }
531581
532582 // Ensure VM cleanup happens even on error (unless --preserve-vm is set)
0 commit comments