mirror of https://github.com/bohanyang/debi
Add GitHub Actions workflow for KVM-based testing of debi.sh with semantic matrix and caching (#3)
* Initial plan * Add GitHub Actions workflow for KVM-based testing Co-authored-by: cha0sCat <47235156+cha0sCat@users.noreply.github.com> * Improve error handling and add security note to workflow Co-authored-by: cha0sCat <47235156+cha0sCat@users.noreply.github.com> * Add explicit permissions to workflow for security Co-authored-by: cha0sCat <47235156+cha0sCat@users.noreply.github.com> * Fix QEMU daemonize incompatibility with nographic option Co-authored-by: cha0sCat <47235156+cha0sCat@users.noreply.github.com> * Fix serial.log permissions and artifact naming conflicts Co-authored-by: cha0sCat <47235156+cha0sCat@users.noreply.github.com> * Fix script execution with pseudo-TTY for stty commands Co-authored-by: cha0sCat <47235156+cha0sCat@users.noreply.github.com> * Add full installation verification with reboot and new password check Co-authored-by: cha0sCat <47235156+cha0sCat@users.noreply.github.com> * fix: only add backports if has backports * Refactor workflow with semantic matrix, caching, and Debian 11 base image Co-authored-by: cha0sCat <47235156+cha0sCat@users.noreply.github.com> * Fix APT cache warning by using user-owned cache directory Co-authored-by: cha0sCat <47235156+cha0sCat@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: cha0sCat <47235156+cha0sCat@users.noreply.github.com> Co-authored-by: Anonymous <>pull/149/head
parent
2c028de296
commit
2723453053
2 changed files with 633 additions and 0 deletions
@ -0,0 +1,218 @@ |
||||
# GitHub Actions Workflow for Testing debi.sh |
||||
|
||||
## Overview |
||||
|
||||
This workflow tests the Debian Network Reinstall Script (`debi.sh`) using KVM virtualization in GitHub Actions. It validates that the script correctly prepares a system for Debian installation, performs the actual installation, and verifies the newly installed system. |
||||
|
||||
## Test Matrix |
||||
|
||||
The workflow uses a semantic matrix strategy to test ~15 different configurations across: |
||||
|
||||
- **Debian Versions**: 10 (Buster), 11 (Bullseye), 12 (Bookworm) |
||||
- **Mirrors**: Default, USTC (China), Cloudflare |
||||
- **Network Interface Naming**: Standard (`ethx`) or predictable names |
||||
- **User Account**: `root` or `debian` |
||||
- **Network Console**: Always enabled for remote installation monitoring |
||||
|
||||
**Key combinations tested:** |
||||
- Debian 10 with default mirror (baseline) |
||||
- Debian 11 with all mirrors and both naming schemes |
||||
- Debian 12 with all mirrors and various user configurations |
||||
|
||||
**Base Image**: All tests use Debian 11 (Bullseye) cloud image as the starting point, regardless of target version. |
||||
|
||||
## How It Works |
||||
|
||||
### 1. Environment Setup |
||||
- Enables KVM support on GitHub Actions runner |
||||
- Caches APT packages for faster subsequent runs |
||||
- Installs QEMU and related tools (qemu-kvm, cloud-utils, sshpass, etc.) |
||||
|
||||
### 2. Base Image Caching |
||||
- Downloads Debian 11 cloud image (only once, then cached) |
||||
- Reuses cached image across all matrix jobs |
||||
- Significantly speeds up workflow execution |
||||
|
||||
### 3. VM Preparation |
||||
- Creates a copy-on-write disk image from the cached base image |
||||
- Generates cloud-init configuration for initial VM setup |
||||
- Configures root SSH access with password `rootpass123` |
||||
|
||||
### 4. VM Execution |
||||
- Starts QEMU VM with KVM acceleration |
||||
- Waits for SSH to become available |
||||
- Uploads `debi.sh` script to the VM |
||||
|
||||
### 5. Script Testing |
||||
- **Builds arguments dynamically** from matrix parameters: |
||||
- `--version` from `matrix.version` |
||||
- `--ustc` or `--cloudflare` from `matrix.mirror` |
||||
- `--ethx` from `matrix.ethx` |
||||
- `--network-console` (always enabled) |
||||
- `--user` and `--password` from `matrix.user` |
||||
- Executes `debi.sh` with built arguments |
||||
- Captures output for debugging |
||||
|
||||
### 6. Installation Validation |
||||
The workflow validates that the script: |
||||
- Successfully downloads Debian installer components to `/boot/debian-*/` |
||||
- Creates the required `linux` and `initrd.gz` files |
||||
- Updates GRUB configuration with Debian Installer entry |
||||
- Sets GRUB default to boot into the installer |
||||
|
||||
### 7. Full Installation Test |
||||
After validation, the workflow: |
||||
- Reboots the VM to start the Debian installer |
||||
- Waits for the installation to complete (up to 30 minutes) |
||||
- Polls for SSH availability with the **new password** (`newpass123`) |
||||
- Verifies the newly installed system |
||||
|
||||
### 7. Success Criteria |
||||
|
||||
A test passes if: |
||||
- ✓ Script executes without critical errors |
||||
- ✓ Installer files exist in `/boot/debian-*/` |
||||
- ✓ GRUB configuration contains "Debian Installer" entry |
||||
- ✓ VM successfully reboots into installer |
||||
- ✓ Installation completes automatically |
||||
- ✓ New system boots and is accessible via SSH with new credentials |
||||
|
||||
## Running the Tests |
||||
|
||||
### Automatic Execution |
||||
Tests run automatically on: |
||||
- Push to `master` or `main` branch |
||||
- Pull requests targeting `master` or `main` |
||||
|
||||
### Manual Execution |
||||
You can manually trigger the workflow: |
||||
1. Go to Actions tab in GitHub |
||||
2. Select "Test Debian Installation Script" |
||||
3. Click "Run workflow" |
||||
|
||||
## Test Artifacts |
||||
|
||||
Each test run uploads: |
||||
- `debi-output.log` - Complete output from script execution |
||||
- `serial.log` - VM serial console log |
||||
|
||||
Access artifacts from the workflow run summary page. |
||||
|
||||
## Interpreting Results |
||||
|
||||
### ✅ Success |
||||
- All validation checks pass |
||||
- New system is accessible with new credentials |
||||
- Green checkmark in GitHub Actions UI |
||||
|
||||
### ❌ Failure |
||||
Common failure scenarios and debugging: |
||||
|
||||
1. **SSH connection timeout (old credentials)** |
||||
- Check serial console log |
||||
- Verify cloud-init configuration |
||||
|
||||
2. **Installer files not downloaded** |
||||
- Review debi-output.log |
||||
- Check network connectivity |
||||
- Verify mirror availability |
||||
|
||||
3. **GRUB update failed** |
||||
- Check for GRUB installation issues |
||||
- Verify disk partitioning |
||||
|
||||
4. **Installation timeout** |
||||
- Installation may take longer than expected |
||||
- Check serial console for installer progress |
||||
- Verify network connectivity to mirrors |
||||
|
||||
5. **Cannot connect with new credentials** |
||||
- Installation may have failed |
||||
- Check serial console for installation errors |
||||
- Verify preseed configuration |
||||
|
||||
## Password Strategy |
||||
|
||||
The workflow uses two different passwords to verify installation success: |
||||
|
||||
| Phase | User | Password | Purpose | |
||||
|-------|------|----------|---------| |
||||
| Initial VM (cloud-init) | root | `rootpass123` | Access the base system to run debi.sh | |
||||
| New System (installed) | root/debian | `newpass123` | Verify the new system was installed | |
||||
|
||||
If SSH connects with `newpass123`, it proves the new Debian system was installed successfully. |
||||
|
||||
## Limitations |
||||
|
||||
This workflow tests the complete installation process: |
||||
- ✓ Script argument parsing |
||||
- ✓ Installer file downloads |
||||
- ✓ GRUB configuration updates |
||||
- ✓ Reboot into installer |
||||
- ✓ Unattended installation |
||||
- ✓ New system verification |
||||
|
||||
Note: Full installation takes 10-30 minutes per test case. |
||||
|
||||
## Performance Optimization |
||||
|
||||
The workflow includes several optimizations: |
||||
|
||||
1. **APT Package Caching**: Dependencies are cached across workflow runs |
||||
2. **Base Image Caching**: Debian 11 cloud image is downloaded once and reused |
||||
3. **Single Base Image**: All tests use Debian 11 as starting point (smaller cache footprint) |
||||
4. **Matrix Exclusions**: Intelligent filtering reduces redundant test combinations |
||||
|
||||
## Adding New Test Cases |
||||
|
||||
The workflow uses a semantic matrix. To modify test coverage: |
||||
|
||||
**Add a new Debian version:** |
||||
```yaml |
||||
matrix: |
||||
version: [10, 11, 12, 13] # Add 13 |
||||
``` |
||||
|
||||
**Test with a new mirror:** |
||||
```yaml |
||||
matrix: |
||||
mirror: ['default', 'ustc', 'cloudflare', 'tuna'] # Add tuna |
||||
``` |
||||
|
||||
**Modify exclusions:** |
||||
```yaml |
||||
exclude: |
||||
# Add exclusions to prevent unwanted combinations |
||||
- version: 13 |
||||
mirror: 'ustc' # Skip USTC for Debian 13 |
||||
``` |
||||
|
||||
The workflow automatically builds command-line arguments from matrix parameters. |
||||
|
||||
## Troubleshooting |
||||
|
||||
### KVM not available |
||||
If KVM is not available, the workflow will fail. GitHub Actions runners support KVM, but some self-hosted runners may not. |
||||
|
||||
### Network timeouts |
||||
If downloads fail, consider: |
||||
- Adding retry logic |
||||
- Using alternative mirrors |
||||
- Checking GitHub Actions network restrictions |
||||
|
||||
### VM boot failures |
||||
Check the serial console log artifact for kernel messages and boot errors. |
||||
|
||||
### Installation hangs |
||||
If the installation takes too long: |
||||
- Check the serial console for progress |
||||
- Verify mirror connectivity |
||||
- Consider using a faster mirror (USTC, Cloudflare) |
||||
|
||||
### Cache issues |
||||
To clear caches and force fresh downloads: |
||||
1. Go to Actions tab → Caches |
||||
2. Delete relevant cache entries |
||||
3. Re-run the workflow |
||||
|
||||
Cache keys are based on workflow file hash, so modifying the workflow automatically invalidates caches. |
||||
@ -0,0 +1,415 @@ |
||||
name: Test Debian Installation Script |
||||
|
||||
on: |
||||
push: |
||||
branches: [ master, main ] |
||||
pull_request: |
||||
branches: [ master, main ] |
||||
workflow_dispatch: |
||||
|
||||
jobs: |
||||
test-debi: |
||||
name: "Debian ${{ matrix.version }} | ${{ matrix.mirror }} | ethx:${{ matrix.ethx }} | user:${{ matrix.user }} | nc:${{ matrix.network_console }}" |
||||
runs-on: ubuntu-22.04 |
||||
timeout-minutes: 45 |
||||
|
||||
permissions: |
||||
contents: read |
||||
|
||||
strategy: |
||||
fail-fast: false |
||||
matrix: |
||||
# Target Debian version to install |
||||
version: [10, 11, 12] |
||||
# Mirror configuration |
||||
mirror: ['default', 'ustc', 'cloudflare'] |
||||
# Network interface naming |
||||
ethx: [true, false] |
||||
# User to create |
||||
user: ['root', 'debian'] |
||||
# Enable network console for remote installation |
||||
network_console: [true] |
||||
|
||||
# Exclude combinations to keep matrix manageable (~12 tests) |
||||
exclude: |
||||
# Debian 10 - only test with default mirror and root user |
||||
- version: 10 |
||||
mirror: 'ustc' |
||||
- version: 10 |
||||
mirror: 'cloudflare' |
||||
- version: 10 |
||||
user: 'debian' |
||||
- version: 10 |
||||
ethx: false |
||||
|
||||
# For Debian 11 & 12, test key combinations |
||||
# Skip debian user with ustc (redundant) |
||||
- version: 11 |
||||
mirror: 'ustc' |
||||
user: 'debian' |
||||
- version: 12 |
||||
mirror: 'ustc' |
||||
user: 'debian' |
||||
|
||||
# Skip cloudflare without ethx (less common) |
||||
- mirror: 'cloudflare' |
||||
ethx: false |
||||
|
||||
# Skip default mirror without ethx for Debian 12 |
||||
- version: 12 |
||||
mirror: 'default' |
||||
ethx: false |
||||
|
||||
steps: |
||||
- name: Checkout repository |
||||
uses: actions/checkout@v4 |
||||
|
||||
- name: Enable KVM |
||||
run: | |
||||
echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules |
||||
sudo udevadm control --reload-rules |
||||
sudo udevadm trigger --name-match=kvm |
||||
|
||||
- name: Cache APT packages |
||||
uses: actions/cache@v4 |
||||
id: cache-apt |
||||
with: |
||||
path: ~/apt-cache |
||||
key: ${{ runner.os }}-apt-${{ hashFiles('.github/workflows/test.yml') }} |
||||
restore-keys: | |
||||
${{ runner.os }}-apt- |
||||
|
||||
- name: Restore APT cache |
||||
if: steps.cache-apt.outputs.cache-hit == 'true' |
||||
run: | |
||||
if [ -d ~/apt-cache ] && [ "$(ls -A ~/apt-cache 2>/dev/null)" ]; then |
||||
sudo cp ~/apt-cache/*.deb /var/cache/apt/archives/ 2>/dev/null || true |
||||
fi |
||||
|
||||
- name: Install dependencies |
||||
run: | |
||||
sudo apt-get update |
||||
sudo apt-get install -y qemu-kvm qemu-utils cloud-image-utils genisoimage expect sshpass |
||||
|
||||
- name: Save APT cache |
||||
if: steps.cache-apt.outputs.cache-hit != 'true' |
||||
run: | |
||||
mkdir -p ~/apt-cache |
||||
sudo cp /var/cache/apt/archives/*.deb ~/apt-cache/ 2>/dev/null || true |
||||
sudo chown -R $USER:$USER ~/apt-cache |
||||
|
||||
- name: Check KVM availability |
||||
run: | |
||||
ls -la /dev/kvm |
||||
kvm-ok || true |
||||
|
||||
- name: Cache Debian cloud image |
||||
id: cache-debian-image |
||||
uses: actions/cache@v4 |
||||
with: |
||||
path: /tmp/debian-11-base.qcow2 |
||||
key: debian-11-cloud-image-${{ hashFiles('.github/workflows/test.yml') }} |
||||
restore-keys: | |
||||
debian-11-cloud-image- |
||||
|
||||
- name: Download Debian 11 cloud image |
||||
if: steps.cache-debian-image.outputs.cache-hit != 'true' |
||||
run: | |
||||
wget -O /tmp/debian-11-base.qcow2 "https://cloud.debian.org/images/cloud/bullseye/latest/debian-11-generic-amd64.qcow2" |
||||
|
||||
- name: Create working disk image |
||||
run: | |
||||
qemu-img create -f qcow2 -F qcow2 -b /tmp/debian-11-base.qcow2 /tmp/test-disk.qcow2 20G |
||||
qemu-img resize /tmp/test-disk.qcow2 20G |
||||
|
||||
- name: Create cloud-init configuration |
||||
run: | |
||||
mkdir -p /tmp/cloud-init |
||||
|
||||
# meta-data |
||||
cat > /tmp/cloud-init/meta-data << 'EOF' |
||||
instance-id: test-debi-vm |
||||
local-hostname: test-debi |
||||
EOF |
||||
|
||||
# user-data with root access |
||||
cat > /tmp/cloud-init/user-data << 'EOF' |
||||
#cloud-config |
||||
users: |
||||
- name: root |
||||
lock_passwd: false |
||||
plain_text_passwd: 'rootpass123' |
||||
|
||||
ssh_pwauth: true |
||||
disable_root: false |
||||
|
||||
packages: |
||||
- wget |
||||
- curl |
||||
|
||||
runcmd: |
||||
- sed -i 's/^#PermitRootLogin.*/PermitRootLogin yes/' /etc/ssh/sshd_config |
||||
- systemctl restart sshd |
||||
EOF |
||||
|
||||
# Create ISO for cloud-init |
||||
genisoimage -output /tmp/cloud-init.iso \ |
||||
-volid cidata -rational-rock -joliet \ |
||||
/tmp/cloud-init/user-data /tmp/cloud-init/meta-data |
||||
|
||||
- name: Start VM and wait for boot |
||||
run: | |
||||
# Start QEMU in background (daemonize mode doesn't support -nographic) |
||||
sudo qemu-system-x86_64 \ |
||||
-machine type=pc,accel=kvm \ |
||||
-cpu host \ |
||||
-m 2048 \ |
||||
-display none \ |
||||
-drive file=/tmp/test-disk.qcow2,format=qcow2,if=virtio \ |
||||
-cdrom /tmp/cloud-init.iso \ |
||||
-net nic,model=virtio \ |
||||
-net user,hostfwd=tcp::2222-:22 \ |
||||
-serial file:/tmp/serial.log \ |
||||
-monitor unix:/tmp/qemu-monitor.sock,server,nowait \ |
||||
-daemonize |
||||
|
||||
# Fix permissions on serial.log so it can be uploaded as artifact |
||||
sudo chmod 644 /tmp/serial.log |
||||
|
||||
echo "Waiting for VM to boot and SSH to become available..." |
||||
for i in {1..60}; do |
||||
if sshpass -p 'rootpass123' ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -p 2222 root@localhost 'echo SSH ready' 2>/dev/null; then |
||||
echo "SSH is ready!" |
||||
break |
||||
fi |
||||
echo "Attempt $i/60: Waiting for SSH..." |
||||
sleep 5 |
||||
done |
||||
|
||||
# Verify SSH is working |
||||
sshpass -p 'rootpass123' ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -p 2222 root@localhost 'uname -a' |
||||
|
||||
- name: Upload debi.sh to VM |
||||
run: | |
||||
sshpass -p 'rootpass123' scp -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -P 2222 \ |
||||
./debi.sh root@localhost:/root/debi.sh |
||||
|
||||
- name: Make script executable |
||||
run: | |
||||
sshpass -p 'rootpass123' ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -p 2222 root@localhost \ |
||||
'chmod +x /root/debi.sh' |
||||
|
||||
- name: Build debi.sh arguments from matrix parameters |
||||
id: build-args |
||||
run: | |
||||
# Start with version |
||||
ARGS="--version ${{ matrix.version }}" |
||||
|
||||
# Add mirror flag |
||||
if [ "${{ matrix.mirror }}" = "ustc" ]; then |
||||
ARGS="$ARGS --ustc" |
||||
elif [ "${{ matrix.mirror }}" = "cloudflare" ]; then |
||||
ARGS="$ARGS --cloudflare" |
||||
fi |
||||
# default mirror doesn't need a flag |
||||
|
||||
# Add ethx flag |
||||
if [ "${{ matrix.ethx }}" = "true" ]; then |
||||
ARGS="$ARGS --ethx" |
||||
fi |
||||
|
||||
# Add network-console flag |
||||
if [ "${{ matrix.network_console }}" = "true" ]; then |
||||
ARGS="$ARGS --network-console" |
||||
fi |
||||
|
||||
# Add user and password |
||||
ARGS="$ARGS --user ${{ matrix.user }} --password newpass123" |
||||
|
||||
echo "args=$ARGS" >> $GITHUB_OUTPUT |
||||
echo "Generated arguments: $ARGS" |
||||
|
||||
- name: Run debi.sh with test arguments |
||||
run: | |
||||
echo "Running debi.sh with arguments: ${{ steps.build-args.outputs.args }}" |
||||
|
||||
# Run the script with a pseudo-TTY to handle stty commands |
||||
# Use 'script' command to provide a PTY for non-interactive SSH |
||||
sshpass -p 'rootpass123' ssh -t -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -p 2222 root@localhost \ |
||||
"script -q -c 'cd /root && ./debi.sh ${{ steps.build-args.outputs.args }}' /tmp/debi-output.log; echo \"Script exit code: \$?\" >> /tmp/debi-output.log" || echo "Script execution finished with non-zero exit code, will validate via file checks" |
||||
|
||||
- name: Download and check debi.sh output |
||||
run: | |
||||
sshpass -p 'rootpass123' scp -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -P 2222 \ |
||||
root@localhost:/tmp/debi-output.log /tmp/debi-output.log || echo "Could not download output log" |
||||
|
||||
if [ -f /tmp/debi-output.log ]; then |
||||
echo "=== debi.sh output ===" |
||||
cat /tmp/debi-output.log |
||||
echo "======================" |
||||
fi |
||||
|
||||
- name: Verify installation preparation |
||||
run: | |
||||
echo "Checking if Debian installer files were downloaded..." |
||||
|
||||
# Check if installer directory was created |
||||
sshpass -p 'rootpass123' ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -p 2222 root@localhost \ |
||||
'ls -la /boot/debian-* || echo "No installer directory found"' |
||||
|
||||
# Check for installer components |
||||
sshpass -p 'rootpass123' ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -p 2222 root@localhost \ |
||||
'ls -lh /boot/debian-*/linux /boot/debian-*/initrd.gz 2>/dev/null || echo "Installer files not found"' |
||||
|
||||
# Check GRUB configuration |
||||
sshpass -p 'rootpass123' ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -p 2222 root@localhost \ |
||||
'cat /etc/default/grub.d/zz-debi.cfg 2>/dev/null || echo "GRUB config not found"' |
||||
|
||||
# Check if GRUB was updated with installer entry |
||||
sshpass -p 'rootpass123' ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -p 2222 root@localhost \ |
||||
'grep -A 5 "Debian Installer" /boot/grub/grub.cfg || echo "Debian Installer entry not found in GRUB"' |
||||
|
||||
- name: Validate installation files exist |
||||
run: | |
||||
# Verify key files exist |
||||
sshpass -p 'rootpass123' ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -p 2222 root@localhost \ |
||||
'test -f /boot/debian-*/linux && test -f /boot/debian-*/initrd.gz && echo "Installation files verified!" || exit 1' |
||||
|
||||
# Verify GRUB config was updated |
||||
sshpass -p 'rootpass123' ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -p 2222 root@localhost \ |
||||
'grep -q "Debian Installer" /boot/grub/grub.cfg && echo "GRUB config verified!" || exit 1' |
||||
|
||||
echo "✓ Script execution completed successfully" |
||||
echo "✓ Installer files downloaded" |
||||
echo "✓ GRUB configuration updated" |
||||
echo "✓ System ready for reboot into Debian installer" |
||||
|
||||
- name: Reboot into Debian installer |
||||
run: | |
||||
echo "Rebooting VM to start Debian installation..." |
||||
|
||||
# Trigger reboot - the system should boot into Debian installer |
||||
sshpass -p 'rootpass123' ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -p 2222 root@localhost \ |
||||
'reboot' 2>/dev/null || true |
||||
|
||||
echo "Reboot command sent. VM will now boot into Debian installer." |
||||
echo "The installation process will take several minutes..." |
||||
|
||||
- name: Wait for Debian installation to complete |
||||
run: | |
||||
echo "Waiting for Debian installation to complete..." |
||||
echo "This typically takes 10-20 minutes depending on network speed and mirror." |
||||
echo "The installer will automatically reboot after completion." |
||||
|
||||
# Wait for the old system to go down |
||||
sleep 30 |
||||
|
||||
# The installation process: |
||||
# 1. VM boots into Debian installer (netboot) |
||||
# 2. Installer runs unattended using preseed configuration |
||||
# 3. System installs packages from mirror |
||||
# 4. System reboots into newly installed Debian |
||||
|
||||
# We'll poll for SSH availability with the NEW password |
||||
# This indicates the new system has been installed and booted |
||||
|
||||
MAX_WAIT=1800 # 30 minutes maximum wait |
||||
POLL_INTERVAL=30 |
||||
ELAPSED=0 |
||||
|
||||
echo "Polling for new system availability (max wait: ${MAX_WAIT}s)..." |
||||
|
||||
while [ $ELAPSED -lt $MAX_WAIT ]; do |
||||
echo "Attempt at ${ELAPSED}s: Trying to connect with new credentials..." |
||||
|
||||
# Try to connect with the NEW password (set by debi.sh installation) |
||||
if sshpass -p 'newpass123' ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o ConnectTimeout=10 -p 2222 ${{ matrix.user }}@localhost 'echo "NEW SYSTEM CONNECTED!"' 2>/dev/null; then |
||||
echo "✓ Successfully connected to newly installed system!" |
||||
echo "✓ Installation completed successfully!" |
||||
exit 0 |
||||
fi |
||||
|
||||
# Also check if old system is still responding (installation not started yet) |
||||
if sshpass -p 'rootpass123' ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o ConnectTimeout=5 -p 2222 root@localhost 'echo "old system"' 2>/dev/null; then |
||||
echo " Old system still responding - installation may not have started" |
||||
fi |
||||
|
||||
sleep $POLL_INTERVAL |
||||
ELAPSED=$((ELAPSED + POLL_INTERVAL)) |
||||
done |
||||
|
||||
echo "✗ Timeout: Could not connect to new system after ${MAX_WAIT}s" |
||||
exit 1 |
||||
|
||||
- name: Verify new system installation |
||||
run: | |
||||
echo "Verifying the newly installed Debian system..." |
||||
|
||||
# Connect with new credentials and verify system |
||||
sshpass -p 'newpass123' ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -p 2222 ${{ matrix.user }}@localhost << 'VERIFY_EOF' |
||||
echo "=== System Information ===" |
||||
uname -a |
||||
|
||||
echo "" |
||||
echo "=== OS Release ===" |
||||
cat /etc/os-release |
||||
|
||||
echo "" |
||||
echo "=== Disk Usage ===" |
||||
df -h |
||||
|
||||
echo "" |
||||
echo "=== Memory Info ===" |
||||
free -h |
||||
|
||||
echo "" |
||||
echo "=== Network Configuration ===" |
||||
ip addr show |
||||
|
||||
echo "" |
||||
echo "=== Hostname ===" |
||||
hostname |
||||
|
||||
echo "" |
||||
echo "✓ New Debian system is running successfully!" |
||||
VERIFY_EOF |
||||
|
||||
- name: Collect debug information on failure |
||||
if: failure() |
||||
run: | |
||||
echo "=== Serial console log ===" |
||||
cat /tmp/serial.log || echo "No serial log available" |
||||
|
||||
echo "=== Trying to connect with old credentials ===" |
||||
sshpass -p 'rootpass123' ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o ConnectTimeout=5 -p 2222 root@localhost \ |
||||
'journalctl -n 100' 2>/dev/null || echo "Could not connect with old credentials" |
||||
|
||||
echo "=== Trying to connect with new credentials ===" |
||||
sshpass -p 'newpass123' ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o ConnectTimeout=5 -p 2222 ${{ matrix.user }}@localhost \ |
||||
'journalctl -n 100' 2>/dev/null || echo "Could not connect with new credentials" |
||||
|
||||
- name: Shutdown VM |
||||
if: always() |
||||
run: | |
||||
# Try graceful shutdown with new credentials first (if new system is installed) |
||||
sshpass -p 'newpass123' ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o ConnectTimeout=5 -p 2222 ${{ matrix.user }}@localhost \ |
||||
'sudo poweroff' 2>/dev/null || true |
||||
|
||||
# Also try with old credentials (if still on old system) |
||||
sshpass -p 'rootpass123' ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o ConnectTimeout=5 -p 2222 root@localhost \ |
||||
'poweroff' 2>/dev/null || true |
||||
|
||||
sleep 5 |
||||
|
||||
# Force kill QEMU if still running |
||||
sudo pkill qemu-system-x86_64 || true |
||||
|
||||
- name: Upload logs as artifacts |
||||
if: always() |
||||
uses: actions/upload-artifact@v4 |
||||
with: |
||||
name: test-logs-v${{ matrix.version }}-${{ matrix.mirror }}-ethx${{ matrix.ethx }}-${{ matrix.user }}-nc${{ matrix.network_console }} |
||||
path: | |
||||
/tmp/debi-output.log |
||||
/tmp/serial.log |
||||
if-no-files-found: warn |
||||
Loading…
Reference in new issue