mirror of
https://github.com/SCST-project/scst.git
synced 2026-08-29 12:17:15 +00:00
Keep exact kernel versions only in ABT_KERNELS. Resolve the bounded GitHub regression and RPM subsets from stable selectors, and reject missing or ambiguous matches.
209 lines
5.9 KiB
Bash
209 lines
5.9 KiB
Bash
#!/bin/bash
|
|
|
|
set -euo pipefail
|
|
|
|
root_dir="$(readlink -f "$(dirname "$0")/..")"
|
|
readonly root_dir
|
|
readonly nightly_config="${SCST_NIGHTLY_CONFIG:-${root_dir}/nightly/conf/nightly.conf}"
|
|
readonly github_config="${SCST_GITHUB_MATRIX_CONFIG:-${root_dir}/.github/kernel-matrix.conf}"
|
|
|
|
# shellcheck source=../nightly/conf/nightly.conf
|
|
source "${nightly_config}"
|
|
# shellcheck source=../.github/kernel-matrix.conf
|
|
source "${github_config}"
|
|
|
|
: "${ABT_KERNELS:?ABT_KERNELS is not defined in ${nightly_config}}"
|
|
: "${GITHUB_REGRESSION_KERNEL_SELECTORS:?GITHUB_REGRESSION_KERNEL_SELECTORS is not defined in ${github_config}}"
|
|
: "${GITHUB_RPM_TARGETS:?GITHUB_RPM_TARGETS is not defined in ${github_config}}"
|
|
command -v jq >/dev/null 2>&1 || {
|
|
echo "Error: jq is required." >&2
|
|
exit 1
|
|
}
|
|
|
|
read -r -a raw_kernel_entries <<<"${ABT_KERNELS}"
|
|
|
|
strip_kernel_options() {
|
|
stripped_kernel="$1"
|
|
|
|
while true; do
|
|
case "${stripped_kernel}" in
|
|
*-nc) stripped_kernel="${stripped_kernel%-nc}" ;;
|
|
*-ns) stripped_kernel="${stripped_kernel%-ns}" ;;
|
|
*-nm) stripped_kernel="${stripped_kernel%-nm}" ;;
|
|
*-4) stripped_kernel="${stripped_kernel%-4}" ;;
|
|
*-f) stripped_kernel="${stripped_kernel%-f}" ;;
|
|
*-i) stripped_kernel="${stripped_kernel%-i}" ;;
|
|
*-u) stripped_kernel="${stripped_kernel%-u}" ;;
|
|
*-p) stripped_kernel="${stripped_kernel%-p}" ;;
|
|
*) return ;;
|
|
esac
|
|
done
|
|
}
|
|
|
|
canonical_kernel_entries=()
|
|
for raw_kernel in "${raw_kernel_entries[@]}"; do
|
|
strip_kernel_options "${raw_kernel}"
|
|
IFS='^' read -r -a kernel_parts <<<"${stripped_kernel}"
|
|
if [[ ${#kernel_parts[@]} -ne 1 && ${#kernel_parts[@]} -ne 3 ]]; then
|
|
echo "Error: invalid ABT_KERNELS entry: ${raw_kernel}" >&2
|
|
exit 1
|
|
fi
|
|
canonical_kernel_entries+=("${stripped_kernel}")
|
|
done
|
|
readonly -a canonical_kernel_entries
|
|
|
|
version_matches_series() {
|
|
local version="$1"
|
|
local series="$2"
|
|
|
|
[[ "${version}" == "${series}" ||
|
|
"${version}" == "${series}."* ||
|
|
"${version}" == "${series}-"* ]]
|
|
}
|
|
|
|
resolve_kernel() {
|
|
local selector="$1"
|
|
local entry version distro release
|
|
local -a selector_parts entry_parts matches=()
|
|
|
|
IFS='^' read -r -a selector_parts <<<"${selector}"
|
|
if [[ ${#selector_parts[@]} -lt 1 || ${#selector_parts[@]} -gt 3 ]]; then
|
|
echo "Error: invalid kernel selector: ${selector}" >&2
|
|
return 1
|
|
fi
|
|
|
|
for entry in "${canonical_kernel_entries[@]}"; do
|
|
IFS='^' read -r -a entry_parts <<<"${entry}"
|
|
version="${entry_parts[0]}"
|
|
distro="${entry_parts[1]:-}"
|
|
release="${entry_parts[2]:-}"
|
|
|
|
if [[ ${#selector_parts[@]} -eq 1 ]]; then
|
|
if [[ -z "${distro}" ]] &&
|
|
version_matches_series "${version}" "${selector_parts[0]}"; then
|
|
matches+=("${entry}")
|
|
fi
|
|
elif [[ "${distro}" == "${selector_parts[0]}" &&
|
|
"${release}" == "${selector_parts[1]}" ]]; then
|
|
if [[ ${#selector_parts[@]} -eq 2 ]] ||
|
|
version_matches_series "${version}" "${selector_parts[2]}"; then
|
|
matches+=("${entry}")
|
|
fi
|
|
fi
|
|
done
|
|
|
|
if [[ ${#matches[@]} -ne 1 ]]; then
|
|
echo "Error: selector ${selector} matched ${#matches[@]} ABT_KERNELS entries." >&2
|
|
return 1
|
|
fi
|
|
resolved_kernel="${matches[0]}"
|
|
}
|
|
|
|
emit_regression_matrix() {
|
|
local selector kernel
|
|
local -a versions=()
|
|
local -A seen_selectors=()
|
|
|
|
for selector in ${GITHUB_REGRESSION_KERNEL_SELECTORS}; do
|
|
if [[ -n "${seen_selectors[${selector}]+present}" ]]; then
|
|
echo "Error: duplicate regression selector: ${selector}" >&2
|
|
return 1
|
|
fi
|
|
seen_selectors["${selector}"]=1
|
|
resolve_kernel "${selector}" || return 1
|
|
kernel="${resolved_kernel}"
|
|
versions+=("${kernel}")
|
|
done
|
|
|
|
printf '%s\n' "${versions[@]}" |
|
|
jq -Rsc 'split("\n") | map(select(length > 0)) | {version: .}'
|
|
}
|
|
|
|
emit_rpm_matrix() {
|
|
local line target selector name base_image kernel_package kernel_repository extra
|
|
local kernel kernel_version row
|
|
local -a rows=()
|
|
local -A seen_targets=() seen_selectors=()
|
|
|
|
while IFS= read -r line; do
|
|
[[ -n "${line}" ]] || continue
|
|
IFS='|' read -r target selector name base_image kernel_package \
|
|
kernel_repository extra <<<"${line}"
|
|
if [[ -z "${target}" || -z "${selector}" || -z "${name}" ||
|
|
-z "${base_image}" || -z "${kernel_package}" || -n "${extra:-}" ]]; then
|
|
echo "Error: invalid RPM target: ${line}" >&2
|
|
return 1
|
|
fi
|
|
if [[ -n "${seen_targets[${target}]+present}" ]]; then
|
|
echo "Error: duplicate RPM target: ${target}" >&2
|
|
return 1
|
|
fi
|
|
if [[ -n "${seen_selectors[${selector}]+present}" ]]; then
|
|
echo "Error: duplicate RPM selector: ${selector}" >&2
|
|
return 1
|
|
fi
|
|
seen_targets["${target}"]=1
|
|
seen_selectors["${selector}"]=1
|
|
|
|
resolve_kernel "${selector}" || return 1
|
|
kernel="${resolved_kernel}"
|
|
kernel_version="${kernel%%^*}"
|
|
row="$(
|
|
jq -cn \
|
|
--arg name "${name}" \
|
|
--arg target "${target}" \
|
|
--arg base_image "${base_image}" \
|
|
--arg kernel_package "${kernel_package}" \
|
|
--arg kernel_version "${kernel_version}" \
|
|
--arg kernel_repository "${kernel_repository}" \
|
|
'{name: $name, target: $target, base_image: $base_image,
|
|
kernel_package: $kernel_package,
|
|
kernel_version: $kernel_version,
|
|
kernel_repository: $kernel_repository}'
|
|
)" || return 1
|
|
rows+=("${row}")
|
|
done <<<"${GITHUB_RPM_TARGETS}"
|
|
|
|
printf '%s\n' "${rows[@]}" | jq -cs '{include: .}'
|
|
}
|
|
|
|
emit_rpm_field() {
|
|
local target="$1"
|
|
local field="$2"
|
|
local matrix
|
|
|
|
case "${field}" in
|
|
name|base_image|kernel_package|kernel_version|kernel_repository)
|
|
;;
|
|
*)
|
|
echo "Error: unsupported RPM matrix field: ${field}" >&2
|
|
return 1
|
|
;;
|
|
esac
|
|
|
|
matrix="$(emit_rpm_matrix)" || return 1
|
|
jq -er \
|
|
--arg target "${target}" \
|
|
--arg field "${field}" '
|
|
[.include[] | select(.target == $target)] |
|
|
if length == 1 then .[0][$field]
|
|
else error("RPM target \($target) matched \(length) entries") end
|
|
' <<<"${matrix}"
|
|
}
|
|
|
|
case "${1:-}" in
|
|
regression) emit_regression_matrix ;;
|
|
rpm) emit_rpm_matrix ;;
|
|
rpm-field)
|
|
if [[ $# -ne 3 ]]; then
|
|
echo "Usage: $0 rpm-field <target> <field>" >&2
|
|
exit 2
|
|
fi
|
|
emit_rpm_field "$2" "$3"
|
|
;;
|
|
*)
|
|
echo "Usage: $0 {regression|rpm|rpm-field}" >&2
|
|
exit 2
|
|
;;
|
|
esac
|