cleanup_build_log() { status="${1:-$?}" trap - EXIT INT TERM HUP if [ "${STEP_LOG_ACTIVE:-0}" = "1" ]; then cleanup_step_log "${status}" || true fi 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 -rf "${BUILD_LOG_TMPDIR}" 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 "$(dirname "${LOG_DIR}")" "$(basename "${LOG_DIR}")" 2>/dev/null || true rm -rf "${LOG_DIR}" 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_TMPDIR="$(mktemp -d "${TMPDIR:-/tmp}/bee-build-log.XXXXXX")" BUILD_LOG_PIPE="${BUILD_LOG_TMPDIR}/pipe" 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} ===" } cleanup_step_log() { status="${1:-$?}" if [ "${STEP_LOG_ACTIVE:-0}" = "1" ]; then STEP_LOG_ACTIVE=0 exec 1>&5 2>&6 exec 5>&- 6>&- if [ -n "${STEP_TEE_PID:-}" ]; then wait "${STEP_TEE_PID}" 2>/dev/null || true fi rm -rf "${STEP_LOG_TMPDIR}" fi return "${status}" } run_step() { step_name="$1" step_slug="$2" shift 2 step_log="${LOG_DIR}/${step_slug}.log" echo "" echo "=== step: ${step_name} ===" echo "=== step log: ${step_log} ===" STEP_LOG_TMPDIR="$(mktemp -d "${TMPDIR:-/tmp}/bee-step-log.XXXXXX")" STEP_LOG_PIPE="${STEP_LOG_TMPDIR}/pipe" mkfifo "${STEP_LOG_PIPE}" exec 5>&1 6>&2 tee "${step_log}" < "${STEP_LOG_PIPE}" >&5 & STEP_TEE_PID=$! exec > "${STEP_LOG_PIPE}" 2>&1 STEP_LOG_ACTIVE=1 set +e "$@" step_status=$? set -e cleanup_step_log "${step_status}" if [ "${step_status}" -ne 0 ]; then echo "ERROR: step failed: ${step_name} (see ${step_log})" >&2 exit "${step_status}" fi echo "=== step OK: ${step_name} ===" } run_step_sh() { step_name="$1" step_slug="$2" step_script="$3" run_step "${step_name}" "${step_slug}" sh -c "${step_script}" } run_optional_step_sh() { step_name="$1" step_slug="$2" step_script="$3" if [ "${BEE_REQUIRE_MEMTEST:-0}" = "1" ]; then run_step_sh "${step_name}" "${step_slug}" "${step_script}" return 0 fi mkdir -p "${LOG_DIR}" 2>/dev/null || true step_log="${LOG_DIR}/${step_slug}.log" echo "" echo "=== optional step: ${step_name} ===" echo "=== optional step log: ${step_log} ===" set +e sh -c "${step_script}" > "${step_log}" 2>&1 step_status=$? set -e cat "${step_log}" if [ "${step_status}" -ne 0 ]; then echo "WARNING: optional step failed: ${step_name} (see ${step_log})" >&2 else echo "=== optional step OK: ${step_name} ===" fi }