From 49093b10d58e99eefb72dd6c8ec45f08f22b3f4d Mon Sep 17 00:00:00 2001 From: Aidan Garske Date: Mon, 22 Dec 2025 09:32:37 -0800 Subject: [PATCH] Add WP Yocto Github Actions --- .github/scripts/boot-qemu.sh | 159 ++++++++ .github/scripts/yocto-verify-common.sh | 489 +++++++++++++++++++++++ .github/workflows/build-wolfprovider.yml | 203 +++++++++- .github/workflows/yocto-curl.yml | 123 ++++++ .github/workflows/yocto-librelp.yml | 123 ++++++ .github/workflows/yocto-openssh.yml | 120 ++++++ .github/workflows/yocto-openssl.yml | 120 ++++++ .github/workflows/yocto-rsyslog.yml | 120 ++++++ .github/workflows/yocto-test.yml | 140 +++++++ .github/workflows/yocto-verify.yml | 115 ++++++ 10 files changed, 1700 insertions(+), 12 deletions(-) create mode 100755 .github/scripts/boot-qemu.sh create mode 100644 .github/scripts/yocto-verify-common.sh create mode 100644 .github/workflows/yocto-curl.yml create mode 100644 .github/workflows/yocto-librelp.yml create mode 100644 .github/workflows/yocto-openssh.yml create mode 100644 .github/workflows/yocto-openssl.yml create mode 100644 .github/workflows/yocto-rsyslog.yml create mode 100644 .github/workflows/yocto-test.yml create mode 100644 .github/workflows/yocto-verify.yml diff --git a/.github/scripts/boot-qemu.sh b/.github/scripts/boot-qemu.sh new file mode 100755 index 00000000..6299ca79 --- /dev/null +++ b/.github/scripts/boot-qemu.sh @@ -0,0 +1,159 @@ +#!/bin/bash +# +# boot-qemu-wic.sh +# +# Copyright (C) 2006-2025 wolfSSL Inc. +# +# This file is part of wolfProvider. +# +# wolfProvider is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# wolfProvider is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with wolfProvider. If not, see . +# +# Boot a Yocto WIC image in QEMU and run commands +# Usage: boot-qemu-wic.sh "command1" "command2" "command3" ... +set -e + +WIC_FILE="$1" +shift + +if [ -z "$WIC_FILE" ] || [ ! -f "$WIC_FILE" ]; then + echo "ERROR: WIC file not found: $WIC_FILE" + echo "Usage: $0 [command2] ..." + exit 1 +fi + +if [ $# -eq 0 ]; then + echo "ERROR: No commands provided" + echo "Usage: $0 [command2] ..." + exit 1 +fi + +echo "=== Booting WIC image: $WIC_FILE ===" +echo "=== Commands to run: $# ===" + +# Create expect script dynamically +EXPECT_SCRIPT=$(mktemp /tmp/qemu-boot.XXXXXX.exp) + +cat > "$EXPECT_SCRIPT" <<'EXPECT_HEADER' +#!/usr/bin/expect +if {[info exists env(EXPECT_TIMEOUT)]} { + set timeout $env(EXPECT_TIMEOUT) +} else { + set timeout 10800 +} +log_user 1 + +# Get WIC path from environment +set wic_path $env(WIC_FILE) + +puts "=== Starting QEMU with WIC: $wic_path ===" + +# Boot QEMU with SandyBridge CPU (supports AVX for compatibility) +spawn qemu-system-x86_64 \ + -cpu SandyBridge \ + -drive file=$wic_path,if=virtio,format=raw \ + -m 2048 \ + -smp 2 \ + -nographic \ + -serial mon:stdio + +# Wait for login prompt +puts "=== Waiting for login prompt ===" +expect { + "login:" { + puts "=== Login prompt detected ===" + sleep 2 + send "root\r" + } + timeout { + puts "ERROR: Timeout waiting for login" + exit 1 + } +} + +# Wait for shell prompt +puts "=== Waiting for shell prompt ===" +expect { + -re "#|root@" { + puts "\n=== LOGGED IN SUCCESSFULLY ===" + } + "login:" { + puts "=== Got login again, retrying ===" + sleep 1 + send "root\r" + exp_continue + } + timeout { + puts "ERROR: Timeout waiting for shell" + exit 1 + } +} + +sleep 2 + +EXPECT_HEADER + +# Add each command to the expect script +CMD_NUM=1 +for cmd in "$@"; do + cat >> "$EXPECT_SCRIPT" <> "$EXPECT_SCRIPT" <<'EXPECT_FOOTER' + +# Shutdown +puts "=== All commands completed, shutting down ===" +send "poweroff\r" + +expect { + eof { + puts "\n=== QEMU SHUTDOWN COMPLETE ===" + } + timeout { + puts "\n=== Timeout on shutdown ===" + } +} +EXPECT_FOOTER + +# Make executable and run +chmod +x "$EXPECT_SCRIPT" + +echo "=== Generated expect script ===" + +# Export WIC_FILE for expect script +export WIC_FILE + +# Run the expect script +if "$EXPECT_SCRIPT"; then + EXIT_CODE=0 + echo "=== Boot and test completed successfully ===" +else + EXIT_CODE=$? + echo "=== Boot and test failed with exit code $EXIT_CODE ===" +fi + +# Cleanup +rm -f "$EXPECT_SCRIPT" + +exit $EXIT_CODE + diff --git a/.github/scripts/yocto-verify-common.sh b/.github/scripts/yocto-verify-common.sh new file mode 100644 index 00000000..d8fa7690 --- /dev/null +++ b/.github/scripts/yocto-verify-common.sh @@ -0,0 +1,489 @@ +#!/bin/bash +# +# yocto-verify-common.sh +# +# Copyright (C) 2006-2025 wolfSSL Inc. +# +# This file is part of wolfProvider. +# +# wolfProvider is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# wolfProvider is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA +# +# Common verification functions for wolfProvider yocto test images +# Source this file to use the verification functions and call the high-level +# wrapper functions in yocto-*.yml workflow files. + + +######################################################## +# Common verification functions +######################################################## + + +# Verify OpenSSL version +verify_openssl_version() { + local output_file="$1" + local expected_version="$2" + local errors_var="$3" # Name of errors variable to increment + + local openssl_line=$(grep -E "^OpenSSL [0-9]" "$output_file" | head -1) + if [ -z "$openssl_line" ]; then + echo "✗ ERROR: OpenSSL version line not found in output" + eval "$errors_var=\$((\$$errors_var + 1))" + return 1 + fi + + local actual_version=$(echo "$openssl_line" | grep -oE "[0-9]+\.[0-9]+\.[0-9]+" | head -1) + local expected_num=$(echo "$expected_version" | grep -oE "[0-9]+\.[0-9]+\.[0-9]+" | head -1) + if [ -z "$expected_num" ]; then + expected_num="$expected_version" + fi + + if echo "$openssl_line" | grep -q "$expected_num"; then + echo "✓ OpenSSL version matches: $actual_version" + return 0 + else + echo "✗ ERROR: OpenSSL version mismatch" + echo " Expected: $expected_num" + echo " Found: $actual_version" + echo " Full line: $openssl_line" + eval "$errors_var=\$((\$$errors_var + 1))" + return 1 + fi +} + +# Verify wolfSSL version +verify_wolfssl_version() { + local output_file="$1" + local expected_version="$2" + local errors_var="$3" + + local wolfssl_line=$(grep -E "build info: wolfSSL" "$output_file" | head -1) + if [ -z "$wolfssl_line" ]; then + echo "✗ ERROR: wolfSSL version line not found in output" + eval "$errors_var=\$((\$$errors_var + 1))" + return 1 + fi + + local actual_version=$(echo "$wolfssl_line" | grep -oE "[0-9]+\.[0-9]+\.[0-9]+" | head -1) + local expected_num=$(echo "$expected_version" | grep -oE "[0-9]+\.[0-9]+\.[0-9]+" | head -1) + if [ -z "$expected_num" ]; then + expected_num="$expected_version" + fi + + if echo "$wolfssl_line" | grep -q "$expected_num"; then + echo "✓ wolfSSL version matches: $actual_version" + return 0 + else + echo "✗ ERROR: wolfSSL version mismatch" + echo " Expected: $expected_num" + echo " Found: $actual_version" + echo " Full line: $wolfssl_line" + eval "$errors_var=\$((\$$errors_var + 1))" + return 1 + fi +} + +# Verify FIPS mode loaded correctly +verify_fips_mode() { + local output_file="$1" + local expected_fips="$2" + local errors_var="$3" + + if [ "$expected_fips" = "FIPS" ]; then + if grep -q "Detected wolfSSL FIPS build\|FIPS Mode: Enabled" "$output_file"; then + echo "✓ FIPS mode detected correctly" + return 0 + else + echo "✗ ERROR: FIPS mode not detected (expected: FIPS)" + eval "$errors_var=\$((\$$errors_var + 1))" + return 1 + fi + else + if grep -q "Detected wolfSSL non-FIPS build\|FIPS Mode: Disabled" "$output_file"; then + echo "✓ Non-FIPS mode detected correctly" + return 0 + else + echo "✗ ERROR: Non-FIPS mode not detected (expected: non-FIPS)" + eval "$errors_var=\$((\$$errors_var + 1))" + return 1 + fi + fi +} + +# Verify provider mode loaded correctly (replace-default vs standalone) +verify_provider_mode() { + local output_file="$1" + local expected_replace_default="$2" + local errors_var="$3" + + local provider_output=$(sed -n '/Test 2: OpenSSL Provider List/,/Test [0-9]:/p' "$output_file" | head -n -1 2>/dev/null || sed -n '/Test 2: OpenSSL Provider List/,$p' "$output_file" | head -50) + local replace_default_file=$(grep -A 2 "cat /etc/openssl/replace-default-enabled" "$output_file" | grep -E "^[01]$" | head -1 || echo "") + + if [ "$expected_replace_default" = "true" ]; then + if echo "$provider_output" | grep -qi "libwolfprov"; then + echo "✗ ERROR: libwolfprov found (indicates standalone mode, not replace-default)" + eval "$errors_var=\$((\$$errors_var + 1))" + return 1 + elif echo "$provider_output" | grep -q "default" && echo "$provider_output" | grep -A 5 "default" | grep -qi "wolfSSL Provider"; then + echo "✓ Default provider is wolfProvider (replace-default mode confirmed)" + if [ "$replace_default_file" = "0" ]; then + echo " ⚠ WARNING: Config file says standalone (0) but runtime shows replace-default mode" + elif [ -z "$replace_default_file" ]; then + echo " ⚠ WARNING: Config file not found (runtime detection takes precedence)" + fi + return 0 + else + echo "✗ ERROR: Default provider is not wolfSSL Provider (expected in replace-default mode)" + echo " Provider output snippet:" + echo "$provider_output" | head -30 + eval "$errors_var=\$((\$$errors_var + 1))" + return 1 + fi + else + if echo "$provider_output" | grep -qi "libwolfprov"; then + echo "✓ libwolfprov found (standalone mode confirmed)" + return 0 + elif echo "$provider_output" | grep -qi "wolfSSL Provider"; then + echo "✓ wolfProvider found in provider output (standalone mode)" + return 0 + else + echo "✗ ERROR: wolfProvider not found in provider output (expected in standalone mode)" + echo " Provider output:" + echo "$provider_output" | head -40 + eval "$errors_var=\$((\$$errors_var + 1))" + return 1 + fi + fi +} + +# Verify provider loaded successfully (replace-default vs standalone) +verify_provider_loaded() { + local output_file="$1" + local expected_replace_default="$2" + local errors_var="$3" + + if [ "$expected_replace_default" = "true" ]; then + echo "✓ Provider is the default provider (replace-default mode)" + return 0 + else + if grep -q "Custom provider 'libwolfprov' loaded successfully" "$output_file"; then + echo "✓ Provider loaded successfully" + return 0 + else + echo "✗ ERROR: Provider load success message not found (expected in standalone mode)" + eval "$errors_var=\$((\$$errors_var + 1))" + return 1 + fi + fi +} + +# Verify wolfProvider test results (wolfproviderenv, wolfprovidercmd, wolfprovidertest) +# Usage: verify_test_results +verify_test_results() { + local output_file="$1" + local errors_var="$2" + local test_name="$3" + + local env_status="999" + local cmd_status="999" + local test_status="999" + local tests_passed=0 + local test_failed=0 + + # Extract exit codes from output + # Look for patterns like "wolfproviderenv" followed by exit code or success indicators + if grep -q "=== Running wolfproviderenv ===" "$output_file"; then + # Check if wolfproviderenv completed successfully + if grep -A 50 "=== Running wolfproviderenv ===" "$output_file" | grep -q "Environment setup completed\|Passed!"; then + env_status="0" + elif grep -A 50 "=== Running wolfproviderenv ===" "$output_file" | grep -qi "error\|failed"; then + env_status="1" + fi + fi + + if grep -q "=== Running wolfprovidercmd ===" "$output_file"; then + # Check if wolfprovidercmd completed successfully + if grep -A 50 "=== Running wolfprovidercmd ===" "$output_file" | grep -q "PASSED\|passed\|success"; then + cmd_status="0" + elif grep -A 50 "=== Running wolfprovidercmd ===" "$output_file" | grep -qi "error\|failed\|FAILED"; then + cmd_status="1" + fi + fi + + if grep -q "=== Running wolfprovidertest ===" "$output_file"; then + # Check if wolfprovidertest completed successfully + if grep -A 50 "=== Running wolfprovidertest ===" "$output_file" | grep -q "PASSED\|passed\|success\|All tests passed"; then + test_status="0" + elif grep -A 50 "=== Running wolfprovidertest ===" "$output_file" | grep -qi "error\|failed\|FAILED"; then + test_status="1" + fi + fi + + echo "" + echo "==========================================" + echo "Reviewing Test Results" + echo "==========================================" + echo "" + + # Check wolfproviderenv + if [ "$env_status" -eq "0" ]; then + echo " ✓ wolfproviderenv: PASSED" + tests_passed=$((tests_passed + 1)) + elif [ "$env_status" -eq "999" ]; then + echo " ✗ wolfproviderenv: NOT FOUND (script may not have run)" + test_failed=1 + else + echo " ✗ wolfproviderenv: FAILED" + test_failed=1 + fi + + # Check wolfprovidercmd + if [ "$cmd_status" -eq "0" ]; then + echo " ✓ wolfprovidercmd: PASSED" + tests_passed=$((tests_passed + 1)) + elif [ "$cmd_status" -eq "999" ]; then + echo " ✗ wolfprovidercmd: NOT FOUND (script may not have run)" + test_failed=1 + else + echo " ✗ wolfprovidercmd: FAILED" + test_failed=1 + fi + + # Check wolfprovidertest + if [ "$test_status" -eq "0" ]; then + echo " ✓ wolfprovidertest: PASSED" + tests_passed=$((tests_passed + 1)) + elif [ "$test_status" -eq "999" ]; then + echo " ✗ wolfprovidertest: NOT FOUND (script may not have run)" + test_failed=1 + else + echo " ✗ wolfprovidertest: FAILED" + test_failed=1 + fi + + echo "" + echo "==========================================" + echo "Final Results: ${tests_passed}/3 tests passed" + echo "==========================================" + echo "" + + if [ $test_failed -eq 1 ]; then + echo "✗ Some tests FAILED" + echo "" + echo "Log file (last 50 lines):" + tail -50 "$output_file" + eval "$errors_var=\$((\$$errors_var + 1))" + return 1 + else + echo "✓ All tests PASSED!" + return 0 + fi +} + +# Verify curl ptest results (uses TESTDONE format) +# Usage: verify_ptest_curl +verify_ptest_curl() { + local output_file="$1" + local errors_var="$2" + local test_name="$3" + + echo "" + echo "==========================================" + echo "Verifying ${test_name} Ptest Results" + echo "==========================================" + echo "" + + # Check for success indicators + local test_done_found=0 + local all_passed=0 + + # Look for "TESTDONE: X tests out of X reported OK: 100%" + if grep -q "TESTDONE:" "$output_file"; then + test_done_found=1 + # Check if all tests passed (100%) + if grep -q "TESTDONE:.*reported OK: 100%" "$output_file"; then + all_passed=1 + fi + fi + + if [ $test_done_found -eq 1 ]; then + if [ $all_passed -eq 1 ]; then + local test_count=$(grep "TESTDONE:" "$output_file" | grep -oE "[0-9]+ tests" | head -1 | grep -oE "[0-9]+") + echo "✓ ${test_name} ptest completed successfully" + echo " Tests passed: 100% ($test_count tests)" + return 0 + else + echo "✗ ERROR: ${test_name} ptest did not achieve 100% pass rate" + grep "TESTDONE:" "$output_file" | head -5 + eval "$errors_var=\$((\$$errors_var + 1))" + return 1 + fi + else + echo "✗ ERROR: ${test_name} ptest TESTDONE message not found" + echo " This may indicate the ptest did not complete" + eval "$errors_var=\$((\$$errors_var + 1))" + return 1 + fi +} + +# Generic ptest verification function (checks for FAIL: lines) +# Usage: verify_ptest_generic +verify_ptest_generic() { + local output_file="$1" + local errors_var="$2" + local test_name="$3" + + echo "" + echo "==========================================" + echo "Verifying ${test_name} Ptest Results" + echo "==========================================" + echo "" + + # Extract the FAIL count from summary line (e.g., "# FAIL: 0") + local fail_count=$(grep -E "^[[:space:]]*# FAIL:[[:space:]]*[0-9]+" "$output_file" 2>/dev/null | grep -oE "[0-9]+" | head -1 || echo "") + + # Also check for non-summary FAIL lines (actual test failures, not starting with #) + local test_failures=$(grep "FAIL:" "$output_file" 2>/dev/null | grep -vE "^[[:space:]]*#" || true) + + # Fail only if there are actual test failures OR if fail_count is a number > 0 + if [ -n "$test_failures" ] || { [ -n "$fail_count" ] && [ "$fail_count" -gt 0 ]; }; then + echo "✗ ERROR: ${test_name} ptest had failures" + if [ -n "$test_failures" ]; then + echo "$test_failures" | head -5 + fi + if [ -n "$fail_count" ] && [ "$fail_count" -gt 0 ]; then + echo " Summary: # FAIL: $fail_count" + fi + eval "$errors_var=\$((\$$errors_var + 1))" + return 1 + fi + + echo "✓ ${test_name} ptest completed successfully" + return 0 +} + + +######################################################## +# Wrapper verification functions +######################################################## + + +# Verify wolfProvider environment configuration +# Usage: yocto_env_verify +yocto_env_verify() { + local output_file="$1" + local expected_openssl_version="$2" + local expected_wolfssl_version="$3" + local expected_replace_default="$4" + local expected_fips="$5" + + if [ $# -ne 5 ]; then + echo "ERROR: Invalid arguments" + echo "Usage: yocto_env_verify " + return 1 + fi + + if [ ! -f "$output_file" ]; then + echo "ERROR: Output file not found: $output_file" + return 1 + fi + + echo "==========================================" + echo "Verifying wolfproviderenv Configuration" + echo "==========================================" + echo "Expected OpenSSL: $expected_openssl_version" + echo "Expected wolfSSL: $expected_wolfssl_version" + echo "Expected Replace-Default: $expected_replace_default" + echo "Expected FIPS: $expected_fips" + echo "" + + local ERRORS=0 + + # Use common verification functions + verify_openssl_version "$output_file" "$expected_openssl_version" "ERRORS" + verify_wolfssl_version "$output_file" "$expected_wolfssl_version" "ERRORS" + verify_fips_mode "$output_file" "$expected_fips" "ERRORS" + verify_provider_loaded "$output_file" "$expected_replace_default" "ERRORS" + verify_provider_mode "$output_file" "$expected_replace_default" "ERRORS" + + # Verify test passed + if grep -q "Passed!" "$output_file"; then + echo "✓ Test 1 passed" + else + echo "✗ ERROR: Test 1 'Passed!' message not found" + ERRORS=$((ERRORS + 1)) + fi + + # Verify environment setup completed + if grep -q "Environment setup completed" "$output_file"; then + echo "✓ Environment setup completed" + else + echo "✗ ERROR: Environment setup completion message not found" + ERRORS=$((ERRORS + 1)) + fi + + echo "" + echo "==========================================" + if [ $ERRORS -eq 0 ]; then + echo "✓ All verifications PASSED" + echo "==========================================" + return 0 + else + echo "✗ $ERRORS verification(s) FAILED" + echo "==========================================" + return 1 + fi +} + +# Verify wolfProvider test and Ptests results +# Usage: yocto_test_verify +yocto_test_verify() { + local test_name="$1" + local output_file="$2" + + if [ $# -ne 2 ]; then + echo "ERROR: Invalid arguments" + echo "Usage: yocto_test_verify " + return 1 + fi + + if [ ! -f "$output_file" ]; then + echo "ERROR: Output file not found: $output_file" + return 1 + fi + + local ERRORS=0 + + # Verify test results + if [ "$test_name" = "wolfProvider" ]; then + verify_test_results "$output_file" "ERRORS" "$test_name" + elif ["$test_name" = "curl"]; then + verify_ptest_curl "$output_file" "ERRORS" "$test_name" + else + verify_ptest_generic "$output_file" "ERRORS" "$test_name" + fi + + echo "" + echo "==========================================" + if [ $ERRORS -eq 0 ]; then + echo "✓ ${test_name} test verifications PASSED" + echo "==========================================" + return 0 + else + echo "✗ ${test_name} test verifications FAILED" + echo " ${ERRORS} verification(s) failed" + echo "==========================================" + return 1 + fi +} diff --git a/.github/workflows/build-wolfprovider.yml b/.github/workflows/build-wolfprovider.yml index 319c4927..c799b121 100644 --- a/.github/workflows/build-wolfprovider.yml +++ b/.github/workflows/build-wolfprovider.yml @@ -16,6 +16,10 @@ on: required: false type: boolean default: false + build_type: + required: false + type: string + default: debian jobs: build_wolfprovider_common: @@ -42,20 +46,46 @@ jobs: OPENSSL_PACKAGES_PATH: /tmp/openssl-packages WOLFPROV_PACKAGES_PATH: /tmp/wolfprov-packages DEBS_PATH: debs + WICS_PATH: wics + YOCTO_IMAGES_PATH: /tmp/yocto-images steps: # Check if artifact already exists from another job in the same workflow run # When multiple matrix jobs run in parallel, the first one to finish uploads the artifact # Other jobs can then find it and skip rebuilding (no need to download it, just check it exists) + - name: Prepare artifact name for check + id: prepare_artifact_name + run: | + if [ "${{ inputs.build_type }}" = "yocto" ]; then + # For Yocto, create unique name based on matrix values + if [ "${{ inputs.fips_ref }}" = "FIPS" ]; then + FIPS_STR="fips" + else + FIPS_STR="nonfips" + fi + + if [ "${{ inputs.replace_default }}" = "true" ]; then + REPLACE_DEFAULT_STR="replace-default" + else + REPLACE_DEFAULT_STR="standalone" + fi + + ARTIFACT_NAME="yocto-image-${FIPS_STR}-${REPLACE_DEFAULT_STR}" + else + # For Debian, use existing format + ARTIFACT_NAME="debian-packages-${{ inputs.fips_ref }}${{ inputs.replace_default && '-replace-default' || '' }}-${{ inputs.wolfssl_ref }}-${{ inputs.openssl_ref }}" + fi + echo "artifact_name=${ARTIFACT_NAME}" >> $GITHUB_OUTPUT + - name: Check for existing artifact from same run id: check_artifact continue-on-error: true uses: actions/download-artifact@v4 with: - name: debian-packages-${{ inputs.fips_ref }}${{ inputs.replace_default && '-replace-default' || '' }}-${{ inputs.wolfssl_ref }}-${{ inputs.openssl_ref }} + name: ${{ steps.prepare_artifact_name.outputs.artifact_name }} - # Download pre-built packages from debs branch + # Download pre-built packages from debs branch (for Debian builds) - name: Checkout debs branch - if: steps.check_artifact.outcome != 'success' + if: steps.check_artifact.outcome != 'success' && inputs.build_type == 'debian' uses: actions/checkout@v4 with: repository: wolfSSL/wolfProvider @@ -67,8 +97,146 @@ jobs: sparse-checkout-cone-mode: false path: ${{ env.DEBS_PATH }} + # Download pre-built WIC images from wics branch (for Yocto builds) + # Files may be split into parts (>100MB) to comply with GitHub's file size limits + - name: Install xz-utils + if: steps.check_artifact.outcome != 'success' && inputs.build_type == 'yocto' + run: | + apt-get update + apt-get install -y xz-utils + + - name: Checkout wics branch + if: steps.check_artifact.outcome != 'success' && inputs.build_type == 'yocto' + uses: actions/checkout@v4 + with: + repository: wolfSSL/wolfProvider + ref: wics + sparse-checkout: | + fips + nonfips + sparse-checkout-cone-mode: false + path: ${{ env.WICS_PATH }} + + - name: Setup WIC images from wics branch + if: steps.check_artifact.outcome != 'success' && inputs.build_type == 'yocto' + run: | + mkdir -p ${{ env.YOCTO_IMAGES_PATH }} + + echo "Available directories in wics branch:" + ls -la ${{ env.WICS_PATH }}/ + + # Determine which WIC file to download based on matrix values + # Each matrix job downloads ONLY its specific WIC file + if [ "${{ inputs.fips_ref }}" = "FIPS" ]; then + FIPS_DIR="fips" + else + FIPS_DIR="nonfips" + fi + + # Directory uses hyphen, not underscore + if [ "${{ inputs.replace_default }}" = "true" ]; then + CONFIG_DIR="replace-default" + else + CONFIG_DIR="standalone" + fi + + echo "Looking for WIC file in: $FIPS_DIR/$CONFIG_DIR" + + # Files are in nested directories: fips/replace-default/, fips/standalone/, etc. + nested_path="${{ env.WICS_PATH }}/$FIPS_DIR/$CONFIG_DIR" + if [ -d "$nested_path" ]; then + echo "Found nested directory: $nested_path" + echo "Contents:" + ls -lah "$nested_path" + + cd "$nested_path" + + # Check for split files (.wic.xz.part-*) or single file + PART_FILES=$(find . -name "*.wic.xz.part-*" -type f | sort) + SINGLE_FILE=$(find . -name "*.wic.xz" -type f ! -name "*.wic.xz.part-*" | head -1) + + if [ -n "$PART_FILES" ]; then + echo "Found split WIC files, reassembling..." + + # Determine the base filename from the first part file + FIRST_PART=$(echo "$PART_FILES" | head -1) + BASE_NAME=$(basename "$FIRST_PART" | sed 's/\.part-[0-9]*$//') + + echo "Base filename: $BASE_NAME" + echo "Part files found:" + echo "$PART_FILES" + + # Reassemble split files by concatenating parts in order + # The glob pattern *.wic.xz.part-* will expand in sorted order + echo "Reassembling split files by concatenating parts in order..." + cat *.wic.xz.part-* > "$BASE_NAME" + echo "Reassembly complete" + + # Verify the reassembled file exists + if [ ! -f "$BASE_NAME" ]; then + echo "ERROR: Failed to reassemble $BASE_NAME" + exit 1 + fi + + # Copy the reassembled file to output directory + cp "$BASE_NAME" ${{ env.YOCTO_IMAGES_PATH }}/ + echo "Copied reassembled file: $BASE_NAME" + + elif [ -n "$SINGLE_FILE" ]; then + echo "Found single WIC file: $SINGLE_FILE" + cp "$SINGLE_FILE" ${{ env.YOCTO_IMAGES_PATH }}/ + echo "Copied single file: $SINGLE_FILE" + else + echo "ERROR: No WIC files found (neither split parts nor single file)" + echo "Searched for:" + echo " - Split files: *.wic.xz.part-*" + echo " - Single file: *.wic.xz" + exit 1 + fi + + # Decompress .wic.xz files to .wic files + cd ${{ env.YOCTO_IMAGES_PATH }} + if ls *.wic.xz 1> /dev/null 2>&1; then + echo "Decompressing .wic.xz files..." + for xz_file in *.wic.xz; do + echo "Decompressing: $xz_file" + unxz -v "$xz_file" + echo "Decompressed to: ${xz_file%.xz}" + done + else + echo "ERROR: No .wic.xz files found to decompress" + exit 1 + fi + + echo "Copied and decompressed WIC file(s) for matrix: fips_ref=${{ inputs.fips_ref }}, replace_default=${{ inputs.replace_default }}" + else + echo "ERROR: Directory not found: $nested_path" + echo "Available directories in $FIPS_DIR:" + ls -la "${{ env.WICS_PATH }}/$FIPS_DIR/" || true + exit 1 + fi + + # Verify we found the decompressed WIC file + WIC_COUNT=$(find ${{ env.YOCTO_IMAGES_PATH }} -name "*.wic" -type f ! -name "*.wic.xz" | wc -l) + if [ "$WIC_COUNT" -eq 0 ]; then + echo "ERROR: No decompressed WIC image found for $FIPS_DIR/$CONFIG_DIR" + echo "Searched in:" + ls -laR ${{ env.WICS_PATH }}/$FIPS_DIR/ || echo "Directory $FIPS_DIR not found" + echo "Files in YOCTO_IMAGES_PATH:" + ls -la ${{ env.YOCTO_IMAGES_PATH }} || true + exit 1 + fi + + if [ "$WIC_COUNT" -gt 1 ]; then + echo "WARNING: Found multiple WIC files ($WIC_COUNT), expected 1" + fi + + echo "" + echo "WIC image ready for use ($WIC_COUNT decompressed file(s)):" + ls -lah ${{ env.YOCTO_IMAGES_PATH }} + - name: Setup packages from debs branch - if: steps.check_artifact.outcome != 'success' + if: steps.check_artifact.outcome != 'success' && inputs.build_type == 'debian' run: | mkdir -p ${{ env.WOLFSSL_PACKAGES_PATH }} mkdir -p ${{ env.OPENSSL_PACKAGES_PATH }} @@ -120,7 +288,7 @@ jobs: ls -la ${{ env.OPENSSL_PACKAGES_PATH }} - name: Install OpenSSL and wolfSSL packages - if: steps.check_artifact.outcome != 'success' + if: steps.check_artifact.outcome != 'success' && inputs.build_type == 'debian' run: | echo "Installing OpenSSL and wolfSSL packages (${{ inputs.fips_ref }})..." @@ -147,7 +315,7 @@ jobs: dpkg -l | grep wolfssl || echo " No wolfSSL packages found" - name: Checkout wolfProvider - if: steps.check_artifact.outcome != 'success' + if: steps.check_artifact.outcome != 'success' && inputs.build_type == 'debian' uses: actions/checkout@v4 with: fetch-depth: 1 @@ -155,24 +323,24 @@ jobs: # Avoid "detected dubious ownership" warning - name: Ensure the working directory safe - if: steps.check_artifact.outcome != 'success' + if: steps.check_artifact.outcome != 'success' && inputs.build_type == 'debian' run: | git config --global --add safe.directory "$GITHUB_WORKSPACE" # When running on a fork the upstream tags are not present, so fetch them explicitly - name: Fetch tags from upstream(for Debian versioning) - if: steps.check_artifact.outcome != 'success' + if: steps.check_artifact.outcome != 'success' && inputs.build_type == 'debian' run: | git remote add upstream https://github.com/wolfSSL/wolfProvider.git || true git fetch upstream --tags --no-recurse-submodules - name: Install wolfProvider - if: steps.check_artifact.outcome != 'success' + if: steps.check_artifact.outcome != 'success' && inputs.build_type == 'debian' run: | $GITHUB_WORKSPACE/debian/install-wolfprov.sh ${{ inputs.fips_ref == 'FIPS' && '--fips' || '' }} ${{ env.WOLFPROV_PACKAGES_PATH }} - name: Setup packages directory - if: steps.check_artifact.outcome != 'success' + if: steps.check_artifact.outcome != 'success' && inputs.build_type == 'debian' run: | mkdir -p ${{ env.WOLFPROV_PACKAGES_PATH }} @@ -193,10 +361,10 @@ jobs: echo "OpenSSL packages:" ls -la ${{ env.OPENSSL_PACKAGES_PATH }} - # Save all packages as artifacts for consumers + # Save all packages as artifacts for consumers (Debian) # Skip upload if artifact already exists (from a parallel run) - name: Upload wolfProvider packages - if: steps.check_artifact.outcome != 'success' + if: steps.check_artifact.outcome != 'success' && inputs.build_type == 'debian' uses: actions/upload-artifact@v4 with: name: debian-packages-${{ inputs.fips_ref }}${{ inputs.replace_default && '-replace-default' || '' }}-${{ inputs.wolfssl_ref }}-${{ inputs.openssl_ref }} @@ -205,3 +373,14 @@ jobs: ${{ env.OPENSSL_PACKAGES_PATH }} ${{ env.WOLFPROV_PACKAGES_PATH }} retention-days: 1 + + # Save WIC images as artifacts + # Each matrix job uploads its unique WIC file with a unique artifact name + - name: Upload Yocto WIC images + if: steps.check_artifact.outcome != 'success' && inputs.build_type == 'yocto' + uses: actions/upload-artifact@v4 + with: + name: yocto-image-${{ inputs.fips_ref == 'FIPS' && 'fips' || 'nonfips' }}-${{ inputs.replace_default && 'replace-default' || 'standalone' }} + path: | + ${{ env.YOCTO_IMAGES_PATH }} + retention-days: 1 diff --git a/.github/workflows/yocto-curl.yml b/.github/workflows/yocto-curl.yml new file mode 100644 index 00000000..fc1fc766 --- /dev/null +++ b/.github/workflows/yocto-curl.yml @@ -0,0 +1,123 @@ +name: Yocto Curl + +# START OF COMMON SECTION +on: + push: + branches: ['*'] + pull_request: + branches: ['*'] + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true +# END OF COMMON SECTION + +jobs: + build_wolfprovider: + uses: ./.github/workflows/build-wolfprovider.yml + with: + wolfssl_ref: ${{ matrix.wolfssl_ref }} + openssl_ref: ${{ matrix.openssl_ref }} + fips_ref: ${{ matrix.fips_ref }} + replace_default: ${{ matrix.replace_default }} + build_type: 'yocto' + strategy: + matrix: + wolfssl_ref: [ 'v5.8.4-stable' ] + openssl_ref: [ 'openssl-3.2.6' ] + fips_ref: [ 'FIPS', 'non-FIPS' ] + replace_default: [ true, false ] + + verify_yocto_env: + needs: build_wolfprovider + uses: ./.github/workflows/yocto-verify.yml + with: + wolfssl_ref: ${{ matrix.wolfssl_ref }} + openssl_ref: ${{ matrix.openssl_ref }} + fips_ref: ${{ matrix.fips_ref }} + replace_default: ${{ matrix.replace_default }} + strategy: + fail-fast: false + matrix: + wolfssl_ref: [ 'v5.8.4-stable' ] + openssl_ref: [ 'openssl-3.2.6' ] + fips_ref: [ 'FIPS', 'non-FIPS' ] + replace_default: [ true, false ] + + run_curl_ptest: + name: Run Curl Ptest - ${{ matrix.wolfssl_ref }}-${{ matrix.openssl_ref }}-${{ matrix.fips_ref }}-${{ matrix.replace_default }} + needs: [build_wolfprovider, verify_yocto_env] + strategy: + fail-fast: false + matrix: + wolfssl_ref: [ 'v5.8.4-stable' ] + openssl_ref: [ 'openssl-3.2.6' ] + fips_ref: [ 'FIPS', 'non-FIPS' ] + replace_default: [ true, false ] + runs-on: ubuntu-latest + container: + image: ghcr.io/crops/poky:ubuntu-22.04 + options: --user root + timeout-minutes: 60 + + steps: + - name: Checkout wolfProvider + uses: actions/checkout@v4 + + - name: Download WIC images + uses: actions/download-artifact@v4 + with: + name: yocto-image-${{ matrix.fips_ref == 'FIPS' && 'fips' || 'nonfips' }}-${{ matrix.replace_default && 'replace-default' || 'standalone' }} + path: /tmp/yocto-images + + - name: Install QEMU, expect, and xz-utils + run: | + apt-get update + apt-get install -y qemu-system-x86 expect xz-utils + + - name: Setup WIC image + run: | + cd /tmp/yocto-images + if ls *.wic.xz 1> /dev/null 2>&1; then + unxz -v *.wic.xz || true + fi + WIC_FILE=$(ls *.wic 2>/dev/null | grep -v "\.wic\." | head -1) + if [ -z "$WIC_FILE" ] || [ ! -f "$WIC_FILE" ]; then + echo "ERROR: No decompressed WIC file found" + exit 1 + fi + echo "WIC_PATH=/tmp/yocto-images/$WIC_FILE" >> $GITHUB_ENV + + - name: Run curl ptest + timeout-minutes: 60 + run: | + echo "=== Running curl ptest for ${{ matrix.fips_ref }}-${{ matrix.replace_default }} ===" + OUTPUT_FILE="/tmp/curl-ptest-output-${{ matrix.fips_ref }}-${{ matrix.replace_default }}.txt" + + export EXPECT_TIMEOUT=3600 # 1 hour + $GITHUB_WORKSPACE/.github/scripts/boot-qemu.sh \ + "$WIC_PATH" \ + "echo 'setting up environment'" \ + "wolfproviderenv" \ + "echo '=== Running curl ptest ==='" \ + "cd /usr/lib/curl/ptest && ./run-ptest" > "$OUTPUT_FILE" 2>&1 || true + + echo "=== Curl ptest output ===" + cat "$OUTPUT_FILE" + echo "" + + # Verify ptest results + echo "=== Verifying curl ptest results ===" + source $GITHUB_WORKSPACE/.github/scripts/yocto-verify-common.sh + yocto_test_verify "curl" "$OUTPUT_FILE" || exit 1 + + - name: Upload ptest logs + if: always() + uses: actions/upload-artifact@v4 + with: + name: curl-ptest-logs-${{ matrix.wolfssl_ref }}-${{ matrix.openssl_ref }}-${{ matrix.fips_ref == 'FIPS' && 'fips' || 'nonfips' }}-${{ matrix.replace_default && 'replace-default' || 'standalone' }} + path: | + /tmp/curl-ptest-output-*.txt + retention-days: 7 + if-no-files-found: ignore diff --git a/.github/workflows/yocto-librelp.yml b/.github/workflows/yocto-librelp.yml new file mode 100644 index 00000000..52bee830 --- /dev/null +++ b/.github/workflows/yocto-librelp.yml @@ -0,0 +1,123 @@ +name: Yocto Librelp + +# START OF COMMON SECTION +on: + push: + branches: ['*'] + pull_request: + branches: ['*'] + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true +# END OF COMMON SECTION + +jobs: + build_wolfprovider: + uses: ./.github/workflows/build-wolfprovider.yml + with: + wolfssl_ref: ${{ matrix.wolfssl_ref }} + openssl_ref: ${{ matrix.openssl_ref }} + fips_ref: ${{ matrix.fips_ref }} + replace_default: ${{ matrix.replace_default }} + build_type: 'yocto' + strategy: + matrix: + wolfssl_ref: [ 'v5.8.4-stable' ] + openssl_ref: [ 'openssl-3.2.6' ] + fips_ref: [ 'FIPS' ] + replace_default: [ true, false ] + + verify_yocto_env: + needs: build_wolfprovider + uses: ./.github/workflows/yocto-verify.yml + with: + wolfssl_ref: ${{ matrix.wolfssl_ref }} + openssl_ref: ${{ matrix.openssl_ref }} + fips_ref: ${{ matrix.fips_ref }} + replace_default: ${{ matrix.replace_default }} + strategy: + fail-fast: false + matrix: + wolfssl_ref: [ 'v5.8.4-stable' ] + openssl_ref: [ 'openssl-3.2.6' ] + fips_ref: [ 'FIPS' ] + replace_default: [ true, false ] + + run_librelp_ptest: + name: Run Librelp Ptest - ${{ matrix.wolfssl_ref }}-${{ matrix.openssl_ref }}-${{ matrix.fips_ref }}-${{ matrix.replace_default }} + needs: [build_wolfprovider, verify_yocto_env] + strategy: + fail-fast: false + matrix: + wolfssl_ref: [ 'v5.8.4-stable' ] + openssl_ref: [ 'openssl-3.2.6' ] + fips_ref: [ 'FIPS' ] + replace_default: [ true, false ] + runs-on: ubuntu-latest + container: + image: ghcr.io/crops/poky:ubuntu-22.04 + options: --user root + timeout-minutes: 60 + + steps: + - name: Checkout wolfProvider + uses: actions/checkout@v4 + + - name: Download WIC images + uses: actions/download-artifact@v4 + with: + name: yocto-image-${{ matrix.fips_ref == 'FIPS' && 'fips' || 'nonfips' }}-${{ matrix.replace_default && 'replace-default' || 'standalone' }} + path: /tmp/yocto-images + + - name: Install QEMU, expect, and xz-utils + run: | + apt-get update + apt-get install -y qemu-system-x86 expect xz-utils + + - name: Setup WIC image + run: | + cd /tmp/yocto-images + if ls *.wic.xz 1> /dev/null 2>&1; then + unxz -v *.wic.xz || true + fi + WIC_FILE=$(ls *.wic 2>/dev/null | grep -v "\.wic\." | head -1) + if [ -z "$WIC_FILE" ] || [ ! -f "$WIC_FILE" ]; then + echo "ERROR: No decompressed WIC file found" + exit 1 + fi + echo "WIC_PATH=/tmp/yocto-images/$WIC_FILE" >> $GITHUB_ENV + + - name: Run librelp ptest + timeout-minutes: 60 + run: | + echo "=== Running librelp ptest for ${{ matrix.fips_ref }}-${{ matrix.replace_default }} ===" + OUTPUT_FILE="/tmp/librelp-ptest-output-${{ matrix.fips_ref }}-${{ matrix.replace_default }}.txt" + + export EXPECT_TIMEOUT=3600 # 1 hour + $GITHUB_WORKSPACE/.github/scripts/boot-qemu.sh \ + "$WIC_PATH" \ + "echo 'setting up environment'" \ + "wolfproviderenv" \ + "echo '=== Running librelp ptest ==='" \ + "cd /usr/lib/librelp/ptest && ./run-ptest" > "$OUTPUT_FILE" 2>&1 || true + + echo "=== Librelp ptest output ===" + cat "$OUTPUT_FILE" + echo "" + + # Verify ptest results + echo "=== Verifying librelp ptest results ===" + source $GITHUB_WORKSPACE/.github/scripts/yocto-verify-common.sh + yocto_test_verify "Librelp" "$OUTPUT_FILE" || exit 1 + + - name: Upload ptest logs + if: always() + uses: actions/upload-artifact@v4 + with: + name: librelp-ptest-logs-${{ matrix.wolfssl_ref }}-${{ matrix.openssl_ref }}-${{ matrix.fips_ref == 'FIPS' && 'fips' || 'nonfips' }}-${{ matrix.replace_default && 'replace-default' || 'standalone' }} + path: | + /tmp/librelp-ptest-output-*.txt + retention-days: 7 + if-no-files-found: ignore diff --git a/.github/workflows/yocto-openssh.yml b/.github/workflows/yocto-openssh.yml new file mode 100644 index 00000000..54c48475 --- /dev/null +++ b/.github/workflows/yocto-openssh.yml @@ -0,0 +1,120 @@ +name: Yocto OpenSSH + +# START OF COMMON SECTION +on: + workflow_dispatch: + schedule: + - cron: '0 8 * * *' # Daily at 8:00 AM UTC + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true +# END OF COMMON SECTION + +jobs: + build_wolfprovider: + uses: ./.github/workflows/build-wolfprovider.yml + with: + wolfssl_ref: ${{ matrix.wolfssl_ref }} + openssl_ref: ${{ matrix.openssl_ref }} + fips_ref: ${{ matrix.fips_ref }} + replace_default: ${{ matrix.replace_default }} + build_type: 'yocto' + strategy: + matrix: + wolfssl_ref: [ 'v5.8.4-stable' ] + openssl_ref: [ 'openssl-3.2.6' ] + fips_ref: [ 'FIPS', 'non-FIPS' ] + replace_default: [ true, false ] + + verify_yocto_env: + needs: build_wolfprovider + uses: ./.github/workflows/yocto-verify.yml + with: + wolfssl_ref: ${{ matrix.wolfssl_ref }} + openssl_ref: ${{ matrix.openssl_ref }} + fips_ref: ${{ matrix.fips_ref }} + replace_default: ${{ matrix.replace_default }} + strategy: + fail-fast: false + matrix: + wolfssl_ref: [ 'v5.8.4-stable' ] + openssl_ref: [ 'openssl-3.2.6' ] + fips_ref: [ 'FIPS', 'non-FIPS' ] + replace_default: [ true, false ] + + run_openssh_ptest: + name: Run OpenSSH Ptest - ${{ matrix.wolfssl_ref }}-${{ matrix.openssl_ref }}-${{ matrix.fips_ref }}-${{ matrix.replace_default }} + needs: [build_wolfprovider, verify_yocto_env] + strategy: + fail-fast: false + matrix: + wolfssl_ref: [ 'v5.8.4-stable' ] + openssl_ref: [ 'openssl-3.2.6' ] + fips_ref: [ 'FIPS', 'non-FIPS' ] + replace_default: [ true, false ] + runs-on: ubuntu-latest + container: + image: ghcr.io/crops/poky:ubuntu-22.04 + options: --user root + timeout-minutes: 180 + + steps: + - name: Checkout wolfProvider + uses: actions/checkout@v4 + + - name: Download WIC images + uses: actions/download-artifact@v4 + with: + name: yocto-image-${{ matrix.fips_ref == 'FIPS' && 'fips' || 'nonfips' }}-${{ matrix.replace_default && 'replace-default' || 'standalone' }} + path: /tmp/yocto-images + + - name: Install QEMU, expect, and xz-utils + run: | + apt-get update + apt-get install -y qemu-system-x86 expect xz-utils + + - name: Setup WIC image + run: | + cd /tmp/yocto-images + if ls *.wic.xz 1> /dev/null 2>&1; then + unxz -v *.wic.xz || true + fi + WIC_FILE=$(ls *.wic 2>/dev/null | grep -v "\.wic\." | head -1) + if [ -z "$WIC_FILE" ] || [ ! -f "$WIC_FILE" ]; then + echo "ERROR: No decompressed WIC file found" + exit 1 + fi + echo "WIC_PATH=/tmp/yocto-images/$WIC_FILE" >> $GITHUB_ENV + + - name: Run openssh ptest + timeout-minutes: 180 + run: | + echo "=== Running openssh ptest for ${{ matrix.fips_ref }}-${{ matrix.replace_default }} ===" + OUTPUT_FILE="/tmp/openssh-ptest-output-${{ matrix.fips_ref }}-${{ matrix.replace_default }}.txt" + + $GITHUB_WORKSPACE/.github/scripts/boot-qemu.sh \ + "$WIC_PATH" \ + "echo 'setting up environment'" \ + "wolfproviderenv" \ + "echo '=== Running openssh ptest ==='" \ + "cd /usr/lib/openssh/ptest && ./run-ptest" > "$OUTPUT_FILE" 2>&1 || true + + echo "=== OpenSSH ptest output ===" + cat "$OUTPUT_FILE" + echo "" + + # Verify ptest results + echo "=== Verifying openssh ptest results ===" + source $GITHUB_WORKSPACE/.github/scripts/yocto-verify-common.sh + yocto_test_verify "OpenSSH" "$OUTPUT_FILE" || exit 1 + + - name: Upload ptest logs + if: always() + uses: actions/upload-artifact@v4 + with: + name: openssh-ptest-logs-${{ matrix.wolfssl_ref }}-${{ matrix.openssl_ref }}-${{ matrix.fips_ref == 'FIPS' && 'fips' || 'nonfips' }}-${{ matrix.replace_default && 'replace-default' || 'standalone' }} + path: | + /tmp/openssh-ptest-output-*.txt + retention-days: 7 + if-no-files-found: ignore diff --git a/.github/workflows/yocto-openssl.yml b/.github/workflows/yocto-openssl.yml new file mode 100644 index 00000000..a080aae1 --- /dev/null +++ b/.github/workflows/yocto-openssl.yml @@ -0,0 +1,120 @@ +name: Yocto OpenSSL + +# START OF COMMON SECTION +on: + workflow_dispatch: + schedule: + - cron: '0 8 * * *' # Daily at 8:00 AM UTC + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true +# END OF COMMON SECTION + +jobs: + build_wolfprovider: + uses: ./.github/workflows/build-wolfprovider.yml + with: + wolfssl_ref: ${{ matrix.wolfssl_ref }} + openssl_ref: ${{ matrix.openssl_ref }} + fips_ref: ${{ matrix.fips_ref }} + replace_default: ${{ matrix.replace_default }} + build_type: 'yocto' + strategy: + matrix: + wolfssl_ref: [ 'v5.8.4-stable' ] + openssl_ref: [ 'openssl-3.2.6' ] + fips_ref: [ 'FIPS', 'non-FIPS' ] + replace_default: [ true, false ] + + verify_yocto_env: + needs: build_wolfprovider + uses: ./.github/workflows/yocto-verify.yml + with: + wolfssl_ref: ${{ matrix.wolfssl_ref }} + openssl_ref: ${{ matrix.openssl_ref }} + fips_ref: ${{ matrix.fips_ref }} + replace_default: ${{ matrix.replace_default }} + strategy: + fail-fast: false + matrix: + wolfssl_ref: [ 'v5.8.4-stable' ] + openssl_ref: [ 'openssl-3.2.6' ] + fips_ref: [ 'FIPS', 'non-FIPS' ] + replace_default: [ true, false ] + + run_openssl_ptest: + name: Run OpenSSL Ptest - ${{ matrix.wolfssl_ref }}-${{ matrix.openssl_ref }}-${{ matrix.fips_ref }}-${{ matrix.replace_default }} + needs: [build_wolfprovider, verify_yocto_env] + strategy: + fail-fast: false + matrix: + wolfssl_ref: [ 'v5.8.4-stable' ] + openssl_ref: [ 'openssl-3.2.6' ] + fips_ref: [ 'FIPS', 'non-FIPS' ] + replace_default: [ true, false ] + runs-on: ubuntu-latest + container: + image: ghcr.io/crops/poky:ubuntu-22.04 + options: --user root + timeout-minutes: 180 + + steps: + - name: Checkout wolfProvider + uses: actions/checkout@v4 + + - name: Download WIC images + uses: actions/download-artifact@v4 + with: + name: yocto-image-${{ matrix.fips_ref == 'FIPS' && 'fips' || 'nonfips' }}-${{ matrix.replace_default && 'replace-default' || 'standalone' }} + path: /tmp/yocto-images + + - name: Install QEMU, expect, and xz-utils + run: | + apt-get update + apt-get install -y qemu-system-x86 expect xz-utils + + - name: Setup WIC image + run: | + cd /tmp/yocto-images + if ls *.wic.xz 1> /dev/null 2>&1; then + unxz -v *.wic.xz || true + fi + WIC_FILE=$(ls *.wic 2>/dev/null | grep -v "\.wic\." | head -1) + if [ -z "$WIC_FILE" ] || [ ! -f "$WIC_FILE" ]; then + echo "ERROR: No decompressed WIC file found" + exit 1 + fi + echo "WIC_PATH=/tmp/yocto-images/$WIC_FILE" >> $GITHUB_ENV + + - name: Run openssl ptest + timeout-minutes: 180 + run: | + echo "=== Running openssl ptest for ${{ matrix.fips_ref }}-${{ matrix.replace_default }} ===" + OUTPUT_FILE="/tmp/openssl-ptest-output-${{ matrix.fips_ref }}-${{ matrix.replace_default }}.txt" + + $GITHUB_WORKSPACE/.github/scripts/boot-qemu.sh \ + "$WIC_PATH" \ + "echo 'setting up environment'" \ + "wolfproviderenv" \ + "echo '=== Running openssl ptest ==='" \ + "cd /usr/lib/openssl/ptest && ./run-ptest" > "$OUTPUT_FILE" 2>&1 || true + + echo "=== OpenSSL ptest output ===" + cat "$OUTPUT_FILE" + echo "" + + # Verify ptest results + echo "=== Verifying openssl ptest results ===" + source $GITHUB_WORKSPACE/.github/scripts/yocto-verify-common.sh + yocto_test_verify "OpenSSL" "$OUTPUT_FILE" || exit 1 + + - name: Upload ptest logs + if: always() + uses: actions/upload-artifact@v4 + with: + name: openssl-ptest-logs-${{ matrix.wolfssl_ref }}-${{ matrix.openssl_ref }}-${{ matrix.fips_ref == 'FIPS' && 'fips' || 'nonfips' }}-${{ matrix.replace_default && 'replace-default' || 'standalone' }} + path: | + /tmp/openssl-ptest-output-*.txt + retention-days: 7 + if-no-files-found: ignore diff --git a/.github/workflows/yocto-rsyslog.yml b/.github/workflows/yocto-rsyslog.yml new file mode 100644 index 00000000..cd880cdf --- /dev/null +++ b/.github/workflows/yocto-rsyslog.yml @@ -0,0 +1,120 @@ +name: Yocto Rsyslog + +# START OF COMMON SECTION +on: + workflow_dispatch: + schedule: + - cron: '0 8 * * *' # Daily at 8:00 AM UTC + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true +# END OF COMMON SECTION + +jobs: + build_wolfprovider: + uses: ./.github/workflows/build-wolfprovider.yml + with: + wolfssl_ref: ${{ matrix.wolfssl_ref }} + openssl_ref: ${{ matrix.openssl_ref }} + fips_ref: ${{ matrix.fips_ref }} + replace_default: ${{ matrix.replace_default }} + build_type: 'yocto' + strategy: + matrix: + wolfssl_ref: [ 'v5.8.4-stable' ] + openssl_ref: [ 'openssl-3.2.6' ] + fips_ref: [ 'FIPS', 'non-FIPS' ] + replace_default: [ true, false ] + + verify_yocto_env: + needs: build_wolfprovider + uses: ./.github/workflows/yocto-verify.yml + with: + wolfssl_ref: ${{ matrix.wolfssl_ref }} + openssl_ref: ${{ matrix.openssl_ref }} + fips_ref: ${{ matrix.fips_ref }} + replace_default: ${{ matrix.replace_default }} + strategy: + fail-fast: false + matrix: + wolfssl_ref: [ 'v5.8.4-stable' ] + openssl_ref: [ 'openssl-3.2.6' ] + fips_ref: [ 'FIPS', 'non-FIPS' ] + replace_default: [ true, false ] + + run_rsyslog_ptest: + name: Run Rsyslog Ptest - ${{ matrix.wolfssl_ref }}-${{ matrix.openssl_ref }}-${{ matrix.fips_ref }}-${{ matrix.replace_default }} + needs: [build_wolfprovider, verify_yocto_env] + strategy: + fail-fast: false + matrix: + wolfssl_ref: [ 'v5.8.4-stable' ] + openssl_ref: [ 'openssl-3.2.6' ] + fips_ref: [ 'FIPS', 'non-FIPS' ] + replace_default: [ true, false ] + runs-on: ubuntu-latest + container: + image: ghcr.io/crops/poky:ubuntu-22.04 + options: --user root + timeout-minutes: 120 + + steps: + - name: Checkout wolfProvider + uses: actions/checkout@v4 + + - name: Download WIC images + uses: actions/download-artifact@v4 + with: + name: yocto-image-${{ matrix.fips_ref == 'FIPS' && 'fips' || 'nonfips' }}-${{ matrix.replace_default && 'replace-default' || 'standalone' }} + path: /tmp/yocto-images + + - name: Install QEMU, expect, and xz-utils + run: | + apt-get update + apt-get install -y qemu-system-x86 expect xz-utils + + - name: Setup WIC image + run: | + cd /tmp/yocto-images + if ls *.wic.xz 1> /dev/null 2>&1; then + unxz -v *.wic.xz || true + fi + WIC_FILE=$(ls *.wic 2>/dev/null | grep -v "\.wic\." | head -1) + if [ -z "$WIC_FILE" ] || [ ! -f "$WIC_FILE" ]; then + echo "ERROR: No decompressed WIC file found" + exit 1 + fi + echo "WIC_PATH=/tmp/yocto-images/$WIC_FILE" >> $GITHUB_ENV + + - name: Run rsyslog ptest + timeout-minutes: 120 + run: | + echo "=== Running rsyslog ptest for ${{ matrix.fips_ref }}-${{ matrix.replace_default }} ===" + OUTPUT_FILE="/tmp/rsyslog-ptest-output-${{ matrix.fips_ref }}-${{ matrix.replace_default }}.txt" + + $GITHUB_WORKSPACE/.github/scripts/boot-qemu.sh \ + "$WIC_PATH" \ + "echo 'setting up environment'" \ + "wolfproviderenv" \ + "echo '=== Running rsyslog ptest ==='" \ + "cd /usr/lib/rsyslog/ptest && ./run-ptest" > "$OUTPUT_FILE" 2>&1 || true + + echo "=== Rsyslog ptest output ===" + cat "$OUTPUT_FILE" + echo "" + + # Verify ptest results + echo "=== Verifying rsyslog ptest results ===" + source $GITHUB_WORKSPACE/.github/scripts/yocto-verify-common.sh + yocto_test_verify "Rsyslog" "$OUTPUT_FILE" || exit 1 + + - name: Upload ptest logs + if: always() + uses: actions/upload-artifact@v4 + with: + name: rsyslog-ptest-logs-${{ matrix.wolfssl_ref }}-${{ matrix.openssl_ref }}-${{ matrix.fips_ref == 'FIPS' && 'fips' || 'nonfips' }}-${{ matrix.replace_default && 'replace-default' || 'standalone' }} + path: | + /tmp/rsyslog-ptest-output-*.txt + retention-days: 7 + if-no-files-found: ignore diff --git a/.github/workflows/yocto-test.yml b/.github/workflows/yocto-test.yml new file mode 100644 index 00000000..9137709d --- /dev/null +++ b/.github/workflows/yocto-test.yml @@ -0,0 +1,140 @@ +name: Yocto wolfProviderTests + +# START OF COMMON SECTION +on: + push: + branches: ['*'] + pull_request: + branches: ['*'] + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true +# END OF COMMON SECTION + +jobs: + build_wolfprovider: + uses: ./.github/workflows/build-wolfprovider.yml + with: + wolfssl_ref: ${{ matrix.wolfssl_ref }} + openssl_ref: ${{ matrix.openssl_ref }} + fips_ref: ${{ matrix.fips_ref }} + replace_default: ${{ matrix.replace_default }} + build_type: 'yocto' + strategy: + matrix: + wolfssl_ref: [ 'v5.8.4-stable' ] + openssl_ref: [ 'openssl-3.2.6' ] + fips_ref: [ 'FIPS', 'non-FIPS' ] + replace_default: [ true, false ] + + verify_yocto_env: + needs: build_wolfprovider + uses: ./.github/workflows/yocto-verify.yml + with: + wolfssl_ref: ${{ matrix.wolfssl_ref }} + openssl_ref: ${{ matrix.openssl_ref }} + fips_ref: ${{ matrix.fips_ref }} + replace_default: ${{ matrix.replace_default }} + strategy: + matrix: + wolfssl_ref: [ 'v5.8.4-stable' ] + openssl_ref: [ 'openssl-3.2.6' ] + fips_ref: [ 'FIPS', 'non-FIPS' ] + replace_default: [ true, false ] + + yocto_test: + name: Run wolfProvider tests - ${{ matrix.wolfssl_ref }}-${{ matrix.openssl_ref }}-${{ matrix.fips_ref }}-${{ matrix.replace_default }} + needs: [build_wolfprovider, verify_yocto_env] + strategy: + fail-fast: false + matrix: + wolfssl_ref: [ 'v5.8.4-stable' ] + openssl_ref: [ 'openssl-3.2.6' ] + fips_ref: [ 'FIPS', 'non-FIPS' ] + replace_default: [ true, false ] + runs-on: ubuntu-latest + container: + image: ghcr.io/crops/poky:ubuntu-22.04 + options: --user root + timeout-minutes: 60 + + steps: + - name: Checkout wolfProvider + uses: actions/checkout@v4 + + - name: Download Yocto image + uses: actions/download-artifact@v4 + with: + name: yocto-image-${{ matrix.fips_ref == 'FIPS' && 'fips' || 'nonfips' }}-${{ matrix.replace_default && 'replace-default' || 'standalone' }} + path: /tmp/yocto-image + + - name: Install QEMU, expect, and xz-utils + run: | + apt-get update + apt-get install -y qemu-system-x86 expect xz-utils + + - name: Setup Yocto image (reuse from verify workflow) + run: | + echo "=== Downloaded Yocto image ===" + ls -lah /tmp/yocto-image/ + cd /tmp/yocto-image + + # Extract if compressed + if ls *.wic.xz 1> /dev/null 2>&1; then + echo "Extracting xz-compressed Yocto image..." + unxz -v *.wic.xz || true + fi + + # Verify the WIC file is found + WIC_FILE=$(ls *.wic 2>/dev/null | grep -v "\.wic\." | head -1) + + if [ -z "$WIC_FILE" ] || [ ! -f "$WIC_FILE" ]; then + echo "ERROR: No decompressed WIC file found" + echo "Available files:" + ls -la /tmp/yocto-image/ + exit 1 + fi + + echo "Using WIC file: $WIC_FILE" + echo "Expected configuration: fips_ref=${{ matrix.fips_ref }}, replace_default=${{ matrix.replace_default }}" + echo "WIC_PATH=/tmp/yocto-image/$WIC_FILE" >> $GITHUB_ENV + + - name: Boot QEMU, run wolfProvider tests + timeout-minutes: 60 + run: | + # WIC image has been verified - now run wolfProvider tests + echo "=== Running wolfProvider tests for ${{ matrix.fips_ref }}-${{ matrix.replace_default }} ===" + echo "WIC file: $WIC_PATH" + + OUTPUT_FILE="/tmp/yocto-wolfprovider-tests-output-${{ matrix.fips_ref }}-${{ matrix.replace_default }}.txt" + + export EXPECT_TIMEOUT=3600 # 1 hour + $GITHUB_WORKSPACE/.github/scripts/boot-qemu.sh \ + "$WIC_PATH" \ + "echo '=== Running wolfproviderenv ==='" \ + "wolfproviderenv" \ + "echo '=== Running wolfprovidercmd ==='" \ + "wolfprovidercmd" \ + "echo '=== Running wolfprovidertest ==='" \ + "wolfprovidertest" > "$OUTPUT_FILE" 2>&1 || true + + # Display the output + echo "=== wolfProvider tests output ===" + cat "$OUTPUT_FILE" + echo "" + + echo "=== Verifying test results ===" + source $GITHUB_WORKSPACE/.github/scripts/yocto-verify-common.sh + yocto_test_verify "wolfProvider" "$OUTPUT_FILE" || exit 1 + + - name: Upload wolfProvider tests logs + if: always() + uses: actions/upload-artifact@v4 + with: + name: yocto-wolfprovider-tests-logs-${{ matrix.wolfssl_ref }}-${{ matrix.openssl_ref }}-${{ matrix.fips_ref == 'FIPS' && 'fips' || 'nonfips' }}-${{ matrix.replace_default && 'replace-default' || 'standalone' }} + path: | + /tmp/yocto-wolfprovider-tests-output-*.txt + retention-days: 7 + if-no-files-found: ignore diff --git a/.github/workflows/yocto-verify.yml b/.github/workflows/yocto-verify.yml new file mode 100644 index 00000000..523cb880 --- /dev/null +++ b/.github/workflows/yocto-verify.yml @@ -0,0 +1,115 @@ +name: Verify Yocto Environment + +# START OF COMMON SECTION +on: + workflow_call: + inputs: + wolfssl_ref: + required: true + type: string + openssl_ref: + required: true + type: string + fips_ref: + required: false + type: string + replace_default: + required: false + type: boolean + default: false +# END OF COMMON SECTION + +jobs: + verify_yocto_environment: + name: Verify Yocto Environment - ${{ inputs.wolfssl_ref }}-${{ inputs.openssl_ref }}-${{ inputs.fips_ref }}-${{ inputs.replace_default }} + runs-on: ubuntu-latest + container: + image: ghcr.io/crops/poky:ubuntu-22.04 + options: --user root + timeout-minutes: 30 + + steps: + - name: Checkout wolfProvider + uses: actions/checkout@v4 + + - name: Download Yocto image + uses: actions/download-artifact@v4 + with: + name: yocto-image-${{ inputs.fips_ref == 'FIPS' && 'fips' || 'nonfips' }}-${{ inputs.replace_default && 'replace-default' || 'standalone' }} + path: /tmp/yocto-images + + - name: Install QEMU, expect, and xz-utils + run: | + apt-get update + apt-get install -y qemu-system-x86 expect xz-utils + + - name: Setup Yocto image + run: | + echo "=== Downloaded Yocto image ===" + ls -lah /tmp/yocto-images/ + cd /tmp/yocto-images + + # Extract if Yocto image is compressed + if ls *.wic.xz 1> /dev/null 2>&1; then + echo "Extracting xz-compressed WIC files..." + unxz -v *.wic.xz || true + fi + + # Verify the Yocto image file is found + WIC_FILE=$(ls *.wic 2>/dev/null | grep -v "\.wic\." | head -1) + + if [ -z "$WIC_FILE" ] || [ ! -f "$WIC_FILE" ]; then + echo "ERROR: No decompressed Yocto image file found" + echo "Available files:" + ls -la /tmp/yocto-images/ + exit 1 + fi + + echo "Using Yocto image file: $WIC_FILE" + echo "Expected configuration: fips_ref=${{ inputs.fips_ref }}, replace_default=${{ inputs.replace_default }}" + echo "WIC_PATH=/tmp/yocto-images/$WIC_FILE" >> $GITHUB_ENV + + - name: Boot QEMU, verify configuration + timeout-minutes: 30 + run: | + # Run everything in a single QEMU boot session to capture output for verification + echo "=== Booting QEMU and verifying configuration for ${{ inputs.fips_ref }}-${{ inputs.replace_default }} ===" + echo "Yocto image file: $WIC_PATH" + + OUTPUT_FILE="/tmp/yocto-test-output-${{ inputs.fips_ref }}-${{ inputs.replace_default }}.txt" + + # Run commands and capture all output + # Check the replace-default detection file first, then verify providers + export EXPECT_TIMEOUT=3600 # 1 hour + $GITHUB_WORKSPACE/.github/scripts/boot-qemu.sh \ + "$WIC_PATH" \ + "cat /etc/openssl/replace-default-enabled 2>/dev/null || echo 'File not found'" \ + "openssl list -providers" \ + "openssl version" \ + "cd /usr/bin && ls -la wolfproviderenv" \ + "wolfproviderenv" > "$OUTPUT_FILE" 2>&1 || true + + # Display the output + echo "=== Full test output ===" + cat "$OUTPUT_FILE" + echo "" + + # Verify the Yocto environment is correctly built for test output + echo "=== Verifying configuration ===" + source $GITHUB_WORKSPACE/.github/scripts/yocto-verify-common.sh + yocto_env_verify \ + "$OUTPUT_FILE" \ + "${{ inputs.openssl_ref }}" \ + "${{ inputs.wolfssl_ref }}" \ + "${{ inputs.replace_default }}" \ + "${{ inputs.fips_ref }}" + + - name: Upload Yocto environment verification logs (if any) + if: always() + uses: actions/upload-artifact@v4 + with: + name: yocto-test-logs-${{ inputs.wolfssl_ref }}-${{ inputs.openssl_ref }}-${{ inputs.fips_ref == 'FIPS' && 'fips' || 'nonfips' }}-${{ inputs.replace_default && 'replace-default' || 'standalone' }} + path: | + /tmp/yocto-images/*.log + retention-days: 3 + if-no-files-found: ignore