370 lines
12 KiB
Bash
370 lines
12 KiB
Bash
#!/bin/bash
|
|
|
|
# Test case for Weldr API (on-premise) distro dot notation and aliases.
|
|
#
|
|
# This test case verifies that distributions can be specified with and without
|
|
# the dot to sepratae the major and minor version (true for RHEL-8 and RHEL-9).
|
|
# It also verifies the behavior of distro name aliases
|
|
# (e.g. "rhel-9" -> "rhel-9.7"). This is done by building a SAP image and
|
|
# inspecting it using guestfish. Specifically, the SAP image contains DNF VAR
|
|
# config /etc/dnf/vars/releasever, which contains value "X.Y", which should be
|
|
# the same as the distro release that the alias points to.
|
|
|
|
set -xeuo pipefail
|
|
|
|
source /usr/libexec/osbuild-composer-test/set-env-variables.sh
|
|
source /usr/libexec/tests/osbuild-composer/shared_lib.sh
|
|
|
|
# Don't run in nightly pipeline until we have the version with dot-notation in nightly compose
|
|
if ! nvrGreaterOrEqual "osbuild-composer" "100"; then
|
|
echo "osbuild-composer version is too old, skipping the test"
|
|
exit 0
|
|
fi
|
|
|
|
TMPDIR=$(mktemp -d)
|
|
greenprint "Registering clean ups"
|
|
function cleanup() {
|
|
greenprint "== Script execution stopped or finished - Cleaning up =="
|
|
set +eu
|
|
rm -rf "${TMPDIR}"
|
|
set -eu
|
|
}
|
|
trap cleanup EXIT
|
|
|
|
# Remove any restrictions on the image types for weldr API, since
|
|
# testing the distro alias requires building the SAP image.
|
|
#
|
|
# Also override the alias for RHEL 8 since the default alias, 8.10, doesn't
|
|
# have a locked version, so the releasever is not set in the dnf vars, and this
|
|
# test relies on that file to verify that we are using the correct distro
|
|
# object and code path.
|
|
EXTRA_COMPOSER_CONF="$(mktemp -p "$TMPDIR")"
|
|
cat <<EOF | tee "${EXTRA_COMPOSER_CONF}"
|
|
# overrides the default rhel-* configuration
|
|
[weldr_api.distros."rhel-*"]
|
|
|
|
# overrides the default rhel-8 alias
|
|
[distro_aliases]
|
|
rhel-8 = "rhel-8.8"
|
|
rhel-9 = "rhel-9.7"
|
|
EOF
|
|
|
|
# Provision the software under test.
|
|
/usr/libexec/osbuild-composer-test/provision.sh none "${EXTRA_COMPOSER_CONF}"
|
|
|
|
# install test dependencies
|
|
sudo dnf install -y '/usr/bin/guestfish'
|
|
|
|
# path for repository overrides with higher priority
|
|
REPO_OVERRIDES_DIR=/etc/osbuild-composer/repositories
|
|
# path for repositories shipped with osbuild-composer (lower priority)
|
|
REPO_SHIPPED_DIR="/usr/share/osbuild-composer/repositories"
|
|
# path for repositories shipped with osbuild-composer tests, intended for
|
|
# use as part of tests.
|
|
REPO_TEST_DIR="/usr/share/tests/osbuild-composer/repositories"
|
|
|
|
DISTRO="${ID}-${VERSION_ID}"
|
|
DISTRO_WITHOUT_DOT="${ID}-${VERSION_ID//./}"
|
|
DISTRO_WITHOUT_MINOR="${ID}-${VERSION_ID%.*}"
|
|
|
|
DISTRO_TEST_REPO="${REPO_TEST_DIR}/${DISTRO}.json"
|
|
|
|
# Clean up the repository directories
|
|
function clean_repo_dirs() {
|
|
sudo rm -rf "${REPO_OVERRIDES_DIR}"
|
|
sudo mkdir -p "${REPO_OVERRIDES_DIR}"
|
|
sudo rm -rf "${REPO_SHIPPED_DIR}"
|
|
sudo mkdir -p "${REPO_SHIPPED_DIR}"
|
|
}
|
|
|
|
# Stop osbuild-composer, worker and all sockets
|
|
function stop_osbuild_composer() {
|
|
sudo systemctl stop 'osbuild*'
|
|
}
|
|
|
|
# Start osbuild-composer with clean cache and store
|
|
function start_osbuild_composer_clean() {
|
|
stop_osbuild_composer
|
|
sudo rm -rf /var/cache/osbuild-composer
|
|
sudo rm -rf /var/lib/osbuild-composer
|
|
sudo systemctl start osbuild-composer.socket
|
|
|
|
# check that the API is running
|
|
sudo composer-cli status show
|
|
}
|
|
|
|
# Common test case for verifying that depsolving the provided blueprint works.
|
|
function _test_depsolving_bp() {
|
|
if [[ $# -ne 2 ]]; then
|
|
echo "Usage: _test_depsolving_bp <blueprint> <blueprint_name>"
|
|
exit 1
|
|
fi
|
|
|
|
local blueprint="$1"
|
|
local blueprint_name="$2"
|
|
|
|
sudo composer-cli blueprints push "${blueprint}"
|
|
sudo composer-cli blueprints depsolve "${blueprint_name}"
|
|
sudo composer-cli blueprints delete "${blueprint_name}"
|
|
}
|
|
|
|
# Common test case for verifying that the provided blueprint can produce an image.
|
|
function _test_compose_bp() {
|
|
if [[ $# -lt 3 || $# -gt 5 ]]; then
|
|
echo "Usage: _test_compose_bp <blueprint> <blueprint_name> <tmpdir> [<image_type>] [<test_distro_alias>]"
|
|
exit 1
|
|
fi
|
|
|
|
local blueprint="$1"
|
|
local blueprint_name="$2"
|
|
local tmpdir="$3"
|
|
local image_type="${4:-qcow2}"
|
|
local test_distro_alias="${5:-0}"
|
|
|
|
local composestart="${tmpdir}/compose-start.json"
|
|
local composeinfo="${tmpdir}/compose-info.json"
|
|
|
|
sudo composer-cli blueprints push "${blueprint}"
|
|
sudo composer-cli --json compose start "${blueprint_name}" "${image_type}" | tee "${composestart}"
|
|
|
|
local composeid
|
|
composeid=$(get_build_info '.build_id' "${composestart}")
|
|
|
|
# Wait for the compose to finish.
|
|
local composestatus
|
|
echo "⏱ Waiting for compose to finish: ${composeid}"
|
|
while true; do
|
|
sudo composer-cli --json compose info "${composeid}" | tee "${composeinfo}" > /dev/null
|
|
composestatus=$(get_build_info '.queue_status' "${composeinfo}")
|
|
|
|
# Is the compose finished?
|
|
if [[ ${composestatus} != RUNNING ]] && [[ ${composestatus} != WAITING ]]; then
|
|
break
|
|
fi
|
|
|
|
# Wait 30 seconds and try again.
|
|
sleep 30
|
|
done
|
|
|
|
jq . "${composeinfo}"
|
|
|
|
# Did the compose finish with success?
|
|
if [[ $composestatus != FINISHED ]]; then
|
|
echo "Something went wrong with the compose. 😢"
|
|
exit 1
|
|
fi
|
|
|
|
if [[ "${test_distro_alias}" == "1" ]]; then
|
|
pushd "${tmpdir}"
|
|
_verify_distro_alias_img "${composeid}"
|
|
popd
|
|
fi
|
|
|
|
sudo composer-cli compose delete "${composeid}" >/dev/null
|
|
}
|
|
|
|
# Verify that the image contains /etc/dnf/vars/releasever with the expected
|
|
# content. Specifically, verify that the content of /etc/dnf/vars/releasever
|
|
# is the same as the VERSION_ID of the distro that the distro alias point to.
|
|
function _verify_distro_alias_img() {
|
|
if [[ $# -ne 1 ]]; then
|
|
echo "Usage: _verify_distro_alias_img <compose_id>"
|
|
exit 1
|
|
fi
|
|
|
|
local compose_id="$1"
|
|
|
|
local image_file
|
|
image_file=$(sudo composer-cli compose image "${compose_id}")
|
|
|
|
if [[ ! -f "${image_file}" ]]; then
|
|
echo "Image file ${image_file} does not exist."
|
|
exit 1
|
|
fi
|
|
|
|
# uncompress the file if compressed
|
|
if [[ "${image_file}" == *.xz ]]; then
|
|
sudo unxz "${image_file}"
|
|
image_file="${image_file%.xz}"
|
|
fi
|
|
|
|
local dnf_vars_releasever="/etc/dnf/vars/releasever"
|
|
greenprint "Check ${dnf_vars_releasever} in the image"
|
|
|
|
local dnf_vars_releasever_content
|
|
dnf_vars_releasever_content=$(LIBGUESTFS_BACKEND=direct sudo --preserve-env=LIBGUESTFS_BACKEND guestfish --ro -a "${image_file}" -i cat "${dnf_vars_releasever}")
|
|
|
|
if [[ "${dnf_vars_releasever_content}" != "${VERSION_ID}" ]]; then
|
|
echo "Unexpected content of ${dnf_vars_releasever}: ${dnf_vars_releasever_content}"
|
|
echo "Expected: ${VERSION_ID}"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
# Create a testing blueprint with wget package.
|
|
function _create_blueprint() {
|
|
if [[ $# -lt 2 ]] || [[ $# -gt 3 ]]; then
|
|
echo "Usage: _create_blueprint <directory> <blueprint_name> [<distro>]"
|
|
exit 1
|
|
fi
|
|
|
|
local directory="$1"
|
|
local blueprint_name="$2"
|
|
local distro="${3:-}"
|
|
|
|
cat <<EOF > "${directory}/${blueprint_name}.toml"
|
|
name = "${blueprint_name}"
|
|
description = "A testing blueprint"
|
|
version = "0.0.1"
|
|
EOF
|
|
|
|
if [[ -n "${distro}" ]]; then
|
|
cat <<EOF >> "${directory}/${blueprint_name}.toml"
|
|
distro = "${distro}"
|
|
EOF
|
|
fi
|
|
|
|
cat <<EOF >> "${directory}/${blueprint_name}.toml"
|
|
|
|
[[packages]]
|
|
name = "wget"
|
|
EOF
|
|
|
|
echo "${directory}/${blueprint_name}.toml"
|
|
}
|
|
|
|
# Common test case for repo configurations.
|
|
function _test_repo() {
|
|
local test_name="$1"
|
|
local distro="$2"
|
|
|
|
greenprint "TEST: ${test_name}"
|
|
|
|
local directory="${TMPDIR}/${test_name}"
|
|
mkdir -p "${directory}"
|
|
|
|
stop_osbuild_composer
|
|
clean_repo_dirs
|
|
sudo cp "${DISTRO_TEST_REPO}" "${REPO_SHIPPED_DIR}/${distro}.json"
|
|
start_osbuild_composer_clean
|
|
local test_bp
|
|
test_bp=$(_create_blueprint "${directory}" "${test_name}")
|
|
_test_depsolving_bp "${test_bp}" "${test_name}"
|
|
}
|
|
|
|
# Test that the repository definitions can contain a dot in its filename,
|
|
# separating the major and minor version.
|
|
function test_repo_with_dot() {
|
|
_test_repo "repo_with_dot" "${DISTRO}"
|
|
}
|
|
|
|
# Test that the repository definitions can be used without a dot in its filename,
|
|
# even though the distro version may contain a dot.
|
|
function test_repo_without_dot() {
|
|
_test_repo "repo_without_dot" "${DISTRO_WITHOUT_DOT}"
|
|
}
|
|
|
|
# Test that the repository definitions with and without a dot in its filename
|
|
# are equivalent and can override each other. Test uses empty file in the
|
|
# shipped directory and the test repository in the overrides directory to
|
|
# verify that the override happens.
|
|
function test_repo_dot_overrides() {
|
|
local test_name="repo_dot_overrides"
|
|
greenprint "TEST: ${test_name}"
|
|
|
|
local directory="${TMPDIR}/${test_name}"
|
|
mkdir -p "${directory}"
|
|
|
|
# Case 1: repo without dot in shipped dir, repo with dot in overrides dir
|
|
stop_osbuild_composer
|
|
clean_repo_dirs
|
|
echo "{}" | sudo tee "${REPO_SHIPPED_DIR}/${DISTRO_WITHOUT_DOT}.json"
|
|
sudo cp "${DISTRO_TEST_REPO}" "${REPO_OVERRIDES_DIR}/${DISTRO}.json"
|
|
start_osbuild_composer_clean
|
|
local test_bp
|
|
test_bp=$(_create_blueprint "${directory}" "${test_name}")
|
|
_test_depsolving_bp "${test_bp}" "${test_name}"
|
|
|
|
# Case 2: repo with dot in shipped dir, repo without dot in overrides dir
|
|
stop_osbuild_composer
|
|
clean_repo_dirs
|
|
echo "{}" | sudo tee "${REPO_SHIPPED_DIR}/${DISTRO}.json"
|
|
sudo cp "${DISTRO_TEST_REPO}" "${REPO_OVERRIDES_DIR}/${DISTRO_WITHOUT_DOT}.json"
|
|
start_osbuild_composer_clean
|
|
test_bp=$(_create_blueprint "${directory}" "${test_name}")
|
|
_test_depsolving_bp "${test_bp}" "${test_name}"
|
|
}
|
|
|
|
# Common test case for distro names in BP.
|
|
function _test_distro() {
|
|
local test_name="$1"
|
|
local distro="$2"
|
|
|
|
greenprint "TEST: ${test_name}"
|
|
|
|
local directory="${TMPDIR}/${test_name}"
|
|
mkdir -p "${directory}"
|
|
|
|
stop_osbuild_composer
|
|
clean_repo_dirs
|
|
sudo cp "${DISTRO_TEST_REPO}" "${REPO_SHIPPED_DIR}"
|
|
start_osbuild_composer_clean
|
|
local test_bp
|
|
test_bp=$(_create_blueprint "${directory}" "${test_name}" "${distro}")
|
|
_test_depsolving_bp "${test_bp}" "${test_name}"
|
|
_test_compose_bp "${test_bp}" "${test_name}" "${directory}"
|
|
}
|
|
|
|
# Test that the distro name in the blueprint can contain a dot in its name.
|
|
function test_distro_with_dot() {
|
|
_test_distro "distro_with_dot" "${DISTRO}"
|
|
}
|
|
|
|
# Test that the distro name in the blueprint can be used without a dot in its name.
|
|
function test_distro_without_dot() {
|
|
_test_distro "distro_without_dot" "${DISTRO_WITHOUT_DOT}"
|
|
}
|
|
|
|
# Test that the distro alias without the minor version can be used in the blueprint.
|
|
# This test case requires that the test case is run on RHEL version which is
|
|
# set as the target distro without minor version in the default composer configuration.
|
|
function test_distro_alias() {
|
|
local test_name="distro_alias"
|
|
greenprint "TEST: ${test_name}"
|
|
|
|
if [[ "${ID}" != "rhel" ]]; then
|
|
echo "Testing distro alias requires RHEL distro."
|
|
exit 1
|
|
fi
|
|
|
|
local directory="${TMPDIR}/${test_name}"
|
|
mkdir -p "${directory}"
|
|
|
|
stop_osbuild_composer
|
|
clean_repo_dirs
|
|
sudo cp "${DISTRO_TEST_REPO}" "${REPO_SHIPPED_DIR}/${DISTRO_WITHOUT_MINOR}.json"
|
|
start_osbuild_composer_clean
|
|
local test_bp
|
|
test_bp=$(_create_blueprint "${directory}" "${test_name}" "${DISTRO_WITHOUT_MINOR}")
|
|
_test_depsolving_bp "${test_bp}" "${test_name}"
|
|
_test_compose_bp "${test_bp}" "${test_name}" "${directory}" "ec2-sap" "1"
|
|
}
|
|
|
|
# Skip all tests if the DISTRO does not contain a dot.
|
|
if [[ "${DISTRO}" == "${DISTRO_WITHOUT_DOT}" ]]; then
|
|
echo "The distro does not contain dot to separate major and minor version."
|
|
echo "Skipping the test, since testing the dot notation or aliases does not make sense."
|
|
exit 0
|
|
fi
|
|
|
|
# Run the tests.
|
|
test_repo_with_dot
|
|
test_repo_without_dot
|
|
test_repo_dot_overrides
|
|
test_distro_with_dot
|
|
test_distro_without_dot
|
|
test_distro_alias
|
|
|
|
# If we got here, all tests passed.
|
|
echo "All tests passed! 🥳"
|
|
exit 0
|