refactor: harden diagnostics and consolidate runtime code

This commit is contained in:
Mikhail Chusavitin
2026-09-01 13:01:28 +03:00
parent ac4bc0b2b7
commit 0a6ca8ba0f
49 changed files with 1441 additions and 837 deletions
+26 -21
View File
@@ -77,6 +77,7 @@ export GOCACHE GOMODCACHE
# Keep the entrypoint focused on build orchestration. These libraries only
# define helpers; stateful logging is loaded after its output paths are known.
. "${BUILDER_DIR}/lib/iso-validation.sh"
. "${BUILDER_DIR}/lib/template.sh"
. "${BUILDER_DIR}/lib/bootloader.sh"
. "${BUILDER_DIR}/lib/fast-path.sh"
@@ -158,11 +159,19 @@ sync_builder_workdir() {
PROJECT_VERSION_EFFECTIVE="$(resolve_project_version)"
if ! validate_project_version "${PROJECT_VERSION_EFFECTIVE}"; then
echo "ERROR: project version must start and end with an ASCII letter or digit and contain only letters, digits, dots, and hyphens: ${PROJECT_VERSION_EFFECTIVE}" >&2
exit 1
fi
SQUASHFS_FILENAME="filesystem-v${PROJECT_VERSION_EFFECTIVE}.squashfs"
ISO_BASENAME="easy-bee-${BUILD_VARIANT}-v${PROJECT_VERSION_EFFECTIVE}-amd64"
# Hostname baked into the live image: same product+version scheme as
# ISO_BASENAME/SQUASHFS_FILENAME, but hostname labels don't allow dots.
BEE_HOSTNAME="easy-bee-${BUILD_VARIANT}-v$(printf '%s' "${PROJECT_VERSION_EFFECTIVE}" | tr '.' '-')"
if [ "${#BEE_HOSTNAME}" -gt 63 ]; then
echo "ERROR: derived hostname exceeds the 63-byte DNS label limit: ${BEE_HOSTNAME}" >&2
exit 1
fi
# Versioned output directory: dist/easy-bee-v4.1/ - all final artifacts live here.
OUT_DIR="${DIST_DIR}/release/easy-bee-v${PROJECT_VERSION_EFFECTIVE}"
ISO_VERSION_LABEL_TOKEN="$(printf '%s' "${PROJECT_VERSION_EFFECTIVE}" | tr '[:lower:].-' '[:upper:]__')"
@@ -538,9 +547,7 @@ fi
# Patch motd with build info
BEE_BUILD_INFO="${BUILD_DATE} git:${GIT_COMMIT} debian:${DEBIAN_VERSION} ${GPU_BUILD_INFO}"
if [ -f "${OVERLAY_STAGE_DIR}/etc/motd" ]; then
sed "s/%%BUILD_INFO%%/${BEE_BUILD_INFO}/" "${OVERLAY_STAGE_DIR}/etc/motd" \
> "${OVERLAY_STAGE_DIR}/etc/motd.patched"
mv "${OVERLAY_STAGE_DIR}/etc/motd.patched" "${OVERLAY_STAGE_DIR}/etc/motd"
replace_literal_in_file "${OVERLAY_STAGE_DIR}/etc/motd" "%%BUILD_INFO%%" "${BEE_BUILD_INFO}"
fi
# --- copy variant-specific package list, remove all other variant lists ---
@@ -568,26 +575,24 @@ fi
# --- substitute version placeholders in package list and archive ---
if [ "$BEE_GPU_VENDOR" = "nvidia" ]; then
sed -i \
-e "s/%%NVIDIA_FABRICMANAGER_VERSION%%/${NVIDIA_FABRICMANAGER_VERSION}/g" \
-e "s/%%DCGM_VERSION%%/${DCGM_VERSION}/g" \
"${BUILD_WORK_DIR}/config/package-lists/bee-gpu.list.chroot"
replace_literal_in_file "${BUILD_WORK_DIR}/config/package-lists/bee-gpu.list.chroot" \
"%%NVIDIA_FABRICMANAGER_VERSION%%" "${NVIDIA_FABRICMANAGER_VERSION}"
replace_literal_in_file "${BUILD_WORK_DIR}/config/package-lists/bee-gpu.list.chroot" \
"%%DCGM_VERSION%%" "${DCGM_VERSION}"
elif [ "$BEE_GPU_VENDOR" = "amd" ]; then
sed -i \
-e "s/%%ROCM_VERSION%%/${ROCM_VERSION}/g" \
-e "s/%%ROCM_SMI_VERSION%%/${ROCM_SMI_VERSION}/g" \
-e "s/%%ROCM_BANDWIDTH_TEST_VERSION%%/${ROCM_BANDWIDTH_TEST_VERSION}/g" \
-e "s/%%ROCM_VALIDATION_SUITE_VERSION%%/${ROCM_VALIDATION_SUITE_VERSION}/g" \
-e "s/%%ROCBLAS_VERSION%%/${ROCBLAS_VERSION}/g" \
-e "s/%%ROCRAND_VERSION%%/${ROCRAND_VERSION}/g" \
-e "s/%%HIP_RUNTIME_AMD_VERSION%%/${HIP_RUNTIME_AMD_VERSION}/g" \
-e "s/%%HIPBLASLT_VERSION%%/${HIPBLASLT_VERSION}/g" \
-e "s/%%COMGR_VERSION%%/${COMGR_VERSION}/g" \
"${BUILD_WORK_DIR}/config/package-lists/bee-gpu.list.chroot"
gpu_package_list="${BUILD_WORK_DIR}/config/package-lists/bee-gpu.list.chroot"
replace_literal_in_file "$gpu_package_list" "%%ROCM_VERSION%%" "${ROCM_VERSION}"
replace_literal_in_file "$gpu_package_list" "%%ROCM_SMI_VERSION%%" "${ROCM_SMI_VERSION}"
replace_literal_in_file "$gpu_package_list" "%%ROCM_BANDWIDTH_TEST_VERSION%%" "${ROCM_BANDWIDTH_TEST_VERSION}"
replace_literal_in_file "$gpu_package_list" "%%ROCM_VALIDATION_SUITE_VERSION%%" "${ROCM_VALIDATION_SUITE_VERSION}"
replace_literal_in_file "$gpu_package_list" "%%ROCBLAS_VERSION%%" "${ROCBLAS_VERSION}"
replace_literal_in_file "$gpu_package_list" "%%ROCRAND_VERSION%%" "${ROCRAND_VERSION}"
replace_literal_in_file "$gpu_package_list" "%%HIP_RUNTIME_AMD_VERSION%%" "${HIP_RUNTIME_AMD_VERSION}"
replace_literal_in_file "$gpu_package_list" "%%HIPBLASLT_VERSION%%" "${HIPBLASLT_VERSION}"
replace_literal_in_file "$gpu_package_list" "%%COMGR_VERSION%%" "${COMGR_VERSION}"
if [ -f "${BUILD_WORK_DIR}/config/archives/rocm.list.chroot" ]; then
sed -i \
-e "s/%%ROCM_VERSION%%/${ROCM_VERSION}/g" \
"${BUILD_WORK_DIR}/config/archives/rocm.list.chroot"
replace_literal_in_file "${BUILD_WORK_DIR}/config/archives/rocm.list.chroot" \
"%%ROCM_VERSION%%" "${ROCM_VERSION}"
fi
fi
+8
View File
@@ -85,6 +85,14 @@ render_bootloader_template() {
initrd_placeholder="$7"
initrd="$8"
for required_placeholder in \
"@VERSION@" \
"$kernel_placeholder" \
"@APPEND_LIVE@" \
"$initrd_placeholder"; do
require_template_placeholder "$template" "$required_placeholder" || return 1
done
BEE_RENDER_VERSION="$version" \
BEE_RENDER_KERNEL_PLACEHOLDER="$kernel_placeholder" \
BEE_RENDER_KERNEL="$kernel" \
+5 -2
View File
@@ -359,9 +359,12 @@ validate_live_cmdline_params() {
bad = 1
}
$1 == command && has("boot=live") {
$1 == command {
live_entries++
if (!has("boot=live")) {
reject("missing boot=live")
}
if (!has("udev.children_max=1")) {
reject("missing udev.children_max=1")
}
@@ -432,7 +435,7 @@ validate_iso_live_boot_entries() {
exit 1
}
if grep -q '@APPEND_LIVE@\|@KERNEL_LIVE@\|@INITRD_LIVE@' "$grub_cfg" "$isolinux_cfg"; then
if grep -Eq '@[A-Z][A-Z_]*@' "$grub_cfg" "$isolinux_cfg"; then
echo "ERROR: unresolved live-build placeholders remain in ISO bootloader config" >&2
rm -f "$grub_cfg" "$isolinux_cfg"
exit 1
+55
View File
@@ -0,0 +1,55 @@
require_template_placeholder() {
file="$1"
placeholder="$2"
if [ -z "$placeholder" ]; then
echo "ERROR: template placeholder must not be empty" >&2
return 1
fi
if ! BEE_TEMPLATE_PLACEHOLDER="$placeholder" awk '
index($0, ENVIRON["BEE_TEMPLATE_PLACEHOLDER"]) { found=1 }
END { exit found ? 0 : 1 }
' "$file"; then
echo "ERROR: required placeholder $placeholder is missing from $file" >&2
return 1
fi
}
replace_literal_in_file() {
file="$1"
placeholder="$2"
replacement="$3"
require_template_placeholder "$file" "$placeholder" || return 1
tmp="$(mktemp "${TMPDIR:-/tmp}/bee-template.XXXXXX")"
if BEE_TEMPLATE_PLACEHOLDER="$placeholder" \
BEE_TEMPLATE_REPLACEMENT="$replacement" \
awk '
function replace_literal(text, needle, value, at) {
while ((at = index(text, needle)) != 0) {
text = substr(text, 1, at - 1) value substr(text, at + length(needle))
}
return text
}
{
print replace_literal($0,
ENVIRON["BEE_TEMPLATE_PLACEHOLDER"],
ENVIRON["BEE_TEMPLATE_REPLACEMENT"])
}
' "$file" > "$tmp" && cat "$tmp" > "$file"; then
status=0
else
status=$?
fi
rm -f "$tmp"
return "$status"
}
validate_project_version() {
version="$1"
case "$version" in
""|[!A-Za-z0-9]*|*[!A-Za-z0-9]|*[!A-Za-z0-9.-]*)
return 1
;;
esac
return 0
}
+42
View File
@@ -11,8 +11,37 @@ LOG_DIR="$TEST_ROOT/log"
mkdir -p "$LOG_DIR"
. "$BUILDER_DIR/lib/iso-validation.sh"
. "$BUILDER_DIR/lib/template.sh"
. "$BUILDER_DIR/lib/bootloader.sh"
literal_file="$TEST_ROOT/literal-file"
printf '%s\n' 'before %%VALUE%% after %%VALUE%%' > "$literal_file"
replace_literal_in_file "$literal_file" '%%VALUE%%' 'a&b#c\\d'
if [ "$(cat "$literal_file")" != 'before a&b#c\\d after a&b#c\\d' ]; then
echo "ERROR: generic literal replacement changed replacement characters" >&2
exit 1
fi
if replace_literal_in_file "$literal_file" '' value >/dev/null 2>&1; then
echo "ERROR: generic literal replacement accepted an empty placeholder" >&2
exit 1
fi
if replace_literal_in_file "$literal_file" '%%MISSING%%' value >/dev/null 2>&1; then
echo "ERROR: generic literal replacement accepted a missing placeholder" >&2
exit 1
fi
for valid_version in 13 13.0 v13.0-2-gabcdef0-dirty; do
if ! validate_project_version "$valid_version"; then
echo "ERROR: rejected valid project version: $valid_version" >&2
exit 1
fi
done
for invalid_version in '' '.13' '13.' '13/0' '13_0' '13 0' '13&0'; do
if validate_project_version "$invalid_version"; then
echo "ERROR: accepted unsafe project version: $invalid_version" >&2
exit 1
fi
done
literal_template="$TEST_ROOT/literal-template"
literal_output="$TEST_ROOT/literal-output"
printf '%s\n' '@VERSION@ @KERNEL@ @APPEND_LIVE@ @INITRD@' > "$literal_template"
@@ -23,6 +52,11 @@ if [ "$(cat "$literal_output")" != "$literal_expected" ]; then
echo "ERROR: bootloader renderer changed literal replacement characters" >&2
exit 1
fi
if render_bootloader_template "$literal_template" "$literal_output" \
'13.0-test' '@MISSING_KERNEL@' '/live/vmlinuz' 'boot=live' '@INITRD@' '/live/initrd.img' >/dev/null 2>&1; then
echo "ERROR: bootloader renderer accepted a missing required placeholder" >&2
exit 1
fi
rendered_grub="$TEST_ROOT/grub.cfg"
rendered_isolinux="$TEST_ROOT/live.cfg"
@@ -49,6 +83,14 @@ if validate_live_cmdline_params "$missing_serialization" linux GRUB "$BEE_ISO_VO
exit 1
fi
missing_boot_live="$TEST_ROOT/missing-boot-live.cfg"
awk 'BEGIN { removed=0 } /^ linux / && !removed { sub(/ boot=live/, ""); removed=1 } { print }' \
"$rendered_grub" > "$missing_boot_live"
if validate_live_cmdline_params "$missing_boot_live" linux GRUB "$BEE_ISO_VOLUME" >/dev/null 2>&1; then
echo "ERROR: validator ignored a live entry without boot=live" >&2
exit 1
fi
CACHE_ROOT="$TEST_ROOT/cache"
BUILD_VARIANT="test"
BUILD_WORK_DIR="$TEST_ROOT/work"