updates
This commit is contained in:
107
scripts/bootstrap_golden.sh
Executable file
107
scripts/bootstrap_golden.sh
Executable file
@@ -0,0 +1,107 @@
|
||||
#!/bin/bash
|
||||
# Bootstrap the golden image by booting it, running sparrowdo --bootstrap, then shutting down
|
||||
# This should be run ONCE after creating the golden image
|
||||
|
||||
GOLDEN_IMAGE="$1"
|
||||
SSH_PRIVATE_KEY="${2:-$HOME/.ssh/id_rsa}"
|
||||
|
||||
if [ -z "$GOLDEN_IMAGE" ]; then
|
||||
echo "Usage: $0 <golden_image_path> [ssh_private_key]"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f "$GOLDEN_IMAGE" ]; then
|
||||
echo "ERROR: Golden image not found: $GOLDEN_IMAGE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
BOOTSTRAP_VM="bootstrap-golden-$(date +%s)"
|
||||
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
|
||||
echo "=========================================="
|
||||
echo "Bootstrapping Golden Image"
|
||||
echo "=========================================="
|
||||
echo "Golden Image: $GOLDEN_IMAGE"
|
||||
echo "Bootstrap VM: $BOOTSTRAP_VM"
|
||||
echo "SSH Key: $SSH_PRIVATE_KEY"
|
||||
echo ""
|
||||
|
||||
# Provision temporary VM from golden image
|
||||
echo "[1/4] Provisioning temporary VM..."
|
||||
VM_IP=$("${SCRIPT_DIR}/provision_vm.sh" "$BOOTSTRAP_VM" "$GOLDEN_IMAGE" 60)
|
||||
|
||||
if [ "$VM_IP" = "ERROR" ] || [ -z "$VM_IP" ]; then
|
||||
echo "ERROR: Failed to provision bootstrap VM"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
VM_IP=$(echo "$VM_IP" | tail -1)
|
||||
echo "VM IP: $VM_IP"
|
||||
|
||||
# Wait for SSH
|
||||
echo ""
|
||||
echo "[2/4] Waiting for SSH to be ready..."
|
||||
for i in {1..30}; do
|
||||
if ssh -i "$SSH_PRIVATE_KEY" \
|
||||
-o StrictHostKeyChecking=no \
|
||||
-o ConnectTimeout=5 \
|
||||
-o UserKnownHostsFile=/dev/null \
|
||||
rocky@${VM_IP} 'echo "SSH ready"' 2>/dev/null; then
|
||||
echo "SSH connection established"
|
||||
break
|
||||
fi
|
||||
sleep 2
|
||||
done
|
||||
|
||||
# Run sparrowdo bootstrap
|
||||
echo ""
|
||||
echo "[3/4] Running Sparrowdo bootstrap..."
|
||||
if sparrowdo \
|
||||
--host="${VM_IP}" \
|
||||
--ssh_user=rocky \
|
||||
--ssh_private_key="${SSH_PRIVATE_KEY}" \
|
||||
--ssh_args="-o StrictHostKeyChecking=no -o ConnectTimeout=10 -o UserKnownHostsFile=/dev/null" \
|
||||
--bootstrap \
|
||||
--color; then
|
||||
echo "Bootstrap completed successfully!"
|
||||
else
|
||||
echo "WARNING: Bootstrap may have failed"
|
||||
fi
|
||||
|
||||
# Shutdown the VM cleanly to save changes
|
||||
echo ""
|
||||
echo "[4/4] Shutting down VM to save changes..."
|
||||
ssh -i "$SSH_PRIVATE_KEY" \
|
||||
-o StrictHostKeyChecking=no \
|
||||
-o UserKnownHostsFile=/dev/null \
|
||||
rocky@${VM_IP} 'sudo shutdown -h now' 2>/dev/null || true
|
||||
|
||||
# Wait for VM to shut down
|
||||
echo "Waiting for VM to shut down..."
|
||||
sleep 10
|
||||
|
||||
for i in {1..30}; do
|
||||
if ! sudo virsh -c qemu:///system list --name 2>/dev/null | grep -q "$BOOTSTRAP_VM"; then
|
||||
echo "VM has shut down"
|
||||
break
|
||||
fi
|
||||
sleep 2
|
||||
done
|
||||
|
||||
# Clean up VM definition (disk contains the bootstrapped state)
|
||||
echo "Cleaning up VM definition..."
|
||||
sudo virsh -c qemu:///system undefine "$BOOTSTRAP_VM" 2>/dev/null || true
|
||||
|
||||
echo ""
|
||||
echo "=========================================="
|
||||
echo "Bootstrap Complete"
|
||||
echo "=========================================="
|
||||
echo "Golden image has been bootstrapped with Sparrowdo"
|
||||
echo "The image now contains:"
|
||||
echo " - Raku/Rakudo runtime"
|
||||
echo " - Sparrowdo and dependencies"
|
||||
echo " - All required testing tools"
|
||||
echo ""
|
||||
echo "This image can now be used for testing without"
|
||||
echo "running bootstrap on each test VM."
|
||||
echo "=========================================="
|
||||
51
scripts/build-golden.sh
Executable file
51
scripts/build-golden.sh
Executable file
@@ -0,0 +1,51 @@
|
||||
#!/bin/bash
|
||||
|
||||
BASE_IMAGE="$1"
|
||||
GOLDEN_IMAGE="$2"
|
||||
SSH_PUB_KEY="${3:-$HOME/.ssh/id_rsa.pub}"
|
||||
|
||||
if [ -z "$BASE_IMAGE" ] || [ -z "$GOLDEN_IMAGE" ]; then
|
||||
echo "Usage: $0 <base_image> <golden_image> [ssh_pub_key]"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Creating golden image: $GOLDEN_IMAGE"
|
||||
cp "$BASE_IMAGE" "$GOLDEN_IMAGE"
|
||||
|
||||
export LIBGUESTFS_BACKEND=direct
|
||||
|
||||
sudo virt-customize -a "$GOLDEN_IMAGE" \
|
||||
--install rakudo,rakudo-zef,perl,git,openssh-server \
|
||||
--run-command 'useradd -m rocky && echo "rocky:rockypass" | chpasswd' \
|
||||
--run-command 'echo "rocky ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/rocky && chmod 0440 /etc/sudoers.d/rocky' \
|
||||
--ssh-inject root:file:"$SSH_PUB_KEY" \
|
||||
--ssh-inject rocky:file:"$SSH_PUB_KEY" \
|
||||
--root-password password:rockytesting \
|
||||
--run-command 'systemctl enable sshd' \
|
||||
--selinux-relabel
|
||||
|
||||
echo "Bootstrapping Sparrowdo..."
|
||||
BOOTSTRAP_VM="bootstrap-$$"
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
|
||||
VM_IP=$("$SCRIPT_DIR/provision_vm.sh" "$BOOTSTRAP_VM" "$GOLDEN_IMAGE" 60 | tail -1)
|
||||
|
||||
if [ -z "$VM_IP" ] || [ "$VM_IP" = "ERROR" ]; then
|
||||
echo "ERROR: Failed to provision bootstrap VM"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
sleep 5
|
||||
|
||||
SSH_KEY="${SSH_PUB_KEY%.pub}"
|
||||
sparrowdo --host="$VM_IP" --ssh_user=rocky --ssh_private_key="$SSH_KEY" \
|
||||
--ssh_args="-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null" \
|
||||
--bootstrap --color
|
||||
|
||||
ssh -i "$SSH_KEY" -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null \
|
||||
rocky@"$VM_IP" 'sudo shutdown -h now' 2>/dev/null || true
|
||||
|
||||
sleep 10
|
||||
"$SCRIPT_DIR/cleanup_vm.sh" "$BOOTSTRAP_VM"
|
||||
|
||||
echo "Golden image ready: $GOLDEN_IMAGE"
|
||||
14
scripts/cleanup-all.sh
Executable file
14
scripts/cleanup-all.sh
Executable file
@@ -0,0 +1,14 @@
|
||||
#!/bin/bash
|
||||
|
||||
PATTERN="${1:-.*}"
|
||||
|
||||
echo "Cleaning up VMs matching: $PATTERN"
|
||||
|
||||
for vm in $(virsh -c qemu:///system list --all --name | grep -E "$PATTERN"); do
|
||||
echo "Destroying $vm"
|
||||
virsh -c qemu:///system destroy "$vm" 2>/dev/null || true
|
||||
virsh -c qemu:///system undefine "$vm" 2>/dev/null || true
|
||||
rm -f "/var/lib/libvirt/images/${vm}.qcow2" 2>/dev/null || true
|
||||
done
|
||||
|
||||
echo "Cleanup complete"
|
||||
@@ -12,11 +12,11 @@ echo "[Cleanup] Starting cleanup for VM: $VM_NAME"
|
||||
|
||||
# Force stop VM
|
||||
echo "[Cleanup] Destroying VM..."
|
||||
sudo virsh destroy "$VM_NAME" 2>/dev/null || echo "[Cleanup] VM was not running"
|
||||
sudo virsh -c qemu:///system destroy "$VM_NAME" 2>/dev/null || echo "[Cleanup] VM was not running"
|
||||
|
||||
# Remove VM definition
|
||||
echo "[Cleanup] Undefining VM..."
|
||||
sudo virsh undefine "$VM_NAME" 2>/dev/null || echo "[Cleanup] VM definition already removed"
|
||||
sudo virsh -c qemu:///system undefine "$VM_NAME" 2>/dev/null || echo "[Cleanup] VM definition already removed"
|
||||
|
||||
# Remove disk image
|
||||
echo "[Cleanup] Removing disk image..."
|
||||
|
||||
22
scripts/download-image.sh
Executable file
22
scripts/download-image.sh
Executable file
@@ -0,0 +1,22 @@
|
||||
#!/bin/bash
|
||||
|
||||
URL="$1"
|
||||
OUTPUT_DIR="${2:-/var/lib/libvirt/images}"
|
||||
FORCE="${3:-false}"
|
||||
|
||||
if [ -z "$URL" ]; then
|
||||
echo "Usage: $0 <url> [output_dir] [force]"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
FILENAME=$(basename "$URL")
|
||||
CACHED="$OUTPUT_DIR/$FILENAME"
|
||||
|
||||
if [ "$FORCE" = "true" ] || [ ! -f "$CACHED" ]; then
|
||||
echo "Downloading $URL to $CACHED"
|
||||
curl -L --progress-bar -o "$CACHED" "$URL"
|
||||
else
|
||||
echo "Using cached image: $CACHED"
|
||||
fi
|
||||
|
||||
echo "$CACHED"
|
||||
@@ -1,5 +1,6 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
# Note: Not using 'set -e' here because we handle errors explicitly
|
||||
# and arithmetic operations can cause false failures with set -e
|
||||
|
||||
VM_NAME="$1"
|
||||
GOLDEN_IMAGE="$2"
|
||||
@@ -20,7 +21,7 @@ sudo qemu-img create -f qcow2 -b "$GOLDEN_IMAGE" -F qcow2 "$VM_DISK" 2>/dev/null
|
||||
|
||||
# Define and start VM
|
||||
echo "[Provision] Starting VM with virt-install..."
|
||||
sudo virt-install \
|
||||
VIRT_INSTALL_OUTPUT=$(sudo virt-install \
|
||||
--name "$VM_NAME" \
|
||||
--memory 2048 \
|
||||
--vcpus 2 \
|
||||
@@ -31,14 +32,21 @@ sudo virt-install \
|
||||
--noautoconsole \
|
||||
--wait 0 \
|
||||
--transient \
|
||||
2>&1 | grep -v "WARNING" || true
|
||||
2>&1) || {
|
||||
echo "[Provision] ERROR: virt-install failed"
|
||||
echo "$VIRT_INSTALL_OUTPUT" | grep -v "WARNING"
|
||||
echo "[Provision] Cleaning up disk..."
|
||||
sudo rm -f "$VM_DISK"
|
||||
echo "ERROR"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Wait for IP address
|
||||
echo "[Provision] Waiting for VM to obtain IP address (max ${MAX_WAIT}s)..."
|
||||
COUNTER=0
|
||||
while [ $COUNTER -lt $MAX_WAIT ]; do
|
||||
# Try to get IP from DHCP lease
|
||||
IP=$(sudo virsh domifaddr "$VM_NAME" --source lease 2>/dev/null | awk '/ipv4/ {print $4}' | cut -d/ -f1 | head -1)
|
||||
# Try to get IP from DHCP lease (explicitly use system connection)
|
||||
IP=$(sudo virsh -c qemu:///system domifaddr "$VM_NAME" --source lease 2>/dev/null | awk '/ipv4/ {print $4}' | cut -d/ -f1 | head -1)
|
||||
|
||||
if [ -n "$IP" ] && [ "$IP" != "0.0.0.0" ]; then
|
||||
echo "[Provision] IP obtained: $IP"
|
||||
|
||||
60
scripts/run-test.sh
Executable file
60
scripts/run-test.sh
Executable file
@@ -0,0 +1,60 @@
|
||||
#!/bin/bash
|
||||
|
||||
TEST_NAME="$1"
|
||||
TEST_REPO="$2"
|
||||
GOLDEN_IMAGE="$3"
|
||||
SSH_KEY="${4:-$HOME/.ssh/id_rsa}"
|
||||
|
||||
if [ -z "$TEST_NAME" ] || [ -z "$TEST_REPO" ] || [ -z "$GOLDEN_IMAGE" ]; then
|
||||
echo "Usage: $0 <test_name> <test_repo_url> <golden_image> [ssh_key]"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
VM_NAME="$TEST_NAME-$$"
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
WORK_DIR="/tmp/test-$VM_NAME"
|
||||
|
||||
mkdir -p "$WORK_DIR"
|
||||
cd "$WORK_DIR"
|
||||
|
||||
cleanup() {
|
||||
echo "Cleaning up..."
|
||||
"$SCRIPT_DIR/cleanup_vm.sh" "$VM_NAME" 2>/dev/null || true
|
||||
cd /tmp
|
||||
rm -rf "$WORK_DIR"
|
||||
}
|
||||
|
||||
trap cleanup EXIT
|
||||
|
||||
echo "Provisioning VM..."
|
||||
VM_IP=$("$SCRIPT_DIR/provision_vm.sh" "$VM_NAME" "$GOLDEN_IMAGE" 60 | tail -1)
|
||||
|
||||
if [ -z "$VM_IP" ] || [ "$VM_IP" = "ERROR" ]; then
|
||||
echo "ERROR: Failed to provision VM"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "VM ready at $VM_IP"
|
||||
|
||||
echo "Cloning test repository..."
|
||||
git clone "$TEST_REPO" test-repo
|
||||
|
||||
SPARROWFILE=$(find test-repo -name "main.raku" -o -name "sparrowfile" | head -1)
|
||||
|
||||
if [ -z "$SPARROWFILE" ]; then
|
||||
echo "ERROR: No sparrowfile found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Running test: $SPARROWFILE"
|
||||
sparrowdo \
|
||||
--host="$VM_IP" \
|
||||
--ssh_user=rocky \
|
||||
--ssh_private_key="$SSH_KEY" \
|
||||
--ssh_args="-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null" \
|
||||
--no_sudo \
|
||||
--sparrowfile="$SPARROWFILE" \
|
||||
--verbose \
|
||||
--color
|
||||
|
||||
echo "Test completed successfully"
|
||||
@@ -37,6 +37,7 @@ if [ -f "$PREP_SCRIPT_PATH" ]; then
|
||||
sudo virt-customize -a "$GOLDEN_IMAGE" \
|
||||
--run "$PREP_SCRIPT_PATH" \
|
||||
--ssh-inject root:file:"$SSH_PUB_KEY" \
|
||||
--ssh-inject rocky:file:"$SSH_PUB_KEY" \
|
||||
--root-password password:rockytesting \
|
||||
--selinux-relabel 2>&1 || {
|
||||
echo "ERROR: virt-customize failed"
|
||||
|
||||
Reference in New Issue
Block a user