diff --git a/iso/builder/build.sh b/iso/builder/build.sh index 072d11a..c180a29 100755 --- a/iso/builder/build.sh +++ b/iso/builder/build.sh @@ -111,63 +111,192 @@ resolve_iso_version() { resolve_audit_version } +dump_memtest_debug() { + phase="$1" + lb_dir="${2:-}" + iso_path="${3:-}" + phase_slug="$(printf '%s' "${phase}" | tr ' /' '__')" + memtest_log="${LOG_DIR:-}/memtest-${phase_slug}.log" + + ( + echo "=== memtest debug: ${phase} ===" + + echo "-- auto/config --" + if [ -f "${BUILDER_DIR}/auto/config" ]; then + grep -n -- '--memtest' "${BUILDER_DIR}/auto/config" || echo " (no --memtest line found)" + else + echo " (missing ${BUILDER_DIR}/auto/config)" + fi + + echo "-- source bootloader templates --" + for cfg in \ + "${BUILDER_DIR}/config/bootloaders/grub-pc/grub.cfg" \ + "${BUILDER_DIR}/config/bootloaders/isolinux/live.cfg.in"; do + if [ -f "$cfg" ]; then + echo " file: $cfg" + grep -n 'Memory Test\|memtest' "$cfg" || echo " (no memtest lines)" + fi + done + + if [ -n "$lb_dir" ] && [ -d "$lb_dir" ]; then + echo "-- live-build workdir package lists --" + for pkg in \ + "$lb_dir/config/package-lists/bee.list.chroot" \ + "$lb_dir/config/package-lists/bee-gpu.list.chroot" \ + "$lb_dir/config/package-lists/bee-nvidia.list.chroot"; do + if [ -f "$pkg" ]; then + echo " file: $pkg" + grep -n 'memtest' "$pkg" || echo " (no memtest lines)" + fi + done + + echo "-- live-build chroot/boot --" + if [ -d "$lb_dir/chroot/boot" ]; then + find "$lb_dir/chroot/boot" -maxdepth 1 -name 'memtest*' -print | sed 's/^/ /' || true + else + echo " (missing $lb_dir/chroot/boot)" + fi + + echo "-- live-build binary/boot --" + if [ -d "$lb_dir/binary/boot" ]; then + find "$lb_dir/binary/boot" -maxdepth 1 -name 'memtest*' -print | sed 's/^/ /' || true + else + echo " (missing $lb_dir/binary/boot)" + fi + + echo "-- live-build package cache --" + if [ -d "$lb_dir/cache/packages.chroot" ]; then + find "$lb_dir/cache/packages.chroot" -maxdepth 1 -name 'memtest86+*.deb' -print | sed 's/^/ /' || true + else + echo " (missing $lb_dir/cache/packages.chroot)" + fi + fi + + if [ -n "$iso_path" ] && [ -f "$iso_path" ]; then + echo "-- ISO memtest files --" + bsdtar -tf "$iso_path" | grep 'memtest' | sed 's/^/ /' || echo " (no memtest files in ISO)" + + echo "-- ISO GRUB memtest lines --" + bsdtar -xOf "$iso_path" boot/grub/grub.cfg 2>/dev/null | grep -n 'Memory Test\|memtest' || echo " (no memtest lines in boot/grub/grub.cfg)" + + echo "-- ISO isolinux memtest lines --" + bsdtar -xOf "$iso_path" isolinux/live.cfg 2>/dev/null | grep -n 'Memory Test\|memtest' || echo " (no memtest lines in isolinux/live.cfg)" + fi + + echo "=== end memtest debug: ${phase} ===" + ) | { + if [ -n "${LOG_DIR:-}" ] && [ -d "${LOG_DIR}" ]; then + tee "${memtest_log}" + else + cat + fi + } +} + +memtest_fail() { + msg="$1" + iso_path="${2:-}" + echo "ERROR: ${msg}" >&2 + dump_memtest_debug "failure" "${LB_DIR:-}" "$iso_path" >&2 + exit 1 +} + validate_iso_memtest() { iso_path="$1" echo "=== validating memtest in ISO ===" - [ -f "$iso_path" ] || { echo "ERROR: ISO not found for validation: $iso_path" >&2; exit 1; } - command -v bsdtar >/dev/null 2>&1 || { echo "ERROR: bsdtar is required for ISO validation" >&2; exit 1; } + [ -f "$iso_path" ] || memtest_fail "ISO not found for validation: $iso_path" "$iso_path" + command -v bsdtar >/dev/null 2>&1 || memtest_fail "bsdtar is required for ISO validation" "$iso_path" bsdtar -tf "$iso_path" | grep -q '^boot/memtest86+x64\.bin$' || { - echo "ERROR: memtest BIOS binary missing in ISO: boot/memtest86+x64.bin" >&2 - exit 1 + memtest_fail "memtest BIOS binary missing in ISO: boot/memtest86+x64.bin" "$iso_path" } bsdtar -tf "$iso_path" | grep -q '^boot/memtest86+x64\.efi$' || { - echo "ERROR: memtest EFI binary missing in ISO: boot/memtest86+x64.efi" >&2 - exit 1 + memtest_fail "memtest EFI binary missing in ISO: boot/memtest86+x64.efi" "$iso_path" } grub_cfg="$(mktemp)" isolinux_cfg="$(mktemp)" - trap 'rm -f "$grub_cfg" "$isolinux_cfg"' EXIT INT TERM - bsdtar -xOf "$iso_path" boot/grub/grub.cfg > "$grub_cfg" || { - echo "ERROR: failed to extract boot/grub/grub.cfg from ISO" >&2 - exit 1 - } - bsdtar -xOf "$iso_path" isolinux/live.cfg > "$isolinux_cfg" || { - echo "ERROR: failed to extract isolinux/live.cfg from ISO" >&2 - exit 1 - } + bsdtar -xOf "$iso_path" boot/grub/grub.cfg > "$grub_cfg" || memtest_fail "failed to extract boot/grub/grub.cfg from ISO" "$iso_path" + bsdtar -xOf "$iso_path" isolinux/live.cfg > "$isolinux_cfg" || memtest_fail "failed to extract isolinux/live.cfg from ISO" "$iso_path" grep -q 'Memory Test (memtest86+)' "$grub_cfg" || { - echo "ERROR: GRUB menu entry for memtest is missing" >&2 - exit 1 + memtest_fail "GRUB menu entry for memtest is missing" "$iso_path" } grep -q '/boot/memtest86+x64\.efi' "$grub_cfg" || { - echo "ERROR: GRUB memtest EFI path is missing" >&2 - exit 1 + memtest_fail "GRUB memtest EFI path is missing" "$iso_path" } grep -q '/boot/memtest86+x64\.bin' "$grub_cfg" || { - echo "ERROR: GRUB memtest BIOS path is missing" >&2 - exit 1 + memtest_fail "GRUB memtest BIOS path is missing" "$iso_path" } grep -q 'Memory Test (memtest86+)' "$isolinux_cfg" || { - echo "ERROR: isolinux menu entry for memtest is missing" >&2 - exit 1 + memtest_fail "isolinux menu entry for memtest is missing" "$iso_path" } grep -q '/boot/memtest86+x64\.bin' "$isolinux_cfg" || { - echo "ERROR: isolinux memtest path is missing" >&2 - exit 1 + memtest_fail "isolinux memtest path is missing" "$iso_path" } rm -f "$grub_cfg" "$isolinux_cfg" - trap - EXIT INT TERM echo "=== memtest validation OK ===" } AUDIT_VERSION_EFFECTIVE="$(resolve_audit_version)" ISO_VERSION_EFFECTIVE="$(resolve_iso_version)" +ISO_BASENAME="easy-bee-${BEE_GPU_VENDOR}-v${ISO_VERSION_EFFECTIVE}-amd64" +LOG_DIR="${DIST_DIR}/${ISO_BASENAME}.logs" +LOG_ARCHIVE="${DIST_DIR}/${ISO_BASENAME}.logs.tar.gz" +ISO_OUT="${DIST_DIR}/${ISO_BASENAME}.iso" +LOG_OUT="${LOG_DIR}/build.log" + +cleanup_build_log() { + status="${1:-$?}" + trap - EXIT INT TERM HUP + + if [ "${BUILD_LOG_ACTIVE:-0}" = "1" ]; then + BUILD_LOG_ACTIVE=0 + exec 1>&3 2>&4 + exec 3>&- 4>&- + if [ -n "${BUILD_TEE_PID:-}" ]; then + wait "${BUILD_TEE_PID}" 2>/dev/null || true + fi + rm -f "${BUILD_LOG_PIPE}" + fi + + if [ -n "${LOG_DIR:-}" ] && [ -d "${LOG_DIR}" ] && command -v tar >/dev/null 2>&1; then + rm -f "${LOG_ARCHIVE}" + tar -czf "${LOG_ARCHIVE}" -C "${DIST_DIR}" "$(basename "${LOG_DIR}")" 2>/dev/null || true + fi + + exit "${status}" +} + +start_build_log() { + command -v tee >/dev/null 2>&1 || { + echo "ERROR: tee is required for build logging" >&2 + exit 1 + } + + rm -rf "${LOG_DIR}" + rm -f "${LOG_ARCHIVE}" + mkdir -p "${LOG_DIR}" + BUILD_LOG_PIPE="$(mktemp -u "${TMPDIR:-/tmp}/bee-build-log.XXXXXX")" + mkfifo "${BUILD_LOG_PIPE}" + + exec 3>&1 4>&2 + tee "${LOG_OUT}" < "${BUILD_LOG_PIPE}" & + BUILD_TEE_PID=$! + exec > "${BUILD_LOG_PIPE}" 2>&1 + BUILD_LOG_ACTIVE=1 + + trap 'cleanup_build_log "$?"' EXIT INT TERM HUP + + echo "=== build log dir: ${LOG_DIR} ===" + echo "=== build log: ${LOG_OUT} ===" + echo "=== build log archive: ${LOG_ARCHIVE} ===" +} + +start_build_log # Auto-detect kernel ABI: refresh apt index, then query current linux-image-amd64 dependency. # If headers for the detected ABI are not yet installed (kernel updated since image build), @@ -564,6 +693,7 @@ export BEE_GPU_VENDOR_UPPER cd "${LB_DIR}" lb clean 2>&1 | tail -3 lb config 2>&1 | tail -5 +dump_memtest_debug "pre-build" "${LB_DIR}" lb build 2>&1 # --- persist deb package cache back to shared location --- @@ -575,8 +705,8 @@ fi # live-build outputs live-image-amd64.hybrid.iso in LB_DIR ISO_RAW="${LB_DIR}/live-image-amd64.hybrid.iso" -ISO_OUT="${DIST_DIR}/easy-bee-${BEE_GPU_VENDOR}-v${ISO_VERSION_EFFECTIVE}-amd64.iso" if [ -f "$ISO_RAW" ]; then + dump_memtest_debug "post-build" "${LB_DIR}" "$ISO_RAW" validate_iso_memtest "$ISO_RAW" cp "$ISO_RAW" "$ISO_OUT" echo ""