#!/bin/bash # # Manual Test Run - Simulates Jenkins Pipeline Steps # This script walks through all the steps Jenkins would take # set -e # Colors for output GREEN='\033[0;32m' BLUE='\033[0;34m' YELLOW='\033[1;33m' RED='\033[0;31m' NC='\033[0m' # No Color echo_step() { echo -e "${BLUE}========================================${NC}" echo -e "${BLUE}$1${NC}" echo -e "${BLUE}========================================${NC}" } echo_info() { echo -e "${GREEN}[INFO]${NC} $1" } echo_warn() { echo -e "${YELLOW}[WARN]${NC} $1" } echo_error() { echo -e "${RED}[ERROR]${NC} $1" } # ============================================================================= # CONFIGURATION - Edit these variables # ============================================================================= # Build ID (simulating Jenkins BUILD_NUMBER) BUILD_ID="manual-$(date +%s)" # QCOW2 Image URL QCOW2_URL="https://download.rockylinux.org/pub/rocky/9/images/x86_64/Rocky-9-GenericCloud-Base.latest.x86_64.qcow2" # Image storage directory IMAGES_DIR="/var/lib/libvirt/images" # Image download behavior # Set to "true" to force re-download even if cached image exists REDOWNLOAD_IMAGE="false" # SSH Keys SSH_PRIVATE_KEY="${HOME}/.ssh/id_rsa" SSH_PUBLIC_KEY="${HOME}/.ssh/id_rsa.pub" # Test repository configuration # Edit this to point to your actual test repository TEST_NAME="example-test" TEST_REPO_URL="https://github.com/your-org/your-test-repo.git" TEST_REPO_BRANCH="main" # Working directory (this script's location) SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )/.." && pwd )" WORK_DIR="${SCRIPT_DIR}/manual-test-${BUILD_ID}" # Golden image prep script location PREP_SCRIPT="${SCRIPT_DIR}/docs/default-prep.sh" # ============================================================================= # Step 1: Initialize # ============================================================================= echo_step "Step 1: Initialize Environment" echo_info "Build ID: ${BUILD_ID}" echo_info "Working Directory: ${WORK_DIR}" echo_info "Images Directory: ${IMAGES_DIR}" echo_info "Scripts Directory: ${SCRIPT_DIR}/scripts" # Create working directory mkdir -p "${WORK_DIR}" cd "${WORK_DIR}" # Ensure images directory exists sudo mkdir -p "${IMAGES_DIR}" sudo chown ${USER}:${USER} "${IMAGES_DIR}" # Make scripts executable chmod +x "${SCRIPT_DIR}/scripts"/*.sh echo_info "Initialization complete" echo "" read -p "Press Enter to continue to Step 2..." # ============================================================================= # Step 2: Download Base Image # ============================================================================= echo_step "Step 2: Download Base QCOW2 Image" # Extract filename from URL for caching IMAGE_FILENAME=$(basename "${QCOW2_URL}") CACHED_IMAGE="${IMAGES_DIR}/${IMAGE_FILENAME}" BASE_IMAGE="${IMAGES_DIR}/base-${BUILD_ID}.qcow2" echo_info "Image URL: ${QCOW2_URL}" echo_info "Cached image path: ${CACHED_IMAGE}" echo_info "Build-specific image: ${BASE_IMAGE}" echo_info "Redownload setting: ${REDOWNLOAD_IMAGE}" echo "" if [ "${REDOWNLOAD_IMAGE}" = "true" ]; then echo_warn "REDOWNLOAD_IMAGE is enabled - forcing fresh download" echo_info "Downloading from: ${QCOW2_URL}" curl -L --progress-bar -o "${BASE_IMAGE}" "${QCOW2_URL}" else if [ -f "${CACHED_IMAGE}" ]; then echo_info "Found cached image: ${CACHED_IMAGE}" echo_info "Creating copy for build ${BUILD_ID}..." cp "${CACHED_IMAGE}" "${BASE_IMAGE}" else echo_info "No cached image found at: ${CACHED_IMAGE}" echo_info "Downloading from: ${QCOW2_URL}" curl -L --progress-bar -o "${CACHED_IMAGE}" "${QCOW2_URL}" echo_info "Creating copy for build ${BUILD_ID}..." cp "${CACHED_IMAGE}" "${BASE_IMAGE}" fi fi echo "" echo_info "Verifying image..." qemu-img info "${BASE_IMAGE}" | head -10 echo "" read -p "Press Enter to continue to Step 3..." # ============================================================================= # Step 3: Prepare Golden Image # ============================================================================= echo_step "Step 3: Prepare Golden Image" GOLDEN_IMAGE="${IMAGES_DIR}/golden-${BUILD_ID}.qcow2" echo_info "Golden image will be created at: ${GOLDEN_IMAGE}" echo_info "Using prep script: ${PREP_SCRIPT}" echo_info "Using SSH public key: ${SSH_PUBLIC_KEY}" # Check if prep script exists if [ ! -f "${PREP_SCRIPT}" ]; then echo_error "Prep script not found: ${PREP_SCRIPT}" echo_info "You can create it or use the default one in docs/" exit 1 fi # Check if SSH keys exist if [ ! -f "${SSH_PUBLIC_KEY}" ]; then echo_error "SSH public key not found: ${SSH_PUBLIC_KEY}" echo_info "Generate one with: ssh-keygen -t rsa -b 4096 -f ${HOME}/.ssh/id_rsa" exit 1 fi echo_info "Running setup_base.sh..." "${SCRIPT_DIR}/scripts/setup_base.sh" \ "${BASE_IMAGE}" \ "${PREP_SCRIPT}" \ "${GOLDEN_IMAGE}" \ "${SSH_PUBLIC_KEY}" echo_info "Golden image ready: ${GOLDEN_IMAGE}" echo "" read -p "Press Enter to continue to Step 4 (Bootstrap)..." # ============================================================================= # Step 4: Bootstrap Golden Image # ============================================================================= echo_step "Step 4: Bootstrap Golden Image with Sparrowdo" echo_info "Bootstrapping installs Sparrowdo and dependencies ONCE in the golden image" echo_info "This allows all test VMs to skip bootstrap and run tests immediately" echo "" "${SCRIPT_DIR}/scripts/bootstrap_golden.sh" "${GOLDEN_IMAGE}" "${SSH_PRIVATE_KEY}" echo "" read -p "Press Enter to continue to Step 5 (Provision Test VM)..." # ============================================================================= # Step 5: Provision Test VM # ============================================================================= echo_step "Step 5: Provision Test VM" VM_NAME="${TEST_NAME}-${BUILD_ID}" echo_info "Creating VM: ${VM_NAME}" echo_info "Using golden image: ${GOLDEN_IMAGE}" # Provision VM and capture output PROVISION_OUTPUT=$("${SCRIPT_DIR}/scripts/provision_vm.sh" "${VM_NAME}" "${GOLDEN_IMAGE}" 60) # Extract just the IP address (last line of output) VM_IP=$(echo "$PROVISION_OUTPUT" | tail -1) if [ "$VM_IP" = "ERROR" ] || [ -z "$VM_IP" ]; then echo_error "Failed to provision VM" echo_error "Provision output:" echo "$PROVISION_OUTPUT" exit 1 fi echo_info "VM provisioned successfully" echo_info "IP Address: ${VM_IP}" # Wait for SSH to be ready (test with rocky user) echo_info "Waiting for SSH to be ready (testing with rocky user)..." 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_info "SSH connection established for rocky user" break fi echo_info "Attempt $i/30..." sleep 2 done echo "" read -p "Press Enter to continue to Step 6 (Clone Test Repository)..." # ============================================================================= # Step 6: Clone Test Repository # ============================================================================= echo_step "Step 6: Clone Test Repository" echo_info "Cloning: ${TEST_REPO_URL}" echo_info "Branch: ${TEST_REPO_BRANCH}" # Create test workspace TEST_WORKSPACE="${WORK_DIR}/test-workspace" mkdir -p "${TEST_WORKSPACE}" cd "${TEST_WORKSPACE}" # Clone the test repository if git clone -b "${TEST_REPO_BRANCH}" "${TEST_REPO_URL}" test-repo; then echo_info "Repository cloned successfully" else echo_error "Failed to clone repository" echo_warn "Cleanup will still run. Press Ctrl+C to abort or Enter to continue cleanup..." read "${SCRIPT_DIR}/scripts/cleanup_vm.sh" "${VM_NAME}" exit 1 fi # Find sparrowfile (look for main.raku or sparrowfile) SPARROWFILE=$(find test-repo -name main.raku -type f | head -1) if [ -z "$SPARROWFILE" ]; then SPARROWFILE=$(find test-repo -name sparrowfile -type f | head -1) fi if [ -z "$SPARROWFILE" ]; then echo_error "No sparrowfile or main.raku found in repository" echo_warn "Cleanup will still run. Press Ctrl+C to abort or Enter to continue cleanup..." read "${SCRIPT_DIR}/scripts/cleanup_vm.sh" "${VM_NAME}" exit 1 fi echo_info "Found sparrowfile: ${SPARROWFILE}" echo "" read -p "Press Enter to continue to Step 7 (Run Test)..." # ============================================================================= # Step 7: Run Sparrowdo Test # ============================================================================= echo_step "Step 7: Run Sparrowdo Test" # Create logs directory mkdir -p logs echo_info "Running Sparrowdo test against VM..." echo_info "Target: rocky@${VM_IP}" echo_info "Sparrowfile: ${SPARROWFILE}" # Run sparrowdo test if timeout 900 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" \ --no_sudo \ --sparrowfile="${SPARROWFILE}" \ --verbose \ --color 2>&1 | tee logs/test.log; then echo_info "Test completed successfully!" else echo_error "Test failed or timed out" echo_info "Logs saved to: ${TEST_WORKSPACE}/logs/test.log" fi echo "" echo_info "Test logs location: ${TEST_WORKSPACE}/logs/test.log" echo "" read -p "Press Enter to continue to Step 8 (Cleanup)..." # ============================================================================= # Step 8: Cleanup # ============================================================================= echo_step "Step 8: Cleanup" echo_info "Cleaning up VM: ${VM_NAME}" "${SCRIPT_DIR}/scripts/cleanup_vm.sh" "${VM_NAME}" echo "" echo_warn "Do you want to remove temporary images? (y/n)" echo_info "Base image: ${BASE_IMAGE}" echo_info "Golden image: ${GOLDEN_IMAGE}" read -p "Remove images? (y/n): " -n 1 -r echo if [[ $REPLY =~ ^[Yy]$ ]]; then echo_info "Removing temporary images..." sudo rm -f "${BASE_IMAGE}" sudo rm -f "${GOLDEN_IMAGE}" echo_info "Images removed" else echo_info "Images preserved for inspection" echo_info "Base image: ${BASE_IMAGE}" echo_info "Golden image: ${GOLDEN_IMAGE}" fi # ============================================================================= # Summary # ============================================================================= echo "" echo_step "Summary" echo_info "Build ID: ${BUILD_ID}" echo_info "Test Name: ${TEST_NAME}" echo_info "Working Directory: ${WORK_DIR}" echo_info "Test Logs: ${TEST_WORKSPACE}/logs/test.log" if [ -f "${BASE_IMAGE}" ]; then echo_info "Base Image: ${BASE_IMAGE} (preserved)" fi if [ -f "${GOLDEN_IMAGE}" ]; then echo_info "Golden Image: ${GOLDEN_IMAGE} (preserved)" fi echo "" echo_info "Manual test run complete!"