test(vm): add VM testing infrastructure and QEMU automation scripts
- commit
- 60e25802cbd7361bfbce2b1424a3ef85106534e1
- author
- bnema · · 2025-10-20 18:45 UTC
- parent
- 28d6386
- signature
- unsigned
6 files · +178 -0
A test/vm/README.md +51 -0
| @@ -0,0 +1,51 @@ | |||
| 1 | + | # VM Testing | |
| 2 | + | ||
| 3 | + | Quick QEMU testing environment for ArchUp installer. | |
| 4 | + | ||
| 5 | + | ## Prerequisites | |
| 6 | + | ||
| 7 | + | ```bash | |
| 8 | + | sudo pacman -S qemu-full edk2-ovmf sshpass rsync | |
| 9 | + | ``` | |
| 10 | + | ||
| 11 | + | ## Setup | |
| 12 | + | ||
| 13 | + | ```bash | |
| 14 | + | # 1. Create disk image | |
| 15 | + | ./create-vm-img.sh | |
| 16 | + | ||
| 17 | + | # 2. Start VM with Arch ISO | |
| 18 | + | ./start-qemu-arch-iso.sh | |
| 19 | + | ||
| 20 | + | # 3. In the VM, start SSH and set password | |
| 21 | + | systemctl start sshd | |
| 22 | + | passwd # Set password to: test | |
| 23 | + | ||
| 24 | + | # 4. From host, setup SSH keys | |
| 25 | + | ssh-copy-id -p 2222 root@localhost # Use password: test | |
| 26 | + | ``` | |
| 27 | + | ||
| 28 | + | ## Testing Workflow | |
| 29 | + | ||
| 30 | + | ```bash | |
| 31 | + | # Sync local changes to VM | |
| 32 | + | ./sync-scripts-to-vm.sh | |
| 33 | + | ||
| 34 | + | # SSH into VM | |
| 35 | + | ssh -p 2222 root@localhost | |
| 36 | + | ||
| 37 | + | # Run installer | |
| 38 | + | cd ~/.local/share/archup && ./install.sh | |
| 39 | + | ``` | |
| 40 | + | ||
| 41 | + | ## Scripts | |
| 42 | + | ||
| 43 | + | - `create-vm-img.sh` - Create disk image | |
| 44 | + | - `start-qemu-arch-iso.sh` - Boot ISO (auto-downloads) | |
| 45 | + | - `start-qemu-installed.sh` - Boot installed system | |
| 46 | + | - `sync-scripts-to-vm.sh` - Upload changes to VM | |
| 47 | + | ||
| 48 | + | ## Notes | |
| 49 | + | ||
| 50 | + | - SSH: `localhost:2222` → VM `:22` | |
| 51 | + | - ISO/qcow2 files gitignored | |
| @@ -0,0 +1,51 @@ | |||||
| 1 | + | # VM Testing | |||
| 2 | + | ||||
| 3 | + | Quick QEMU testing environment for ArchUp installer. | |||
| 4 | + | ||||
| 5 | + | ## Prerequisites | |||
| 6 | + | ||||
| 7 | + | ```bash | |||
| 8 | + | sudo pacman -S qemu-full edk2-ovmf sshpass rsync | |||
| 9 | + | ``` | |||
| 10 | + | ||||
| 11 | + | ## Setup | |||
| 12 | + | ||||
| 13 | + | ```bash | |||
| 14 | + | # 1. Create disk image | |||
| 15 | + | ./create-vm-img.sh | |||
| 16 | + | ||||
| 17 | + | # 2. Start VM with Arch ISO | |||
| 18 | + | ./start-qemu-arch-iso.sh | |||
| 19 | + | ||||
| 20 | + | # 3. In the VM, start SSH and set password | |||
| 21 | + | systemctl start sshd | |||
| 22 | + | passwd # Set password to: test | |||
| 23 | + | ||||
| 24 | + | # 4. From host, setup SSH keys | |||
| 25 | + | ssh-copy-id -p 2222 root@localhost # Use password: test | |||
| 26 | + | ``` | |||
| 27 | + | ||||
| 28 | + | ## Testing Workflow | |||
| 29 | + | ||||
| 30 | + | ```bash | |||
| 31 | + | # Sync local changes to VM | |||
| 32 | + | ./sync-scripts-to-vm.sh | |||
| 33 | + | ||||
| 34 | + | # SSH into VM | |||
| 35 | + | ssh -p 2222 root@localhost | |||
| 36 | + | ||||
| 37 | + | # Run installer | |||
| 38 | + | cd ~/.local/share/archup && ./install.sh | |||
| 39 | + | ``` | |||
| 40 | + | ||||
| 41 | + | ## Scripts | |||
| 42 | + | ||||
| 43 | + | - `create-vm-img.sh` - Create disk image | |||
| 44 | + | - `start-qemu-arch-iso.sh` - Boot ISO (auto-downloads) | |||
| 45 | + | - `start-qemu-installed.sh` - Boot installed system | |||
| 46 | + | - `sync-scripts-to-vm.sh` - Upload changes to VM | |||
| 47 | + | ||||
| 48 | + | ## Notes | |||
| 49 | + | ||||
| 50 | + | - SSH: `localhost:2222` → VM `:22` | |||
| 51 | + | - ISO/qcow2 files gitignored | |||
A test/vm/check-luks.sh +11 -0
| @@ -0,0 +1,11 @@ | |||
| 1 | + | #!/bin/bash | |
| 2 | + | # Boot to ISO and check LUKS setup | |
| 3 | + | ||
| 4 | + | echo "Checking LUKS volume..." | |
| 5 | + | ||
| 6 | + | # Try to test if LUKS volume exists | |
| 7 | + | cryptsetup luksDump /dev/vda2 | |
| 8 | + | ||
| 9 | + | echo "" | |
| 10 | + | echo "Trying to open with 'test' password..." | |
| 11 | + | echo "test" | cryptsetup open --test-passphrase /dev/vda2 && echo "Password 'test' works!" || echo "Password 'test' does NOT work!" | |
| @@ -0,0 +1,11 @@ | |||||
| 1 | + | #!/bin/bash | |||
| 2 | + | # Boot to ISO and check LUKS setup | |||
| 3 | + | ||||
| 4 | + | echo "Checking LUKS volume..." | |||
| 5 | + | ||||
| 6 | + | # Try to test if LUKS volume exists | |||
| 7 | + | cryptsetup luksDump /dev/vda2 | |||
| 8 | + | ||||
| 9 | + | echo "" | |||
| 10 | + | echo "Trying to open with 'test' password..." | |||
| 11 | + | echo "test" | cryptsetup open --test-passphrase /dev/vda2 && echo "Password 'test' works!" || echo "Password 'test' does NOT work!" | |||
A test/vm/create-vm-img.sh +35 -0
| @@ -0,0 +1,35 @@ | |||
| 1 | + | #!/bin/bash | |
| 2 | + | # Create QEMU disk image for Arch testing | |
| 3 | + | ||
| 4 | + | set -e | |
| 5 | + | ||
| 6 | + | # Get test directory | |
| 7 | + | TEST_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" | |
| 8 | + | ||
| 9 | + | # Default values | |
| 10 | + | IMAGE_NAME="${1:-arch-test.qcow2}" | |
| 11 | + | IMAGE_SIZE="${2:-20G}" | |
| 12 | + | IMAGE_DIR="${3:-$TEST_DIR}" | |
| 13 | + | ||
| 14 | + | # Create directory if it doesn't exist | |
| 15 | + | mkdir -p "$IMAGE_DIR" | |
| 16 | + | ||
| 17 | + | IMAGE_PATH="$IMAGE_DIR/$IMAGE_NAME" | |
| 18 | + | ||
| 19 | + | # Check if image already exists | |
| 20 | + | if [[ -f "$IMAGE_PATH" ]]; then | |
| 21 | + | echo "Warning: Image '$IMAGE_PATH' already exists." | |
| 22 | + | read -p "Do you want to overwrite it? (y/N): " -n 1 -r | |
| 23 | + | echo | |
| 24 | + | if [[ ! $REPLY =~ ^[Yy]$ ]]; then | |
| 25 | + | echo "Aborted." | |
| 26 | + | exit 0 | |
| 27 | + | fi | |
| 28 | + | rm -f "$IMAGE_PATH" | |
| 29 | + | fi | |
| 30 | + | ||
| 31 | + | # Create the disk image | |
| 32 | + | echo "Creating disk image: $IMAGE_PATH (${IMAGE_SIZE})" | |
| 33 | + | qemu-img create -f qcow2 "$IMAGE_PATH" "$IMAGE_SIZE" | |
| 34 | + | ||
| 35 | + | echo "Disk image created successfully at: $IMAGE_PATH" | |
| @@ -0,0 +1,35 @@ | |||||
| 1 | + | #!/bin/bash | |||
| 2 | + | # Create QEMU disk image for Arch testing | |||
| 3 | + | ||||
| 4 | + | set -e | |||
| 5 | + | ||||
| 6 | + | # Get test directory | |||
| 7 | + | TEST_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" | |||
| 8 | + | ||||
| 9 | + | # Default values | |||
| 10 | + | IMAGE_NAME="${1:-arch-test.qcow2}" | |||
| 11 | + | IMAGE_SIZE="${2:-20G}" | |||
| 12 | + | IMAGE_DIR="${3:-$TEST_DIR}" | |||
| 13 | + | ||||
| 14 | + | # Create directory if it doesn't exist | |||
| 15 | + | mkdir -p "$IMAGE_DIR" | |||
| 16 | + | ||||
| 17 | + | IMAGE_PATH="$IMAGE_DIR/$IMAGE_NAME" | |||
| 18 | + | ||||
| 19 | + | # Check if image already exists | |||
| 20 | + | if [[ -f "$IMAGE_PATH" ]]; then | |||
| 21 | + | echo "Warning: Image '$IMAGE_PATH' already exists." | |||
| 22 | + | read -p "Do you want to overwrite it? (y/N): " -n 1 -r | |||
| 23 | + | echo | |||
| 24 | + | if [[ ! $REPLY =~ ^[Yy]$ ]]; then | |||
| 25 | + | echo "Aborted." | |||
| 26 | + | exit 0 | |||
| 27 | + | fi | |||
| 28 | + | rm -f "$IMAGE_PATH" | |||
| 29 | + | fi | |||
| 30 | + | ||||
| 31 | + | # Create the disk image | |||
| 32 | + | echo "Creating disk image: $IMAGE_PATH (${IMAGE_SIZE})" | |||
| 33 | + | qemu-img create -f qcow2 "$IMAGE_PATH" "$IMAGE_SIZE" | |||
| 34 | + | ||||
| 35 | + | echo "Disk image created successfully at: $IMAGE_PATH" | |||
A test/vm/start-qemu-arch-iso.sh +32 -0
| @@ -0,0 +1,32 @@ | |||
| 1 | + | #!/bin/bash | |
| 2 | + | # Start Arch ISO in QEMU with UEFI support and SSH access | |
| 3 | + | ||
| 4 | + | set -e | |
| 5 | + | ||
| 6 | + | # Get test directory | |
| 7 | + | TEST_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" | |
| 8 | + | ISO_FILE="$TEST_DIR/archlinux-x86_64.iso" | |
| 9 | + | ISO_URL="https://geo.mirror.pkgbuild.com/iso/latest/archlinux-x86_64.iso" | |
| 10 | + | ||
| 11 | + | # Download latest Arch ISO if not present | |
| 12 | + | if [[ ! -f "$ISO_FILE" ]]; then | |
| 13 | + | echo "Arch Linux ISO not found in $TEST_DIR" | |
| 14 | + | echo "Downloading latest Arch ISO from $ISO_URL..." | |
| 15 | + | curl -L -o "$ISO_FILE" "$ISO_URL" | |
| 16 | + | echo "Download complete!" | |
| 17 | + | else | |
| 18 | + | echo "Using existing ISO: $ISO_FILE" | |
| 19 | + | fi | |
| 20 | + | ||
| 21 | + | qemu-system-x86_64 \ | |
| 22 | + | -enable-kvm \ | |
| 23 | + | -m 4096 \ | |
| 24 | + | -smp 4 \ | |
| 25 | + | -bios /usr/share/edk2/x64/OVMF.4m.fd \ | |
| 26 | + | -boot d \ | |
| 27 | + | -cdrom "$ISO_FILE" \ | |
| 28 | + | -drive file="$TEST_DIR/arch-test.qcow2",format=qcow2,if=virtio \ | |
| 29 | + | -display gtk \ | |
| 30 | + | -vga virtio \ | |
| 31 | + | -net nic,model=virtio \ | |
| 32 | + | -net user,hostfwd=tcp::2222-:22 | |
| @@ -0,0 +1,32 @@ | |||||
| 1 | + | #!/bin/bash | |||
| 2 | + | # Start Arch ISO in QEMU with UEFI support and SSH access | |||
| 3 | + | ||||
| 4 | + | set -e | |||
| 5 | + | ||||
| 6 | + | # Get test directory | |||
| 7 | + | TEST_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" | |||
| 8 | + | ISO_FILE="$TEST_DIR/archlinux-x86_64.iso" | |||
| 9 | + | ISO_URL="https://geo.mirror.pkgbuild.com/iso/latest/archlinux-x86_64.iso" | |||
| 10 | + | ||||
| 11 | + | # Download latest Arch ISO if not present | |||
| 12 | + | if [[ ! -f "$ISO_FILE" ]]; then | |||
| 13 | + | echo "Arch Linux ISO not found in $TEST_DIR" | |||
| 14 | + | echo "Downloading latest Arch ISO from $ISO_URL..." | |||
| 15 | + | curl -L -o "$ISO_FILE" "$ISO_URL" | |||
| 16 | + | echo "Download complete!" | |||
| 17 | + | else | |||
| 18 | + | echo "Using existing ISO: $ISO_FILE" | |||
| 19 | + | fi | |||
| 20 | + | ||||
| 21 | + | qemu-system-x86_64 \ | |||
| 22 | + | -enable-kvm \ | |||
| 23 | + | -m 4096 \ | |||
| 24 | + | -smp 4 \ | |||
| 25 | + | -bios /usr/share/edk2/x64/OVMF.4m.fd \ | |||
| 26 | + | -boot d \ | |||
| 27 | + | -cdrom "$ISO_FILE" \ | |||
| 28 | + | -drive file="$TEST_DIR/arch-test.qcow2",format=qcow2,if=virtio \ | |||
| 29 | + | -display gtk \ | |||
| 30 | + | -vga virtio \ | |||
| 31 | + | -net nic,model=virtio \ | |||
| 32 | + | -net user,hostfwd=tcp::2222-:22 | |||
A test/vm/start-qemu-installed.sh +16 -0
| @@ -0,0 +1,16 @@ | |||
| 1 | + | #!/bin/bash | |
| 2 | + | # Start installed Arch system in QEMU with UEFI support and SSH access | |
| 3 | + | ||
| 4 | + | # Get test directory | |
| 5 | + | TEST_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" | |
| 6 | + | ||
| 7 | + | qemu-system-x86_64 \ | |
| 8 | + | -enable-kvm \ | |
| 9 | + | -m 4096 \ | |
| 10 | + | -smp 4 \ | |
| 11 | + | -bios /usr/share/edk2/x64/OVMF.4m.fd \ | |
| 12 | + | -drive file="$TEST_DIR/arch-test.qcow2",format=qcow2,if=virtio \ | |
| 13 | + | -display gtk \ | |
| 14 | + | -vga virtio \ | |
| 15 | + | -net nic,model=virtio \ | |
| 16 | + | -net user,hostfwd=tcp::2222-:22 | |
| @@ -0,0 +1,16 @@ | |||||
| 1 | + | #!/bin/bash | |||
| 2 | + | # Start installed Arch system in QEMU with UEFI support and SSH access | |||
| 3 | + | ||||
| 4 | + | # Get test directory | |||
| 5 | + | TEST_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" | |||
| 6 | + | ||||
| 7 | + | qemu-system-x86_64 \ | |||
| 8 | + | -enable-kvm \ | |||
| 9 | + | -m 4096 \ | |||
| 10 | + | -smp 4 \ | |||
| 11 | + | -bios /usr/share/edk2/x64/OVMF.4m.fd \ | |||
| 12 | + | -drive file="$TEST_DIR/arch-test.qcow2",format=qcow2,if=virtio \ | |||
| 13 | + | -display gtk \ | |||
| 14 | + | -vga virtio \ | |||
| 15 | + | -net nic,model=virtio \ | |||
| 16 | + | -net user,hostfwd=tcp::2222-:22 | |||
A test/vm/sync-scripts-to-vm.sh +33 -0
| @@ -0,0 +1,33 @@ | |||
| 1 | + | #!/bin/bash | |
| 2 | + | # Quick sync script to upload all install files to VM for testing | |
| 3 | + | # Uses rsync for fast synchronization | |
| 4 | + | # Usage: ./sync-vm.sh | |
| 5 | + | ||
| 6 | + | set -eo pipefail | |
| 7 | + | ||
| 8 | + | VM_HOST="localhost" | |
| 9 | + | VM_PORT="2222" | |
| 10 | + | VM_USER="root" | |
| 11 | + | VM_PASS="test" | |
| 12 | + | LOCAL_PATH="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" | |
| 13 | + | REMOTE_PATH="/root/.local/share/archup" | |
| 14 | + | ||
| 15 | + | echo "Syncing ArchUp install files to VM..." | |
| 16 | + | ||
| 17 | + | # Create remote directory first | |
| 18 | + | sshpass -p "$VM_PASS" ssh -p "$VM_PORT" -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null \ | |
| 19 | + | "$VM_USER@$VM_HOST" "mkdir -p $REMOTE_PATH" 2>&1 | grep -v "Warning: Permanently added" || true | |
| 20 | + | ||
| 21 | + | # Sync only install directory and root scripts | |
| 22 | + | sshpass -p "$VM_PASS" rsync -az --progress \ | |
| 23 | + | -e "ssh -p $VM_PORT -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null" \ | |
| 24 | + | "$LOCAL_PATH/install/" \ | |
| 25 | + | "$VM_USER@$VM_HOST:$REMOTE_PATH/install/" 2>&1 | grep -v "Warning: Permanently added" || true | |
| 26 | + | ||
| 27 | + | sshpass -p "$VM_PASS" rsync -az --progress \ | |
| 28 | + | -e "ssh -p $VM_PORT -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null" \ | |
| 29 | + | "$LOCAL_PATH"/*.sh "$LOCAL_PATH"/logo.txt \ | |
| 30 | + | "$VM_USER@$VM_HOST:$REMOTE_PATH/" 2>&1 | grep -v "Warning: Permanently added" || true | |
| 31 | + | ||
| 32 | + | echo | |
| 33 | + | echo "✓ Sync complete!" | |
| @@ -0,0 +1,33 @@ | |||||
| 1 | + | #!/bin/bash | |||
| 2 | + | # Quick sync script to upload all install files to VM for testing | |||
| 3 | + | # Uses rsync for fast synchronization | |||
| 4 | + | # Usage: ./sync-vm.sh | |||
| 5 | + | ||||
| 6 | + | set -eo pipefail | |||
| 7 | + | ||||
| 8 | + | VM_HOST="localhost" | |||
| 9 | + | VM_PORT="2222" | |||
| 10 | + | VM_USER="root" | |||
| 11 | + | VM_PASS="test" | |||
| 12 | + | LOCAL_PATH="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" | |||
| 13 | + | REMOTE_PATH="/root/.local/share/archup" | |||
| 14 | + | ||||
| 15 | + | echo "Syncing ArchUp install files to VM..." | |||
| 16 | + | ||||
| 17 | + | # Create remote directory first | |||
| 18 | + | sshpass -p "$VM_PASS" ssh -p "$VM_PORT" -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null \ | |||
| 19 | + | "$VM_USER@$VM_HOST" "mkdir -p $REMOTE_PATH" 2>&1 | grep -v "Warning: Permanently added" || true | |||
| 20 | + | ||||
| 21 | + | # Sync only install directory and root scripts | |||
| 22 | + | sshpass -p "$VM_PASS" rsync -az --progress \ | |||
| 23 | + | -e "ssh -p $VM_PORT -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null" \ | |||
| 24 | + | "$LOCAL_PATH/install/" \ | |||
| 25 | + | "$VM_USER@$VM_HOST:$REMOTE_PATH/install/" 2>&1 | grep -v "Warning: Permanently added" || true | |||
| 26 | + | ||||
| 27 | + | sshpass -p "$VM_PASS" rsync -az --progress \ | |||
| 28 | + | -e "ssh -p $VM_PORT -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null" \ | |||
| 29 | + | "$LOCAL_PATH"/*.sh "$LOCAL_PATH"/logo.txt \ | |||
| 30 | + | "$VM_USER@$VM_HOST:$REMOTE_PATH/" 2>&1 | grep -v "Warning: Permanently added" || true | |||
| 31 | + | ||||
| 32 | + | echo | |||
| 33 | + | echo "✓ Sync complete!" | |||