From 464503218652139d412b42ff0f00d2be2e89a698 Mon Sep 17 00:00:00 2001 From: Bruce Ashfield Date: Sun, 15 Feb 2026 20:25:41 +0000 Subject: vxn: fix non-interactive mode for clean container output Fix several issues preventing non-interactive mode (vxn --no-daemon run) from showing clean container output: - Fix console capture: check DAEMON_MODE instead of DAEMON_SOCKET in Xen backend so ephemeral runs use xl console capture instead of the daemon socat bridge (DAEMON_SOCKET is always set, DAEMON_MODE is only "start" for actual daemon launches) - Fix race condition: add post-loop marker detection after VM exits, with 2s delay for xl console to flush its buffer - Add stdbuf -oL to xl console for line-buffered output - Suppress mke2fs stdout (was only redirecting stderr) - Suppress kernel console messages during VM lifecycle in non-verbose mode - Fix grep -P (Perl regex) for BusyBox compatibility in exit code parsing - Preserve temp directory on failure for debugging - Fix hardcoded "QEMU" in error messages to "VM" Signed-off-by: Bruce Ashfield --- .../vcontainer/files/vrunner-backend-xen.sh | 4 +- recipes-containers/vcontainer/files/vrunner.sh | 47 ++++++++++++++++++---- 2 files changed, 41 insertions(+), 10 deletions(-) (limited to 'recipes-containers/vcontainer') diff --git a/recipes-containers/vcontainer/files/vrunner-backend-xen.sh b/recipes-containers/vcontainer/files/vrunner-backend-xen.sh index 89e26b6b..9f423dc6 100644 --- a/recipes-containers/vcontainer/files/vrunner-backend-xen.sh +++ b/recipes-containers/vcontainer/files/vrunner-backend-xen.sh @@ -357,7 +357,7 @@ hv_start_vm_background() { # Use the domain name as VM identifier HV_VM_PID="$$" # Use our PID as a placeholder for compatibility - if [ -n "$DAEMON_SOCKET" ]; then + if [ "$DAEMON_MODE" = "start" ]; then # Daemon mode: bridge xl console (hvc1) to the daemon unix socket # xl console -n 1 connects to the second PV console (hvc1) socat "UNIX-LISTEN:$DAEMON_SOCKET,fork" "EXEC:xl console -n 1 $HV_DOMNAME" & @@ -366,7 +366,7 @@ hv_start_vm_background() { else # Ephemeral mode: capture guest console (hvc0) to log file # so the monitoring loop in vrunner.sh can see output markers - xl console "$HV_DOMNAME" >> "$log_file" 2>&1 & + stdbuf -oL xl console "$HV_DOMNAME" >> "$log_file" 2>&1 & _XEN_CONSOLE_PID=$! log "DEBUG" "Console capture started (PID: $_XEN_CONSOLE_PID)" fi diff --git a/recipes-containers/vcontainer/files/vrunner.sh b/recipes-containers/vcontainer/files/vrunner.sh index 8ad45afe..04f0e39e 100755 --- a/recipes-containers/vcontainer/files/vrunner.sh +++ b/recipes-containers/vcontainer/files/vrunner.sh @@ -1019,13 +1019,13 @@ if [ -n "$INPUT_PATH" ] && [ "$INPUT_TYPE" != "none" ]; then dd if=/dev/zero of="$INPUT_IMG" bs=1M count=$SIZE_MB 2>/dev/null if [ -d "$INPUT_PATH" ]; then - mke2fs -t ext4 -d "$INPUT_PATH" "$INPUT_IMG" 2>/dev/null + mke2fs -t ext4 -d "$INPUT_PATH" "$INPUT_IMG" >/dev/null 2>&1 else # Single file - create temp dir with the file EXTRACT_DIR="$TEMP_DIR/input-extract" mkdir -p "$EXTRACT_DIR" cp "$INPUT_PATH" "$EXTRACT_DIR/" - mke2fs -t ext4 -d "$EXTRACT_DIR" "$INPUT_IMG" 2>/dev/null + mke2fs -t ext4 -d "$EXTRACT_DIR" "$INPUT_IMG" >/dev/null 2>&1 fi DISK_OPTS="-drive file=$INPUT_IMG,if=virtio,format=raw" @@ -1054,7 +1054,7 @@ if [ -n "$STATE_DIR" ] && ! type hv_skip_state_disk >/dev/null 2>&1; then log "INFO" "Creating new state disk at $STATE_IMG..." # Create 2GB state disk for Docker storage dd if=/dev/zero of="$STATE_IMG" bs=1M count=2048 2>/dev/null - mke2fs -t ext4 "$STATE_IMG" 2>/dev/null + mke2fs -t ext4 "$STATE_IMG" >/dev/null 2>&1 else log "INFO" "Using existing state disk: $STATE_IMG" fi @@ -1087,7 +1087,7 @@ if [ -n "$INPUT_STORAGE" ] && [ -z "$STATE_DIR" ]; then log "DEBUG" "Tar size: ${TAR_SIZE_KB}KB, State disk: ${STATE_SIZE_MB}MB" dd if=/dev/zero of="$STATE_IMG" bs=1M count=$STATE_SIZE_MB 2>/dev/null - mke2fs -t ext4 "$STATE_IMG" 2>/dev/null + mke2fs -t ext4 "$STATE_IMG" >/dev/null 2>&1 # Mount and extract tar MOUNT_DIR="$TEMP_DIR/state-mount" @@ -1109,7 +1109,7 @@ if [ -n "$INPUT_STORAGE" ] && [ -z "$STATE_DIR" ]; then EXTRACT_DIR="$TEMP_DIR/state-extract" mkdir -p "$EXTRACT_DIR" tar --no-same-owner --strip-components=1 --exclude=volumes/backingFsBlockDev -xf "$INPUT_STORAGE" -C "$EXTRACT_DIR" - mke2fs -t ext4 -d "$EXTRACT_DIR" "$STATE_IMG" 2>/dev/null + mke2fs -t ext4 -d "$EXTRACT_DIR" "$STATE_IMG" >/dev/null 2>&1 fi # Use cache=directsync to ensure writes are flushed to disk @@ -1392,6 +1392,14 @@ fi # Non-interactive mode: run VM in background and capture output VM_OUTPUT="$TEMP_DIR/vm_output.txt" + +# Suppress kernel console messages in non-verbose mode to keep output clean +SAVED_PRINTK="" +if [ "$VERBOSE" != "true" ] && [ -w /proc/sys/kernel/printk ]; then + SAVED_PRINTK=$(cat /proc/sys/kernel/printk | awk '{print $1}') + echo 1 > /proc/sys/kernel/printk +fi + hv_start_vm_background "$KERNEL_APPEND" "$VM_OUTPUT" "$TIMEOUT" # Monitor for completion @@ -1441,6 +1449,23 @@ for i in $(seq 1 $TIMEOUT); do sleep 1 done +# If VM ended before markers were detected, wait for console to flush +if [ "$COMPLETE" = "false" ] && ! hv_is_vm_running; then + sleep 2 + case "$OUTPUT_TYPE" in + text) + grep -q "===OUTPUT_END===" "$VM_OUTPUT" 2>/dev/null && COMPLETE=true + ;; + tar) + grep -q "===TAR_END===" "$VM_OUTPUT" 2>/dev/null && COMPLETE=true + ;; + storage) + grep -qE "===STORAGE_END===|===9P_STORAGE_DONE===" "$VM_OUTPUT" 2>/dev/null && COMPLETE=true + ;; + esac + [ "$COMPLETE" = "true" ] && log "DEBUG" "Markers found after VM exit" +fi + # Wait for VM to exit gracefully (poweroff from inside flushes disks properly) if [ "$COMPLETE" = "true" ] && hv_is_vm_running; then log "DEBUG" "Waiting for VM to complete graceful shutdown..." @@ -1452,10 +1477,15 @@ if hv_is_vm_running; then hv_stop_vm fi +# Restore kernel console messages +if [ -n "$SAVED_PRINTK" ]; then + echo "$SAVED_PRINTK" > /proc/sys/kernel/printk +fi + # Extract results if [ "$COMPLETE" = "true" ]; then # Get exit code - EXIT_CODE=$(grep -oP '===EXIT_CODE=\K[0-9]+' "$VM_OUTPUT" | head -1) + EXIT_CODE=$(sed -n 's/.*===EXIT_CODE=\([0-9]*\).*/\1/p' "$VM_OUTPUT" | head -1) EXIT_CODE="${EXIT_CODE:-0}" case "$OUTPUT_TYPE" in @@ -1544,10 +1574,11 @@ if [ "$COMPLETE" = "true" ]; then exit "${EXIT_CODE:-0}" else log "ERROR" "Command execution failed or timed out" - log "ERROR" "QEMU output saved to: $VM_OUTPUT" + KEEP_TEMP=true + log "ERROR" "VM output saved to: $VM_OUTPUT" if [ "$VERBOSE" = "true" ]; then - log "DEBUG" "=== Last 50 lines of QEMU output ===" + log "DEBUG" "=== Last 50 lines of VM output ===" tail -50 "$VM_OUTPUT" fi -- cgit v1.2.3-54-g00ecf