After the move of the repo configs to `osbuild/images`, we changed the way to determine the all available distro repo configs by taking the last release of 'images'. This turns out to be fragile, especially when the test case is being run on a "rhel-x.y.0" branch or basically with any old osbuild-composer binary. It could happen also in Nightly test pipelines after the devel freeze. We always compile osbuild-composer binary with debug information, so we can determine the vendored 'images' version from the binary. We also always ship repo configs from the same 'images' version in the RPMs. Therefore modify the test case to check out the 'images' version that osbuild-composer was compiled with and use repo configs from that version. In addition, don't reduce the depth when cloning the images repository, because even 200 commits may be too little on some older RHEL ZStream branches. Signed-off-by: Tomáš Hozza <thozza@redhat.com>
366 lines
12 KiB
Bash
Executable file
366 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' | sed 's/\.[^.]*$//' | 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
|
|
|
|
# determine the 'osbuild/images' repository version used by the osbuild-composer
|
|
sudo dnf install -y golang
|
|
COMPOSER_DEPS=$(go version -m /usr/libexec/osbuild-composer/osbuild-composer)
|
|
IMAGES_VERSION=$(echo "$COMPOSER_DEPS" | sed -n 's|^\t\+dep\t\+github\.com/osbuild/images\t\+\(v[0-9.]\+\)\t\+$|\1|p')
|
|
if [ -z "$IMAGES_VERSION" ]; then
|
|
echo "ERROR: Unable to determine osbuild/images version from osbuild-composer binary. Composer deps:"
|
|
echo "$COMPOSER_DEPS"
|
|
exit 1
|
|
fi
|
|
|
|
greenprint "INFO: Using osbuild/images version to check repo configs: $IMAGES_VERSION"
|
|
git clone http://github.com/osbuild/images
|
|
( cd images && git checkout "$IMAGES_VERSION" )
|
|
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' | sed 's/\.[^.]*$//')
|
|
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
|