diff --git a/.github/workflows/build-azl3-dlstreamer.yml b/.github/workflows/build-azl3-dlstreamer.yml new file mode 100644 index 00000000..698a9582 --- /dev/null +++ b/.github/workflows/build-azl3-dlstreamer.yml @@ -0,0 +1,107 @@ +name: Build AZL3 DLStreamer Image +on: + workflow_dispatch: # Manual runs + inputs: + ref: + description: "Branch or SHA to test (e.g. feature/x or a1b2c3)" + required: false + run_qemu_test: + description: "Run QEMU boot test after build" + required: false + default: "false" + type: choice + options: + - "true" + - "false" + push: + branches: + - main + pull_request: + branches: + - main + +permissions: + contents: read + +jobs: + build-azl3-dlstreamer: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + ref: ${{ github.event.inputs.ref || github.ref }} + persist-credentials: false + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Install Earthly + uses: earthly/actions-setup@v1 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + version: "latest" + + - name: Install system deps + run: | + sudo apt-get update + sudo apt-get install -y qemu-system-x86 ovmf tree jq systemd-ukify mmdebstrap systemd-boot + + - name: Set up Go + uses: actions/setup-go@v5 + with: + go-version: stable + + - name: Prepare build script + run: | + if [ ! -f scripts/build_azl3_dlstreamer.sh ]; then + echo "scripts/build_azl3_dlstreamer.sh not found!" + exit 1 + fi + chmod +x scripts/build_azl3_dlstreamer.sh + + - name: Run AZL3 DLStreamer Image Build + env: + RUN_QEMU_TEST: ${{ github.event.inputs.run_qemu_test }} + run: | + echo "Starting AZL3 DLStreamer image build..." + # Ensure script has access to docker group for Earthly + sudo usermod -aG docker $USER + + # Prepare arguments with input validation + ARGS="" + case "${RUN_QEMU_TEST}" in + "true") + ARGS="--qemu-test" + echo "QEMU boot test will be run after build" + ;; + "false"|"") + echo "QEMU boot test will be skipped" + ;; + *) + echo "Invalid input for run_qemu_test: ${RUN_QEMU_TEST}" + exit 1 + ;; + esac + + # Run the AZL3 DLStreamer image build script + ./scripts/build_azl3_dlstreamer.sh $ARGS + echo "AZL3 DLStreamer image build completed." + + - name: Notify on failure + if: ${{ failure() && github.event_name == 'pull_request' }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + REVIEWER_ID: srmungar + run: | + PR_AUTHOR=$(jq --raw-output 'try .pull_request.user.login // empty' "$GITHUB_EVENT_PATH") + if [ -z "$PR_AUTHOR" ]; then + echo "PR_AUTHOR not found in event payload. Skipping notification." + exit 0 + fi + COMMENT_BODY="Hey @$PR_AUTHOR and @$REVIEWER_ID — the AZL3 DLStreamer image build has failed. Please check the logs." + curl -s -X POST \ + -H "Authorization: Bearer $GITHUB_TOKEN" \ + -H "Accept: application/vnd.github.v3+json" \ + --data "{\"body\": \"$COMMENT_BODY\"}" \ + "https://api.github.com/repos/${{ github.repository }}/issues/${{ github.event.pull_request.number }}/comments" diff --git a/.github/workflows/build-elxr12-dlstreamer.yml b/.github/workflows/build-elxr12-dlstreamer.yml new file mode 100644 index 00000000..ff81dd3c --- /dev/null +++ b/.github/workflows/build-elxr12-dlstreamer.yml @@ -0,0 +1,107 @@ +name: Build ELXR12 DLStreamer Image +on: + workflow_dispatch: # Manual runs + inputs: + ref: + description: "Branch or SHA to test (e.g. feature/x or a1b2c3)" + required: false + run_qemu_test: + description: "Run QEMU boot test after build" + required: false + default: "false" + type: choice + options: + - "true" + - "false" + push: + branches: + - main + pull_request: + branches: + - main + +permissions: + contents: read + +jobs: + build-elxr12-dlstreamer: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + ref: ${{ github.event.inputs.ref || github.ref }} + persist-credentials: false + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Install Earthly + uses: earthly/actions-setup@v1 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + version: "latest" + + - name: Install system deps + run: | + sudo apt-get update + sudo apt-get install -y qemu-system-x86 ovmf tree jq systemd-ukify mmdebstrap systemd-boot + + - name: Set up Go + uses: actions/setup-go@v5 + with: + go-version: stable + + - name: Prepare build script + run: | + if [ ! -f scripts/build_elxr12_dlstreamer.sh ]; then + echo "scripts/build_elxr12_dlstreamer.sh not found!" + exit 1 + fi + chmod +x scripts/build_elxr12_dlstreamer.sh + + - name: Run ELXR12 DLStreamer Image Build + env: + RUN_QEMU_TEST: ${{ github.event.inputs.run_qemu_test }} + run: | + echo "Starting ELXR12 DLStreamer image build..." + # Ensure script has access to docker group for Earthly + sudo usermod -aG docker $USER + + # Prepare arguments with input validation + ARGS="" + case "${RUN_QEMU_TEST}" in + "true") + ARGS="--qemu-test" + echo "QEMU boot test will be run after build" + ;; + "false"|"") + echo "QEMU boot test will be skipped" + ;; + *) + echo "Invalid input for run_qemu_test: ${RUN_QEMU_TEST}" + exit 1 + ;; + esac + + # Run the ELXR12 DLStreamer image build script + ./scripts/build_elxr12_dlstreamer.sh $ARGS + echo "ELXR12 DLStreamer image build completed." + + - name: Notify on failure + if: ${{ failure() && github.event_name == 'pull_request' }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + REVIEWER_ID: srmungar + run: | + PR_AUTHOR=$(jq --raw-output 'try .pull_request.user.login // empty' "$GITHUB_EVENT_PATH") + if [ -z "$PR_AUTHOR" ]; then + echo "PR_AUTHOR not found in event payload. Skipping notification." + exit 0 + fi + COMMENT_BODY="Hey @$PR_AUTHOR and @$REVIEWER_ID — the ELXR12 DLStreamer image build has failed. Please check the logs." + curl -s -X POST \ + -H "Authorization: Bearer $GITHUB_TOKEN" \ + -H "Accept: application/vnd.github.v3+json" \ + --data "{\"body\": \"$COMMENT_BODY\"}" \ + "https://api.github.com/repos/${{ github.repository }}/issues/${{ github.event.pull_request.number }}/comments" diff --git a/.github/workflows/build-emt3-dlstreamer.yml b/.github/workflows/build-emt3-dlstreamer.yml new file mode 100644 index 00000000..033e8df8 --- /dev/null +++ b/.github/workflows/build-emt3-dlstreamer.yml @@ -0,0 +1,107 @@ +name: Build EMT3 DLStreamer Image +on: + workflow_dispatch: # Manual runs + inputs: + ref: + description: "Branch or SHA to test (e.g. feature/x or a1b2c3)" + required: false + run_qemu_test: + description: "Run QEMU boot test after build" + required: false + default: "false" + type: choice + options: + - "true" + - "false" + push: + branches: + - main + pull_request: + branches: + - main + +permissions: + contents: read + +jobs: + build-emt3-dlstreamer: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + ref: ${{ github.event.inputs.ref || github.ref }} + persist-credentials: false + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Install Earthly + uses: earthly/actions-setup@v1 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + version: "latest" + + - name: Install system deps + run: | + sudo apt-get update + sudo apt-get install -y qemu-system-x86 ovmf tree jq systemd-ukify mmdebstrap systemd-boot + + - name: Set up Go + uses: actions/setup-go@v5 + with: + go-version: stable + + - name: Prepare build script + run: | + if [ ! -f scripts/build_emt3_dlstreamer.sh ]; then + echo "scripts/build_emt3_dlstreamer.sh not found!" + exit 1 + fi + chmod +x scripts/build_emt3_dlstreamer.sh + + - name: Run EMT3 DLStreamer Image Build + env: + RUN_QEMU_TEST: ${{ github.event.inputs.run_qemu_test }} + run: | + echo "Starting EMT3 DLStreamer image build..." + # Ensure script has access to docker group for Earthly + sudo usermod -aG docker $USER + + # Prepare arguments with input validation + ARGS="" + case "${RUN_QEMU_TEST}" in + "true") + ARGS="--qemu-test" + echo "QEMU boot test will be run after build" + ;; + "false"|"") + echo "QEMU boot test will be skipped" + ;; + *) + echo "Invalid input for run_qemu_test: ${RUN_QEMU_TEST}" + exit 1 + ;; + esac + + # Run the EMT3 DLStreamer image build script + ./scripts/build_emt3_dlstreamer.sh $ARGS + echo "EMT3 DLStreamer image build completed." + + - name: Notify on failure + if: ${{ failure() && github.event_name == 'pull_request' }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + REVIEWER_ID: srmungar + run: | + PR_AUTHOR=$(jq --raw-output 'try .pull_request.user.login // empty' "$GITHUB_EVENT_PATH") + if [ -z "$PR_AUTHOR" ]; then + echo "PR_AUTHOR not found in event payload. Skipping notification." + exit 0 + fi + COMMENT_BODY="Hey @$PR_AUTHOR and @$REVIEWER_ID — the EMT3 DLStreamer image build has failed. Please check the logs." + curl -s -X POST \ + -H "Authorization: Bearer $GITHUB_TOKEN" \ + -H "Accept: application/vnd.github.v3+json" \ + --data "{\"body\": \"$COMMENT_BODY\"}" \ + "https://api.github.com/repos/${{ github.repository }}/issues/${{ github.event.pull_request.number }}/comments" diff --git a/.github/workflows/build-ubuntu24-dlstreamer.yml b/.github/workflows/build-ubuntu24-dlstreamer.yml new file mode 100644 index 00000000..5dd9ac68 --- /dev/null +++ b/.github/workflows/build-ubuntu24-dlstreamer.yml @@ -0,0 +1,107 @@ +name: Build Ubuntu24 DLStreamer Image +on: + workflow_dispatch: # Manual runs + inputs: + ref: + description: "Branch or SHA to test (e.g. feature/x or a1b2c3)" + required: false + run_qemu_test: + description: "Run QEMU boot test after build" + required: false + default: "false" + type: choice + options: + - "true" + - "false" + push: + branches: + - main + pull_request: + branches: + - main + +permissions: + contents: read + +jobs: + build-ubuntu24-dlstreamer: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + ref: ${{ github.event.inputs.ref || github.ref }} + persist-credentials: false + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Install Earthly + uses: earthly/actions-setup@v1 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + version: "latest" + + - name: Install system deps + run: | + sudo apt-get update + sudo apt-get install -y qemu-system-x86 ovmf tree jq systemd-ukify mmdebstrap systemd-boot + + - name: Set up Go + uses: actions/setup-go@v5 + with: + go-version: stable + + - name: Prepare build script + run: | + if [ ! -f scripts/build_ubuntu24_dlstreamer.sh ]; then + echo "scripts/build_ubuntu24_dlstreamer.sh not found!" + exit 1 + fi + chmod +x scripts/build_ubuntu24_dlstreamer.sh + + - name: Run Ubuntu24 DLStreamer Image Build + env: + RUN_QEMU_TEST: ${{ github.event.inputs.run_qemu_test }} + run: | + echo "Starting Ubuntu24 DLStreamer image build..." + # Ensure script has access to docker group for Earthly + sudo usermod -aG docker $USER + + # Prepare arguments with input validation + ARGS="" + case "${RUN_QEMU_TEST}" in + "true") + ARGS="--qemu-test" + echo "QEMU boot test will be run after build" + ;; + "false"|"") + echo "QEMU boot test will be skipped" + ;; + *) + echo "Invalid input for run_qemu_test: ${RUN_QEMU_TEST}" + exit 1 + ;; + esac + + # Run the Ubuntu24 DLStreamer image build script + ./scripts/build_ubuntu24_dlstreamer.sh $ARGS + echo "Ubuntu24 DLStreamer image build completed." + + - name: Notify on failure + if: ${{ failure() && github.event_name == 'pull_request' }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + REVIEWER_ID: srmungar + run: | + PR_AUTHOR=$(jq --raw-output 'try .pull_request.user.login // empty' "$GITHUB_EVENT_PATH") + if [ -z "$PR_AUTHOR" ]; then + echo "PR_AUTHOR not found in event payload. Skipping notification." + exit 0 + fi + COMMENT_BODY="Hey @$PR_AUTHOR and @$REVIEWER_ID — the Ubuntu24 DLStreamer image build has failed. Please check the logs." + curl -s -X POST \ + -H "Authorization: Bearer $GITHUB_TOKEN" \ + -H "Accept: application/vnd.github.v3+json" \ + --data "{\"body\": \"$COMMENT_BODY\"}" \ + "https://api.github.com/repos/${{ github.repository }}/issues/${{ github.event.pull_request.number }}/comments" diff --git a/scripts/build_azl3_dlstreamer.sh b/scripts/build_azl3_dlstreamer.sh new file mode 100755 index 00000000..ddeb52f2 --- /dev/null +++ b/scripts/build_azl3_dlstreamer.sh @@ -0,0 +1,192 @@ +#!/bin/bash +set -euo pipefail + +# Parse command line arguments +RUN_QEMU_TESTS=false +WORKING_DIR="$(pwd)" + +while [[ $# -gt 0 ]]; do + case $1 in + --qemu-test|--with-qemu) + RUN_QEMU_TESTS=true + shift + ;; + --working-dir) + WORKING_DIR="$2" + shift 2 + ;; + -h|--help) + echo "Usage: $0 [--qemu-test|--with-qemu] [--working-dir DIR]" + echo " --qemu-test, --with-qemu Run QEMU boot tests after image build" + echo " --working-dir DIR Set the working directory" + echo " -h, --help Show this help message" + exit 0 + ;; + *) + echo "Unknown option $1" + echo "Use -h or --help for usage information" + exit 1 + ;; + esac +done + +# Centralized cleanup function for image files +cleanup_image_files() { + local cleanup_type="${1:-all}" + + case "$cleanup_type" in + "raw") + echo "Cleaning up raw image files from build directories..." + sudo rm -rf ./tmp/*/imagebuild/*/*.raw 2>/dev/null || true + sudo rm -rf ./workspace/*/imagebuild/*/*.raw 2>/dev/null || true + ;; + "extracted") + echo "Cleaning up extracted image files in current directory..." + rm -f ./*.raw 2>/dev/null || true + ;; + "all"|*) + echo "Cleaning up all temporary image files..." + sudo rm -rf ./tmp/*/imagebuild/*/*.raw 2>/dev/null || true + sudo rm -rf ./workspace/*/imagebuild/*/*.raw 2>/dev/null || true + rm -f ./*.raw 2>/dev/null || true + ;; + esac +} + +run_qemu_boot_test() { + local IMAGE_PATTERN="$1" + if [ -z "$IMAGE_PATTERN" ]; then + echo "Error: Image pattern not provided to run_qemu_boot_test" + return 1 + fi + + local RAW_IMAGE="" + local SUCCESS_STRING="login:" + local LOGFILE="/tmp/qemu_boot_test_${IMAGE_PATTERN}.log" + local ORIGINAL_DIR + ORIGINAL_DIR="$(pwd)" + + echo "Looking for compressed raw image matching pattern: *${IMAGE_PATTERN}*.raw.gz" + + cd "$WORKING_DIR" + + if ls ./*"${IMAGE_PATTERN}"*.raw.gz 1>/dev/null 2>&1; then + GZ_IMAGE=$(ls ./*"${IMAGE_PATTERN}"*.raw.gz | head -1) + echo "Found compressed image: $GZ_IMAGE" + echo "Extracting..." + gunzip -k "$GZ_IMAGE" + RAW_IMAGE="${GZ_IMAGE%.gz}" + + if [ ! -f "$RAW_IMAGE" ]; then + echo "Error: extraction failed, $RAW_IMAGE not found" + cd "$ORIGINAL_DIR" + return 1 + fi + + IMAGE="$RAW_IMAGE" + else + echo "Compressed raw image file matching pattern '*${IMAGE_PATTERN}*.raw.gz' not found!" + return 1 + fi + + echo "Booting image: $IMAGE" + sudo bash -c " + LOGFILE=\"$LOGFILE\" + SUCCESS_STRING=\"$SUCCESS_STRING\" + IMAGE=\"$IMAGE\" + RAW_IMAGE=\"$RAW_IMAGE\" + ORIGINAL_DIR=\"$ORIGINAL_DIR\" + + touch \"\$LOGFILE\" && chmod 666 \"\$LOGFILE\" + nohup qemu-system-x86_64 \\ + -m 2048 \\ + -enable-kvm \\ + -cpu host \\ + -drive if=none,file=\"\$IMAGE\",format=raw,id=nvme0 \\ + -device nvme,drive=nvme0,serial=deadbeef \\ + -drive if=pflash,format=raw,readonly=on,file=/usr/share/OVMF/OVMF_CODE_4M.fd \\ + -drive if=pflash,format=raw,file=/usr/share/OVMF/OVMF_VARS_4M.fd \\ + -nographic \\ + -serial mon:stdio \\ + -append 'console=ttyS0' > \"\$LOGFILE\" 2>&1 & + + QEMU_PID=\$! + TIMEOUT=180 + ELAPSED=0 + + while [ \$ELAPSED -lt \$TIMEOUT ]; do + if grep -q \"\$SUCCESS_STRING\" \"\$LOGFILE\" 2>/dev/null; then + echo \"Boot successful - found '\$SUCCESS_STRING' in output\" + kill \$QEMU_PID 2>/dev/null || true + break + fi + if ! ps -p \$QEMU_PID > /dev/null 2>&1; then + echo \"QEMU process exited unexpectedly\" + break + fi + sleep 5 + ELAPSED=\$((ELAPSED + 5)) + echo \"Waiting for boot... (\${ELAPSED}s/\${TIMEOUT}s)\" + done + + kill \$QEMU_PID 2>/dev/null || true + + if grep -q \"\$SUCCESS_STRING\" \"\$LOGFILE\"; then + echo \"Boot test PASSED\" + result=0 + else + echo \"Boot failed or timed out\" + result=1 + fi + + if [ -f \"\$RAW_IMAGE\" ]; then + echo \"Cleaning up extracted image file: \$RAW_IMAGE\" + rm -f \"\$RAW_IMAGE\" + fi + + cd \"\$ORIGINAL_DIR\" + exit \$result + " + + qemu_result=$? + return $qemu_result +} + +git branch + +echo "Building the OS Image Composer..." +echo "Generating binary with go build..." +go build ./cmd/os-image-composer + +build_azl3_dlstreamer_image() { + echo "Building AZL3 DLStreamer Image. (using os-image-composer binary)" + echo "Ensuring we're in the working directory before starting builds..." + cd "$WORKING_DIR" + echo "Current working directory: $(pwd)" + + set +e + output=$(sudo -S ./os-image-composer build image-templates/azl3-x86_64-dlstreamer.yml 2>&1) + build_exit_code=$? + set -e + + if [ $build_exit_code -eq 0 ] && echo "$output" | grep -q "image build completed successfully"; then + echo "AZL3 DLStreamer Image build passed." + if [ "$RUN_QEMU_TESTS" = true ]; then + echo "Running QEMU boot test for AZL3 DLStreamer image..." + if run_qemu_boot_test "azl3-dlstreamer-x86_64"; then + echo "QEMU boot test PASSED for AZL3 DLStreamer image" + else + echo "QEMU boot test FAILED for AZL3 DLStreamer image" + exit 1 + fi + cleanup_image_files raw + fi + else + echo "AZL3 DLStreamer Image build failed." + echo "Build output:" + echo "$output" + exit 1 + fi +} + +build_azl3_dlstreamer_image diff --git a/scripts/build_elxr12_dlstreamer.sh b/scripts/build_elxr12_dlstreamer.sh new file mode 100755 index 00000000..7f763b27 --- /dev/null +++ b/scripts/build_elxr12_dlstreamer.sh @@ -0,0 +1,192 @@ +#!/bin/bash +set -euo pipefail + +# Parse command line arguments +RUN_QEMU_TESTS=false +WORKING_DIR="$(pwd)" + +while [[ $# -gt 0 ]]; do + case $1 in + --qemu-test|--with-qemu) + RUN_QEMU_TESTS=true + shift + ;; + --working-dir) + WORKING_DIR="$2" + shift 2 + ;; + -h|--help) + echo "Usage: $0 [--qemu-test|--with-qemu] [--working-dir DIR]" + echo " --qemu-test, --with-qemu Run QEMU boot tests after image build" + echo " --working-dir DIR Set the working directory" + echo " -h, --help Show this help message" + exit 0 + ;; + *) + echo "Unknown option $1" + echo "Use -h or --help for usage information" + exit 1 + ;; + esac +done + +# Centralized cleanup function for image files +cleanup_image_files() { + local cleanup_type="${1:-all}" + + case "$cleanup_type" in + "raw") + echo "Cleaning up raw image files from build directories..." + sudo rm -rf ./tmp/*/imagebuild/*/*.raw 2>/dev/null || true + sudo rm -rf ./workspace/*/imagebuild/*/*.raw 2>/dev/null || true + ;; + "extracted") + echo "Cleaning up extracted image files in current directory..." + rm -f ./*.raw 2>/dev/null || true + ;; + "all"|*) + echo "Cleaning up all temporary image files..." + sudo rm -rf ./tmp/*/imagebuild/*/*.raw 2>/dev/null || true + sudo rm -rf ./workspace/*/imagebuild/*/*.raw 2>/dev/null || true + rm -f ./*.raw 2>/dev/null || true + ;; + esac +} + +run_qemu_boot_test() { + local IMAGE_PATTERN="$1" + if [ -z "$IMAGE_PATTERN" ]; then + echo "Error: Image pattern not provided to run_qemu_boot_test" + return 1 + fi + + local RAW_IMAGE="" + local SUCCESS_STRING="login:" + local LOGFILE="/tmp/qemu_boot_test_${IMAGE_PATTERN}.log" + local ORIGINAL_DIR + ORIGINAL_DIR="$(pwd)" + + echo "Looking for compressed raw image matching pattern: *${IMAGE_PATTERN}*.raw.gz" + + cd "$WORKING_DIR" + + if ls ./*"${IMAGE_PATTERN}"*.raw.gz 1>/dev/null 2>&1; then + GZ_IMAGE=$(ls ./*"${IMAGE_PATTERN}"*.raw.gz | head -1) + echo "Found compressed image: $GZ_IMAGE" + echo "Extracting..." + gunzip -k "$GZ_IMAGE" + RAW_IMAGE="${GZ_IMAGE%.gz}" + + if [ ! -f "$RAW_IMAGE" ]; then + echo "Error: extraction failed, $RAW_IMAGE not found" + cd "$ORIGINAL_DIR" + return 1 + fi + + IMAGE="$RAW_IMAGE" + else + echo "Compressed raw image file matching pattern '*${IMAGE_PATTERN}*.raw.gz' not found!" + return 1 + fi + + echo "Booting image: $IMAGE" + sudo bash -c " + LOGFILE=\"$LOGFILE\" + SUCCESS_STRING=\"$SUCCESS_STRING\" + IMAGE=\"$IMAGE\" + RAW_IMAGE=\"$RAW_IMAGE\" + ORIGINAL_DIR=\"$ORIGINAL_DIR\" + + touch \"\$LOGFILE\" && chmod 666 \"\$LOGFILE\" + nohup qemu-system-x86_64 \\ + -m 2048 \\ + -enable-kvm \\ + -cpu host \\ + -drive if=none,file=\"\$IMAGE\",format=raw,id=nvme0 \\ + -device nvme,drive=nvme0,serial=deadbeef \\ + -drive if=pflash,format=raw,readonly=on,file=/usr/share/OVMF/OVMF_CODE_4M.fd \\ + -drive if=pflash,format=raw,file=/usr/share/OVMF/OVMF_VARS_4M.fd \\ + -nographic \\ + -serial mon:stdio \\ + -append 'console=ttyS0' > \"\$LOGFILE\" 2>&1 & + + QEMU_PID=\$! + TIMEOUT=180 + ELAPSED=0 + + while [ \$ELAPSED -lt \$TIMEOUT ]; do + if grep -q \"\$SUCCESS_STRING\" \"\$LOGFILE\" 2>/dev/null; then + echo \"Boot successful - found '\$SUCCESS_STRING' in output\" + kill \$QEMU_PID 2>/dev/null || true + break + fi + if ! ps -p \$QEMU_PID > /dev/null 2>&1; then + echo \"QEMU process exited unexpectedly\" + break + fi + sleep 5 + ELAPSED=\$((ELAPSED + 5)) + echo \"Waiting for boot... (\${ELAPSED}s/\${TIMEOUT}s)\" + done + + kill \$QEMU_PID 2>/dev/null || true + + if grep -q \"\$SUCCESS_STRING\" \"\$LOGFILE\"; then + echo \"Boot test PASSED\" + result=0 + else + echo \"Boot failed or timed out\" + result=1 + fi + + if [ -f \"\$RAW_IMAGE\" ]; then + echo \"Cleaning up extracted image file: \$RAW_IMAGE\" + rm -f \"\$RAW_IMAGE\" + fi + + cd \"\$ORIGINAL_DIR\" + exit \$result + " + + qemu_result=$? + return $qemu_result +} + +git branch + +echo "Building the OS Image Composer..." +echo "Generating binary with go build..." +go build ./cmd/os-image-composer + +build_elxr12_dlstreamer_image() { + echo "Building ELXR12 DLStreamer Image. (using os-image-composer binary)" + echo "Ensuring we're in the working directory before starting builds..." + cd "$WORKING_DIR" + echo "Current working directory: $(pwd)" + + set +e + output=$(sudo -S ./os-image-composer build image-templates/elxr12-x86_64-dlstreamer.yml 2>&1) + build_exit_code=$? + set -e + + if [ $build_exit_code -eq 0 ] && echo "$output" | grep -q "image build completed successfully"; then + echo "ELXR12 DLStreamer Image build passed." + if [ "$RUN_QEMU_TESTS" = true ]; then + echo "Running QEMU boot test for ELXR12 DLStreamer image..." + if run_qemu_boot_test "elxr12-dlstreamer-x86_64"; then + echo "QEMU boot test PASSED for ELXR12 DLStreamer image" + else + echo "QEMU boot test FAILED for ELXR12 DLStreamer image" + exit 1 + fi + cleanup_image_files raw + fi + else + echo "ELXR12 DLStreamer Image build failed." + echo "Build output:" + echo "$output" + exit 1 + fi +} + +build_elxr12_dlstreamer_image diff --git a/scripts/build_emt3_dlstreamer.sh b/scripts/build_emt3_dlstreamer.sh new file mode 100755 index 00000000..b82584a0 --- /dev/null +++ b/scripts/build_emt3_dlstreamer.sh @@ -0,0 +1,192 @@ +#!/bin/bash +set -euo pipefail + +# Parse command line arguments +RUN_QEMU_TESTS=false +WORKING_DIR="$(pwd)" + +while [[ $# -gt 0 ]]; do + case $1 in + --qemu-test|--with-qemu) + RUN_QEMU_TESTS=true + shift + ;; + --working-dir) + WORKING_DIR="$2" + shift 2 + ;; + -h|--help) + echo "Usage: $0 [--qemu-test|--with-qemu] [--working-dir DIR]" + echo " --qemu-test, --with-qemu Run QEMU boot tests after image build" + echo " --working-dir DIR Set the working directory" + echo " -h, --help Show this help message" + exit 0 + ;; + *) + echo "Unknown option $1" + echo "Use -h or --help for usage information" + exit 1 + ;; + esac +done + +# Centralized cleanup function for image files +cleanup_image_files() { + local cleanup_type="${1:-all}" + + case "$cleanup_type" in + "raw") + echo "Cleaning up raw image files from build directories..." + sudo rm -rf ./tmp/*/imagebuild/*/*.raw 2>/dev/null || true + sudo rm -rf ./workspace/*/imagebuild/*/*.raw 2>/dev/null || true + ;; + "extracted") + echo "Cleaning up extracted image files in current directory..." + rm -f ./*.raw 2>/dev/null || true + ;; + "all"|*) + echo "Cleaning up all temporary image files..." + sudo rm -rf ./tmp/*/imagebuild/*/*.raw 2>/dev/null || true + sudo rm -rf ./workspace/*/imagebuild/*/*.raw 2>/dev/null || true + rm -f ./*.raw 2>/dev/null || true + ;; + esac +} + +run_qemu_boot_test() { + local IMAGE_PATTERN="$1" + if [ -z "$IMAGE_PATTERN" ]; then + echo "Error: Image pattern not provided to run_qemu_boot_test" + return 1 + fi + + local RAW_IMAGE="" + local SUCCESS_STRING="login:" + local LOGFILE="/tmp/qemu_boot_test_${IMAGE_PATTERN}.log" + local ORIGINAL_DIR + ORIGINAL_DIR="$(pwd)" + + echo "Looking for compressed raw image matching pattern: *${IMAGE_PATTERN}*.raw.gz" + + cd "$WORKING_DIR" + + if ls ./*"${IMAGE_PATTERN}"*.raw.gz 1>/dev/null 2>&1; then + GZ_IMAGE=$(ls ./*"${IMAGE_PATTERN}"*.raw.gz | head -1) + echo "Found compressed image: $GZ_IMAGE" + echo "Extracting..." + gunzip -k "$GZ_IMAGE" + RAW_IMAGE="${GZ_IMAGE%.gz}" + + if [ ! -f "$RAW_IMAGE" ]; then + echo "Error: extraction failed, $RAW_IMAGE not found" + cd "$ORIGINAL_DIR" + return 1 + fi + + IMAGE="$RAW_IMAGE" + else + echo "Compressed raw image file matching pattern '*${IMAGE_PATTERN}*.raw.gz' not found!" + return 1 + fi + + echo "Booting image: $IMAGE" + sudo bash -c " + LOGFILE=\"$LOGFILE\" + SUCCESS_STRING=\"$SUCCESS_STRING\" + IMAGE=\"$IMAGE\" + RAW_IMAGE=\"$RAW_IMAGE\" + ORIGINAL_DIR=\"$ORIGINAL_DIR\" + + touch \"\$LOGFILE\" && chmod 666 \"\$LOGFILE\" + nohup qemu-system-x86_64 \\ + -m 2048 \\ + -enable-kvm \\ + -cpu host \\ + -drive if=none,file=\"\$IMAGE\",format=raw,id=nvme0 \\ + -device nvme,drive=nvme0,serial=deadbeef \\ + -drive if=pflash,format=raw,readonly=on,file=/usr/share/OVMF/OVMF_CODE_4M.fd \\ + -drive if=pflash,format=raw,file=/usr/share/OVMF/OVMF_VARS_4M.fd \\ + -nographic \\ + -serial mon:stdio \\ + -append 'console=ttyS0' > \"\$LOGFILE\" 2>&1 & + + QEMU_PID=\$! + TIMEOUT=180 + ELAPSED=0 + + while [ \$ELAPSED -lt \$TIMEOUT ]; do + if grep -q \"\$SUCCESS_STRING\" \"\$LOGFILE\" 2>/dev/null; then + echo \"Boot successful - found '\$SUCCESS_STRING' in output\" + kill \$QEMU_PID 2>/dev/null || true + break + fi + if ! ps -p \$QEMU_PID > /dev/null 2>&1; then + echo \"QEMU process exited unexpectedly\" + break + fi + sleep 5 + ELAPSED=\$((ELAPSED + 5)) + echo \"Waiting for boot... (\${ELAPSED}s/\${TIMEOUT}s)\" + done + + kill \$QEMU_PID 2>/dev/null || true + + if grep -q \"\$SUCCESS_STRING\" \"\$LOGFILE\"; then + echo \"Boot test PASSED\" + result=0 + else + echo \"Boot failed or timed out\" + result=1 + fi + + if [ -f \"\$RAW_IMAGE\" ]; then + echo \"Cleaning up extracted image file: \$RAW_IMAGE\" + rm -f \"\$RAW_IMAGE\" + fi + + cd \"\$ORIGINAL_DIR\" + exit \$result + " + + qemu_result=$? + return $qemu_result +} + +git branch + +echo "Building the OS Image Composer..." +echo "Generating binary with go build..." +go build ./cmd/os-image-composer + +build_emt3_dlstreamer_image() { + echo "Building EMT3 DLStreamer Image. (using os-image-composer binary)" + echo "Ensuring we're in the working directory before starting builds..." + cd "$WORKING_DIR" + echo "Current working directory: $(pwd)" + + set +e + output=$(sudo -S ./os-image-composer build image-templates/emt3-x86_64-dlstreamer.yml 2>&1) + build_exit_code=$? + set -e + + if [ $build_exit_code -eq 0 ] && echo "$output" | grep -q "image build completed successfully"; then + echo "EMT3 DLStreamer Image build passed." + if [ "$RUN_QEMU_TESTS" = true ]; then + echo "Running QEMU boot test for EMT3 DLStreamer image..." + if run_qemu_boot_test "emt3-x86_64-dlstreamer"; then + echo "QEMU boot test PASSED for EMT3 DLStreamer image" + else + echo "QEMU boot test FAILED for EMT3 DLStreamer image" + exit 1 + fi + cleanup_image_files raw + fi + else + echo "EMT3 DLStreamer Image build failed." + echo "Build output:" + echo "$output" + exit 1 + fi +} + +build_emt3_dlstreamer_image diff --git a/scripts/build_ubuntu24_dlstreamer.sh b/scripts/build_ubuntu24_dlstreamer.sh new file mode 100755 index 00000000..248b378e --- /dev/null +++ b/scripts/build_ubuntu24_dlstreamer.sh @@ -0,0 +1,192 @@ +#!/bin/bash +set -euo pipefail + +# Parse command line arguments +RUN_QEMU_TESTS=false +WORKING_DIR="$(pwd)" + +while [[ $# -gt 0 ]]; do + case $1 in + --qemu-test|--with-qemu) + RUN_QEMU_TESTS=true + shift + ;; + --working-dir) + WORKING_DIR="$2" + shift 2 + ;; + -h|--help) + echo "Usage: $0 [--qemu-test|--with-qemu] [--working-dir DIR]" + echo " --qemu-test, --with-qemu Run QEMU boot tests after image build" + echo " --working-dir DIR Set the working directory" + echo " -h, --help Show this help message" + exit 0 + ;; + *) + echo "Unknown option $1" + echo "Use -h or --help for usage information" + exit 1 + ;; + esac +done + +# Centralized cleanup function for image files +cleanup_image_files() { + local cleanup_type="${1:-all}" + + case "$cleanup_type" in + "raw") + echo "Cleaning up raw image files from build directories..." + sudo rm -rf ./tmp/*/imagebuild/*/*.raw 2>/dev/null || true + sudo rm -rf ./workspace/*/imagebuild/*/*.raw 2>/dev/null || true + ;; + "extracted") + echo "Cleaning up extracted image files in current directory..." + rm -f ./*.raw 2>/dev/null || true + ;; + "all"|*) + echo "Cleaning up all temporary image files..." + sudo rm -rf ./tmp/*/imagebuild/*/*.raw 2>/dev/null || true + sudo rm -rf ./workspace/*/imagebuild/*/*.raw 2>/dev/null || true + rm -f ./*.raw 2>/dev/null || true + ;; + esac +} + +run_qemu_boot_test() { + local IMAGE_PATTERN="$1" + if [ -z "$IMAGE_PATTERN" ]; then + echo "Error: Image pattern not provided to run_qemu_boot_test" + return 1 + fi + + local RAW_IMAGE="" + local SUCCESS_STRING="login:" + local LOGFILE="/tmp/qemu_boot_test_${IMAGE_PATTERN}.log" + local ORIGINAL_DIR + ORIGINAL_DIR="$(pwd)" + + echo "Looking for compressed raw image matching pattern: *${IMAGE_PATTERN}*.raw.gz" + + cd "$WORKING_DIR" + + if ls ./*"${IMAGE_PATTERN}"*.raw.gz 1>/dev/null 2>&1; then + GZ_IMAGE=$(ls ./*"${IMAGE_PATTERN}"*.raw.gz | head -1) + echo "Found compressed image: $GZ_IMAGE" + echo "Extracting..." + gunzip -k "$GZ_IMAGE" + RAW_IMAGE="${GZ_IMAGE%.gz}" + + if [ ! -f "$RAW_IMAGE" ]; then + echo "Error: extraction failed, $RAW_IMAGE not found" + cd "$ORIGINAL_DIR" + return 1 + fi + + IMAGE="$RAW_IMAGE" + else + echo "Compressed raw image file matching pattern '*${IMAGE_PATTERN}*.raw.gz' not found!" + return 1 + fi + + echo "Booting image: $IMAGE" + sudo bash -c " + LOGFILE=\"$LOGFILE\" + SUCCESS_STRING=\"$SUCCESS_STRING\" + IMAGE=\"$IMAGE\" + RAW_IMAGE=\"$RAW_IMAGE\" + ORIGINAL_DIR=\"$ORIGINAL_DIR\" + + touch \"\$LOGFILE\" && chmod 666 \"\$LOGFILE\" + nohup qemu-system-x86_64 \\ + -m 2048 \\ + -enable-kvm \\ + -cpu host \\ + -drive if=none,file=\"\$IMAGE\",format=raw,id=nvme0 \\ + -device nvme,drive=nvme0,serial=deadbeef \\ + -drive if=pflash,format=raw,readonly=on,file=/usr/share/OVMF/OVMF_CODE_4M.fd \\ + -drive if=pflash,format=raw,file=/usr/share/OVMF/OVMF_VARS_4M.fd \\ + -nographic \\ + -serial mon:stdio \\ + -append 'console=ttyS0' > \"\$LOGFILE\" 2>&1 & + + QEMU_PID=\$! + TIMEOUT=180 + ELAPSED=0 + + while [ \$ELAPSED -lt \$TIMEOUT ]; do + if grep -q \"\$SUCCESS_STRING\" \"\$LOGFILE\" 2>/dev/null; then + echo \"Boot successful - found '\$SUCCESS_STRING' in output\" + kill \$QEMU_PID 2>/dev/null || true + break + fi + if ! ps -p \$QEMU_PID > /dev/null 2>&1; then + echo \"QEMU process exited unexpectedly\" + break + fi + sleep 5 + ELAPSED=\$((ELAPSED + 5)) + echo \"Waiting for boot... (\${ELAPSED}s/\${TIMEOUT}s)\" + done + + kill \$QEMU_PID 2>/dev/null || true + + if grep -q \"\$SUCCESS_STRING\" \"\$LOGFILE\"; then + echo \"Boot test PASSED\" + result=0 + else + echo \"Boot failed or timed out\" + result=1 + fi + + if [ -f \"\$RAW_IMAGE\" ]; then + echo \"Cleaning up extracted image file: \$RAW_IMAGE\" + rm -f \"\$RAW_IMAGE\" + fi + + cd \"\$ORIGINAL_DIR\" + exit \$result + " + + qemu_result=$? + return $qemu_result +} + +git branch + +echo "Building the OS Image Composer..." +echo "Generating binary with go build..." +go build ./cmd/os-image-composer + +build_ubuntu24_dlstreamer_image() { + echo "Building Ubuntu24 DLStreamer Image. (using os-image-composer binary)" + echo "Ensuring we're in the working directory before starting builds..." + cd "$WORKING_DIR" + echo "Current working directory: $(pwd)" + + set +e + output=$(sudo -S ./os-image-composer build image-templates/ubuntu24-x86_64-dlstreamer.yml 2>&1) + build_exit_code=$? + set -e + + if [ $build_exit_code -eq 0 ] && echo "$output" | grep -q "image build completed successfully"; then + echo "Ubuntu24 DLStreamer Image build passed." + if [ "$RUN_QEMU_TESTS" = true ]; then + echo "Running QEMU boot test for Ubuntu24 DLStreamer image..." + if run_qemu_boot_test "ubuntu24-dlstreamer-x86_64"; then + echo "QEMU boot test PASSED for Ubuntu24 DLStreamer image" + else + echo "QEMU boot test FAILED for Ubuntu24 DLStreamer image" + exit 1 + fi + cleanup_image_files raw + fi + else + echo "Ubuntu24 DLStreamer Image build failed." + echo "Build output:" + echo "$output" + exit 1 + fi +} + +build_ubuntu24_dlstreamer_image