Test actual image builds of older distros on RHEL and CentOS, to catch issues such as https://issues.redhat.com/browse/RHEL-71397. The test can be later extended to cover also Fedora, but this is out of scope at this point, since the goal is to ensure that RHEL cross-distro builds work, because these differ a lot. Signed-off-by: Tomáš Hozza <thozza@redhat.com>
359 lines
12 KiB
Bash
Executable file
359 lines
12 KiB
Bash
Executable file
#!/usr/bin/bash
|
|
|
|
#
|
|
# Test the available distributions. Only allow releases for the current distro.
|
|
#
|
|
APISOCKET=/run/weldr/api.socket
|
|
|
|
source /etc/os-release
|
|
source /usr/libexec/tests/osbuild-composer/shared_lib.sh
|
|
|
|
# Build a grep pattern that results in an empty string when the expected distros are installed
|
|
case $ID in
|
|
fedora)
|
|
PATTERN="\[|\]|fedora-"
|
|
;;
|
|
rhel)
|
|
MAJOR=$(echo "$VERSION_ID" | sed -E 's/\..*//')
|
|
case $MAJOR in
|
|
8)
|
|
# RHEL 8 only supports building RHEL 8
|
|
PATTERN="\[|\]|rhel-8"
|
|
;;
|
|
9)
|
|
# RHEL 9 supports building RHEL 8 and 9
|
|
PATTERN="\[|\]|rhel-(8|9)"
|
|
;;
|
|
*)
|
|
# RHEL 10 and later support building all releases
|
|
PATTERN="\[|\]|rhel-.*"
|
|
;;
|
|
esac
|
|
;;
|
|
centos)
|
|
MAJOR=$(echo "$VERSION_ID" | sed -E 's/\..*//')
|
|
case $MAJOR in
|
|
9)
|
|
# CentOS 9 supports building CentosOS 9
|
|
PATTERN="\[|\]|centos-(9)"
|
|
;;
|
|
*)
|
|
# CentOS 10 and later support building all releases
|
|
PATTERN="\[|\]|centos-.*"
|
|
;;
|
|
esac
|
|
;;
|
|
*)
|
|
echo "Unknown distribution id: $ID 😢"
|
|
exit 1
|
|
;;
|
|
esac
|
|
|
|
|
|
# Provision the software under test.
|
|
/usr/libexec/osbuild-composer-test/provision.sh none
|
|
echo "====> Finished Provisioning system"
|
|
echo "====> Starting $(basename "$0")"
|
|
|
|
# Remove repo overrides installed by provision.sh, these will show up in the
|
|
# list and cause it to fail and are not needed since this test doesn't build
|
|
# anything.
|
|
sudo rm -rf /etc/osbuild-composer/repositories
|
|
sudo systemctl stop 'osbuild*.service'
|
|
sudo composer-cli status show
|
|
|
|
echo "Repository directories:"
|
|
ls -lR /usr/share/osbuild-composer/repositories/
|
|
|
|
echo "Repositories installed by the rpm:"
|
|
rpm -qil osbuild-composer-core
|
|
|
|
# composer-cli in RHEL 8 doesn't support distro command, so use curl for this test
|
|
if [ ! -e $APISOCKET ]; then
|
|
echo "osbuild-composer.socket has not been started. 😢"
|
|
exit 1
|
|
fi
|
|
|
|
if ! sudo curl -s --unix-socket $APISOCKET http:///localhost/api/status > /dev/null; then
|
|
echo "osbuild-composer server not available. 😢"
|
|
exit 1
|
|
fi
|
|
|
|
if ! RECOGNIZED_DISTROS=$(sudo curl -s --unix-socket $APISOCKET http:///localhost/api/v1/distros/list | jq -r '.distros[]'); then
|
|
echo "osbuild-composer server error getting distros list. 😢"
|
|
exit 1
|
|
fi
|
|
|
|
# Get a list of all installed distros and compare it with a pattern matching host distribution
|
|
# Filter out beta and centos-stream, see GH issue #2257
|
|
INSTALLED_DISTROS=$(find "/usr/share/osbuild-composer/repositories" -name '*.json' -printf '%P\n' | awk -F "." '{ print $1 }' | grep -Ev 'beta|stream' | sort)
|
|
INSTALLED_REMAINDER=$(echo "$INSTALLED_DISTROS" | grep -v -E "$PATTERN")
|
|
# Check if there are any extra distros that match the host pattern but are not recognized
|
|
UNRECOGNIZED_DISTROS=$(echo "${INSTALLED_DISTROS}" | grep -v "${RECOGNIZED_DISTROS}")
|
|
if [ -n "$INSTALLED_REMAINDER" ] || [ -n "$UNRECOGNIZED_DISTROS" ];then
|
|
echo "Unexpected distros detected:"
|
|
echo "$INSTALLED_REMAINDER"
|
|
echo "$UNRECOGNIZED_DISTROS"
|
|
exit 1
|
|
else
|
|
echo "All installed distros are recognized by composer."
|
|
fi
|
|
|
|
# set path to all "images" repositories, do not use "main" here but the
|
|
# last release version (this assume 200 commits since the last tag)
|
|
git clone --depth 200 http://github.com/osbuild/images
|
|
( cd images &&
|
|
git checkout "$(git describe --tags "$(git rev-list --tags --max-count=1)")"
|
|
)
|
|
REPO_PATH="images/data/repositories/"
|
|
|
|
# ALL_DISTROS - all possible distros from upstream repository
|
|
# ALL_EXPECTED_DISTROS - all distros matching host pattern
|
|
# ALL_REMAINDERS - all the unrecognized distros
|
|
# Filter out beta and centos-stream, see GH issue #2257
|
|
ALL_DISTROS=$(find "$REPO_PATH" -name '*.json' -printf '%P\n' | grep -v 'no-aux-key' | awk -F "." '{ print $1 }')
|
|
ALL_EXPECTED_DISTROS=$(echo "$ALL_DISTROS" | grep -E "$PATTERN" | grep -Ev 'beta|stream' | sort)
|
|
# Warning: filter out the remaining distros by matching whole words to avoid matching
|
|
# the value rhel-9X by the pattern rhel-9!
|
|
# If we're running on a RHEL 9.X osbuild-composer doesn't know anything about 9.X+1
|
|
# images so the value rhel-9.X+1 should be treated as unrecognized and error out as
|
|
# expected in the test snippet further below
|
|
ALL_REMAINDERS=$(echo "$ALL_DISTROS" | grep -vw "$RECOGNIZED_DISTROS")
|
|
|
|
echo "DEBUG: ===== ALL_DISTROS ===="
|
|
echo "$ALL_DISTROS"
|
|
echo "DEBUG: ===== ALL_EXPECTED_DISTROS ===="
|
|
echo "$ALL_EXPECTED_DISTROS"
|
|
echo "DEBUG: ===== INSTALLED_DISTROS ===="
|
|
echo "$INSTALLED_DISTROS"
|
|
echo "DEBUG: ===== ALL_REMAINDERS ===="
|
|
echo "$ALL_REMAINDERS"
|
|
echo "DEBUG: ===== END ===="
|
|
|
|
# Check for any missing distros based on the expected host pattern
|
|
if [ "$ALL_EXPECTED_DISTROS" != "$INSTALLED_DISTROS" ];then
|
|
echo "Some distros are missing!"
|
|
echo "Missing distros:"
|
|
diff <(echo "${ALL_EXPECTED_DISTROS}") <(echo "${INSTALLED_DISTROS}") | grep "<" | sed 's/^<\ //g'
|
|
|
|
# the check above compares repositories/*.json files from git checkout
|
|
# vs the files installed from an RPM package in order to find files which are
|
|
# not included in the RPM. Don't fail when running on nightly CI pipeline b/c
|
|
# very often the repository will be newer than the downstream RPM.
|
|
if [[ "${CI_PIPELINE_SOURCE:-}" != "schedule" ]]; then
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
echo "INFO: Start interating over ALL_REMAINDERS"
|
|
# Push a blueprint with unsupported distro to see if composer fails gracefuly
|
|
for REMAINING_DISTRO in $ALL_REMAINDERS; do
|
|
echo "INFO: iterating over $REMAINING_DISTRO"
|
|
|
|
TEST_BP=blueprint.toml
|
|
tee "$TEST_BP" > /dev/null << EOF
|
|
name = "bash"
|
|
description = "A base system with bash"
|
|
version = "0.0.1"
|
|
distro= "$REMAINING_DISTRO"
|
|
|
|
[[packages]]
|
|
name = "bash"
|
|
EOF
|
|
|
|
set +e
|
|
RESPONSE=$(sudo composer-cli blueprints push $TEST_BP 2>&1)
|
|
set -e
|
|
|
|
echo "DEBUG: $REMAINING_DISTRO, RESPONSE=$RESPONSE"
|
|
|
|
# there is a different reponse if legacy composer-cli is used
|
|
if rpm -q --quiet weldr-client; then
|
|
EXPECTED_RESPONSE="ERROR: BlueprintsError: '$REMAINING_DISTRO' is not a valid distribution (architecture '$(uname -m)')"
|
|
else
|
|
EXPECTED_RESPONSE="'$REMAINING_DISTRO' is not a valid distribution"
|
|
RESPONSE=${RESPONSE#*: }
|
|
fi
|
|
|
|
if [ "$RESPONSE" == "$EXPECTED_RESPONSE" ];then
|
|
echo "Blueprint push with $REMAINING_DISTRO distro failed as expected."
|
|
else
|
|
echo "Something went wrong during blueprint push test."
|
|
echo "RESPONSE=$RESPONSE"
|
|
echo "EXPECTED_RESPONSE=$EXPECTED_RESPONSE"
|
|
exit 1
|
|
fi
|
|
done
|
|
|
|
# Function to start a compose
|
|
# TODO: This function should be moved to shared_lib.sh
|
|
function start_compose() {
|
|
local blueprint=$1
|
|
local image_type=${2:-qcow2}
|
|
|
|
local compose_start
|
|
compose_start=$(mktemp)
|
|
local compose_id
|
|
|
|
greenprint "🚀 Starting compose of $image_type for $blueprint blueprint"
|
|
sudo composer-cli --json compose start "$blueprint" "$image_type" | tee "$compose_start" >&2
|
|
compose_id=$(get_build_info ".build_id" "$compose_start")
|
|
|
|
greenprint "INFO: Compose started with ID: ${compose_id}"
|
|
echo "$compose_id"
|
|
}
|
|
|
|
# Function to wait for a compose to finish
|
|
# TODO: This function should be moved to shared_lib.sh
|
|
function wait_for_compose() {
|
|
local compose_id=$1
|
|
local timeout=${2:-600}
|
|
local compose_status
|
|
|
|
if [[ -z "$compose_id" ]]; then
|
|
redprint "ERROR (wait_for_compose): No compose ID provided"
|
|
exit 1
|
|
fi
|
|
|
|
local compose_info
|
|
compose_info=$(mktemp)
|
|
|
|
greenprint "⏱ Waiting for compose to finish: ${compose_id}"
|
|
while [[ $timeout -gt 0 ]]; do
|
|
sudo composer-cli --json compose info "${compose_id}" | tee "$compose_info" > /dev/null
|
|
compose_status=$(get_build_info ".queue_status" "$compose_info")
|
|
|
|
# Is the compose finished?
|
|
if [[ $compose_status != "RUNNING" ]] && [[ $compose_status != "WAITING" ]]; then
|
|
break
|
|
fi
|
|
|
|
# Wait 30 seconds and try again.
|
|
sleep 30
|
|
timeout=$((timeout - 30))
|
|
done
|
|
|
|
# Get the last compose status if the compose was still running before the last sleep
|
|
if [[ $compose_status == "RUNNING" ]]; then
|
|
sudo composer-cli --json compose info "${compose_id}" | tee "$compose_info" > /dev/null
|
|
compose_status=$(get_build_info ".queue_status" "$compose_info")
|
|
fi
|
|
|
|
if [[ $compose_status == "RUNNING" || $compose_status == "WAITING" ]] && [[ timeout -le 0 ]]; then
|
|
redprint "ERROR: Compose did not finish in time"
|
|
exit 1
|
|
fi
|
|
|
|
greenprint "INFO: Compose finished with status: ${compose_status}"
|
|
|
|
# Return the status of the compose
|
|
echo "$compose_status"
|
|
}
|
|
|
|
# Get the compose log.
|
|
# TODO: This function should be moved to shared_lib.sh
|
|
function get_compose_log() {
|
|
local compose_id=$1
|
|
|
|
if [[ -z "$compose_id" ]]; then
|
|
redprint "ERROR (get_compose_log): No compose ID provided"
|
|
exit 1
|
|
fi
|
|
|
|
sudo composer-cli compose log "$compose_id"
|
|
}
|
|
|
|
# Function to ensure the system is subscribed
|
|
# Subscription is need to build RHEL GA images
|
|
function ensure_subscription() {
|
|
if sudo subscription-manager status; then
|
|
greenprint "📋 Running on subscribed RHEL machine"
|
|
elif [[ -f "$V2_RHN_REGISTRATION_SCRIPT" ]]; then
|
|
greenprint "📋 Registering the system using registration script"
|
|
sudo bash "$V2_RHN_REGISTRATION_SCRIPT"
|
|
# Since the system was not registered, it didn't depend on the CDN repos, so don't enable them
|
|
sudo subscription-manager config --rhsm.manage_repos=1
|
|
else
|
|
redprint "ERROR: Not running on a subscribed RHEL machine and no registration script provided"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
# Function to build a vanilla image for a given distro
|
|
function test_cross_build_distro() {
|
|
local distro=$1
|
|
# default to gce image type, because building it will try importing all GPG keys that we ship in repo configs
|
|
local image_type=${2:-gce}
|
|
|
|
if [[ -z "$distro" ]]; then
|
|
redprint "ERROR (cross_build_distro): No distro provided"
|
|
exit 1
|
|
fi
|
|
|
|
greenprint "Testing cross-distro build of $distro ($image_type)"
|
|
local blueprint
|
|
blueprint=$(mktemp --suffix=".toml")
|
|
|
|
local bp_name="cross-distro-$distro"
|
|
cat > "$blueprint" << EOF
|
|
name = "$bp_name"
|
|
distro = "$distro"
|
|
EOF
|
|
|
|
echo "INFO: $blueprint content:"
|
|
cat "$blueprint"
|
|
|
|
sudo composer-cli blueprints push "$blueprint"
|
|
local compose_id
|
|
compose_id=$(start_compose "$bp_name" "$image_type")
|
|
local compose_status
|
|
compose_status=$(wait_for_compose "$compose_id")
|
|
|
|
if [[ $compose_status != "FINISHED" ]]; then
|
|
redprint "ERROR: Compose did not finish successfully ($compose_status)"
|
|
redprint "INFO: Compose logs for $compose_id:"
|
|
get_compose_log "$compose_id"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
# Test cross-distro builds on RHEL and CentOS
|
|
case $ID in
|
|
rhel)
|
|
MAJOR=$(echo "$VERSION_ID" | sed -E 's/\..*//')
|
|
ensure_subscription
|
|
case $MAJOR in
|
|
9)
|
|
# There are no new RHEL-8 releases, so just use the distro alias
|
|
test_cross_build_distro "rhel-8"
|
|
;;
|
|
10)
|
|
# There are no new RHEL-8 releases, so just use the distro alias
|
|
test_cross_build_distro "rhel-8"
|
|
# Test building RHEL 9.5, which is the latest RHEL-9 minor version that is GA at this time
|
|
test_cross_build_distro "rhel-9.5"
|
|
;;
|
|
*)
|
|
greenprint "INFO not testing actual cross-distro image build on $ID-$VERSION_ID"
|
|
;;
|
|
esac
|
|
;;
|
|
centos)
|
|
MAJOR=$(echo "$VERSION_ID" | sed -E 's/\..*//')
|
|
case $MAJOR in
|
|
10)
|
|
test_cross_build_distro "centos-9"
|
|
;;
|
|
*)
|
|
greenprint "INFO not testing actual cross-distro image build on $ID-$VERSION_ID"
|
|
;;
|
|
esac
|
|
;;
|
|
*)
|
|
greenprint "INFO not testing actual cross-distro image build on $ID-$VERSION_ID"
|
|
;;
|
|
esac
|
|
|
|
|
|
echo "🎉 All tests passed."
|
|
exit 0
|