diff options
| -rw-r--r-- | recipes-containers/vcontainer/files/vrunner-backend-xen.sh | 4 | ||||
| -rwxr-xr-x | recipes-containers/vcontainer/files/vrunner.sh | 47 |
2 files changed, 41 insertions, 10 deletions
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() { | |||
| 357 | # Use the domain name as VM identifier | 357 | # Use the domain name as VM identifier |
| 358 | HV_VM_PID="$$" # Use our PID as a placeholder for compatibility | 358 | HV_VM_PID="$$" # Use our PID as a placeholder for compatibility |
| 359 | 359 | ||
| 360 | if [ -n "$DAEMON_SOCKET" ]; then | 360 | if [ "$DAEMON_MODE" = "start" ]; then |
| 361 | # Daemon mode: bridge xl console (hvc1) to the daemon unix socket | 361 | # Daemon mode: bridge xl console (hvc1) to the daemon unix socket |
| 362 | # xl console -n 1 connects to the second PV console (hvc1) | 362 | # xl console -n 1 connects to the second PV console (hvc1) |
| 363 | socat "UNIX-LISTEN:$DAEMON_SOCKET,fork" "EXEC:xl console -n 1 $HV_DOMNAME" & | 363 | socat "UNIX-LISTEN:$DAEMON_SOCKET,fork" "EXEC:xl console -n 1 $HV_DOMNAME" & |
| @@ -366,7 +366,7 @@ hv_start_vm_background() { | |||
| 366 | else | 366 | else |
| 367 | # Ephemeral mode: capture guest console (hvc0) to log file | 367 | # Ephemeral mode: capture guest console (hvc0) to log file |
| 368 | # so the monitoring loop in vrunner.sh can see output markers | 368 | # so the monitoring loop in vrunner.sh can see output markers |
| 369 | xl console "$HV_DOMNAME" >> "$log_file" 2>&1 & | 369 | stdbuf -oL xl console "$HV_DOMNAME" >> "$log_file" 2>&1 & |
| 370 | _XEN_CONSOLE_PID=$! | 370 | _XEN_CONSOLE_PID=$! |
| 371 | log "DEBUG" "Console capture started (PID: $_XEN_CONSOLE_PID)" | 371 | log "DEBUG" "Console capture started (PID: $_XEN_CONSOLE_PID)" |
| 372 | fi | 372 | 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 | |||
| 1019 | dd if=/dev/zero of="$INPUT_IMG" bs=1M count=$SIZE_MB 2>/dev/null | 1019 | dd if=/dev/zero of="$INPUT_IMG" bs=1M count=$SIZE_MB 2>/dev/null |
| 1020 | 1020 | ||
| 1021 | if [ -d "$INPUT_PATH" ]; then | 1021 | if [ -d "$INPUT_PATH" ]; then |
| 1022 | mke2fs -t ext4 -d "$INPUT_PATH" "$INPUT_IMG" 2>/dev/null | 1022 | mke2fs -t ext4 -d "$INPUT_PATH" "$INPUT_IMG" >/dev/null 2>&1 |
| 1023 | else | 1023 | else |
| 1024 | # Single file - create temp dir with the file | 1024 | # Single file - create temp dir with the file |
| 1025 | EXTRACT_DIR="$TEMP_DIR/input-extract" | 1025 | EXTRACT_DIR="$TEMP_DIR/input-extract" |
| 1026 | mkdir -p "$EXTRACT_DIR" | 1026 | mkdir -p "$EXTRACT_DIR" |
| 1027 | cp "$INPUT_PATH" "$EXTRACT_DIR/" | 1027 | cp "$INPUT_PATH" "$EXTRACT_DIR/" |
| 1028 | mke2fs -t ext4 -d "$EXTRACT_DIR" "$INPUT_IMG" 2>/dev/null | 1028 | mke2fs -t ext4 -d "$EXTRACT_DIR" "$INPUT_IMG" >/dev/null 2>&1 |
| 1029 | fi | 1029 | fi |
| 1030 | 1030 | ||
| 1031 | DISK_OPTS="-drive file=$INPUT_IMG,if=virtio,format=raw" | 1031 | 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 | |||
| 1054 | log "INFO" "Creating new state disk at $STATE_IMG..." | 1054 | log "INFO" "Creating new state disk at $STATE_IMG..." |
| 1055 | # Create 2GB state disk for Docker storage | 1055 | # Create 2GB state disk for Docker storage |
| 1056 | dd if=/dev/zero of="$STATE_IMG" bs=1M count=2048 2>/dev/null | 1056 | dd if=/dev/zero of="$STATE_IMG" bs=1M count=2048 2>/dev/null |
| 1057 | mke2fs -t ext4 "$STATE_IMG" 2>/dev/null | 1057 | mke2fs -t ext4 "$STATE_IMG" >/dev/null 2>&1 |
| 1058 | else | 1058 | else |
| 1059 | log "INFO" "Using existing state disk: $STATE_IMG" | 1059 | log "INFO" "Using existing state disk: $STATE_IMG" |
| 1060 | fi | 1060 | fi |
| @@ -1087,7 +1087,7 @@ if [ -n "$INPUT_STORAGE" ] && [ -z "$STATE_DIR" ]; then | |||
| 1087 | log "DEBUG" "Tar size: ${TAR_SIZE_KB}KB, State disk: ${STATE_SIZE_MB}MB" | 1087 | log "DEBUG" "Tar size: ${TAR_SIZE_KB}KB, State disk: ${STATE_SIZE_MB}MB" |
| 1088 | 1088 | ||
| 1089 | dd if=/dev/zero of="$STATE_IMG" bs=1M count=$STATE_SIZE_MB 2>/dev/null | 1089 | dd if=/dev/zero of="$STATE_IMG" bs=1M count=$STATE_SIZE_MB 2>/dev/null |
| 1090 | mke2fs -t ext4 "$STATE_IMG" 2>/dev/null | 1090 | mke2fs -t ext4 "$STATE_IMG" >/dev/null 2>&1 |
| 1091 | 1091 | ||
| 1092 | # Mount and extract tar | 1092 | # Mount and extract tar |
| 1093 | MOUNT_DIR="$TEMP_DIR/state-mount" | 1093 | MOUNT_DIR="$TEMP_DIR/state-mount" |
| @@ -1109,7 +1109,7 @@ if [ -n "$INPUT_STORAGE" ] && [ -z "$STATE_DIR" ]; then | |||
| 1109 | EXTRACT_DIR="$TEMP_DIR/state-extract" | 1109 | EXTRACT_DIR="$TEMP_DIR/state-extract" |
| 1110 | mkdir -p "$EXTRACT_DIR" | 1110 | mkdir -p "$EXTRACT_DIR" |
| 1111 | tar --no-same-owner --strip-components=1 --exclude=volumes/backingFsBlockDev -xf "$INPUT_STORAGE" -C "$EXTRACT_DIR" | 1111 | tar --no-same-owner --strip-components=1 --exclude=volumes/backingFsBlockDev -xf "$INPUT_STORAGE" -C "$EXTRACT_DIR" |
| 1112 | mke2fs -t ext4 -d "$EXTRACT_DIR" "$STATE_IMG" 2>/dev/null | 1112 | mke2fs -t ext4 -d "$EXTRACT_DIR" "$STATE_IMG" >/dev/null 2>&1 |
| 1113 | fi | 1113 | fi |
| 1114 | 1114 | ||
| 1115 | # Use cache=directsync to ensure writes are flushed to disk | 1115 | # Use cache=directsync to ensure writes are flushed to disk |
| @@ -1392,6 +1392,14 @@ fi | |||
| 1392 | 1392 | ||
| 1393 | # Non-interactive mode: run VM in background and capture output | 1393 | # Non-interactive mode: run VM in background and capture output |
| 1394 | VM_OUTPUT="$TEMP_DIR/vm_output.txt" | 1394 | VM_OUTPUT="$TEMP_DIR/vm_output.txt" |
| 1395 | |||
| 1396 | # Suppress kernel console messages in non-verbose mode to keep output clean | ||
| 1397 | SAVED_PRINTK="" | ||
| 1398 | if [ "$VERBOSE" != "true" ] && [ -w /proc/sys/kernel/printk ]; then | ||
| 1399 | SAVED_PRINTK=$(cat /proc/sys/kernel/printk | awk '{print $1}') | ||
| 1400 | echo 1 > /proc/sys/kernel/printk | ||
| 1401 | fi | ||
| 1402 | |||
| 1395 | hv_start_vm_background "$KERNEL_APPEND" "$VM_OUTPUT" "$TIMEOUT" | 1403 | hv_start_vm_background "$KERNEL_APPEND" "$VM_OUTPUT" "$TIMEOUT" |
| 1396 | 1404 | ||
| 1397 | # Monitor for completion | 1405 | # Monitor for completion |
| @@ -1441,6 +1449,23 @@ for i in $(seq 1 $TIMEOUT); do | |||
| 1441 | sleep 1 | 1449 | sleep 1 |
| 1442 | done | 1450 | done |
| 1443 | 1451 | ||
| 1452 | # If VM ended before markers were detected, wait for console to flush | ||
| 1453 | if [ "$COMPLETE" = "false" ] && ! hv_is_vm_running; then | ||
| 1454 | sleep 2 | ||
| 1455 | case "$OUTPUT_TYPE" in | ||
| 1456 | text) | ||
| 1457 | grep -q "===OUTPUT_END===" "$VM_OUTPUT" 2>/dev/null && COMPLETE=true | ||
| 1458 | ;; | ||
| 1459 | tar) | ||
| 1460 | grep -q "===TAR_END===" "$VM_OUTPUT" 2>/dev/null && COMPLETE=true | ||
| 1461 | ;; | ||
| 1462 | storage) | ||
| 1463 | grep -qE "===STORAGE_END===|===9P_STORAGE_DONE===" "$VM_OUTPUT" 2>/dev/null && COMPLETE=true | ||
| 1464 | ;; | ||
| 1465 | esac | ||
| 1466 | [ "$COMPLETE" = "true" ] && log "DEBUG" "Markers found after VM exit" | ||
| 1467 | fi | ||
| 1468 | |||
| 1444 | # Wait for VM to exit gracefully (poweroff from inside flushes disks properly) | 1469 | # Wait for VM to exit gracefully (poweroff from inside flushes disks properly) |
| 1445 | if [ "$COMPLETE" = "true" ] && hv_is_vm_running; then | 1470 | if [ "$COMPLETE" = "true" ] && hv_is_vm_running; then |
| 1446 | log "DEBUG" "Waiting for VM to complete graceful shutdown..." | 1471 | log "DEBUG" "Waiting for VM to complete graceful shutdown..." |
| @@ -1452,10 +1477,15 @@ if hv_is_vm_running; then | |||
| 1452 | hv_stop_vm | 1477 | hv_stop_vm |
| 1453 | fi | 1478 | fi |
| 1454 | 1479 | ||
| 1480 | # Restore kernel console messages | ||
| 1481 | if [ -n "$SAVED_PRINTK" ]; then | ||
| 1482 | echo "$SAVED_PRINTK" > /proc/sys/kernel/printk | ||
| 1483 | fi | ||
| 1484 | |||
| 1455 | # Extract results | 1485 | # Extract results |
| 1456 | if [ "$COMPLETE" = "true" ]; then | 1486 | if [ "$COMPLETE" = "true" ]; then |
| 1457 | # Get exit code | 1487 | # Get exit code |
| 1458 | EXIT_CODE=$(grep -oP '===EXIT_CODE=\K[0-9]+' "$VM_OUTPUT" | head -1) | 1488 | EXIT_CODE=$(sed -n 's/.*===EXIT_CODE=\([0-9]*\).*/\1/p' "$VM_OUTPUT" | head -1) |
| 1459 | EXIT_CODE="${EXIT_CODE:-0}" | 1489 | EXIT_CODE="${EXIT_CODE:-0}" |
| 1460 | 1490 | ||
| 1461 | case "$OUTPUT_TYPE" in | 1491 | case "$OUTPUT_TYPE" in |
| @@ -1544,10 +1574,11 @@ if [ "$COMPLETE" = "true" ]; then | |||
| 1544 | exit "${EXIT_CODE:-0}" | 1574 | exit "${EXIT_CODE:-0}" |
| 1545 | else | 1575 | else |
| 1546 | log "ERROR" "Command execution failed or timed out" | 1576 | log "ERROR" "Command execution failed or timed out" |
| 1547 | log "ERROR" "QEMU output saved to: $VM_OUTPUT" | 1577 | KEEP_TEMP=true |
| 1578 | log "ERROR" "VM output saved to: $VM_OUTPUT" | ||
| 1548 | 1579 | ||
| 1549 | if [ "$VERBOSE" = "true" ]; then | 1580 | if [ "$VERBOSE" = "true" ]; then |
| 1550 | log "DEBUG" "=== Last 50 lines of QEMU output ===" | 1581 | log "DEBUG" "=== Last 50 lines of VM output ===" |
| 1551 | tail -50 "$VM_OUTPUT" | 1582 | tail -50 "$VM_OUTPUT" |
| 1552 | fi | 1583 | fi |
| 1553 | 1584 | ||
