#!/usr/bin/env bash set -euo pipefail export PATH="/run/current-system/sw/bin:/usr/bin:/bin:${PATH}" SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" SOURCE_FLAKE_ROOT="${ULTRACLOUD_BAREMETAL_E2E_SOURCE_FLAKE_ROOT:-$(cd "${SCRIPT_DIR}/../.." && pwd)}" TASK_ID="0de75570-dabd-471b-95fe-5898c54e2e8c" WORK_ROOT="${ULTRACLOUD_WORK_ROOT:-${PWD}/work}" LOG_ROOT="${1:-${ULTRACLOUD_BAREMETAL_E2E_LOG_ROOT:-${WORK_ROOT}/baremetal-iso-e2e/${TASK_ID}}}" STATE_DIR="${ULTRACLOUD_BAREMETAL_STATE_DIR:-${LOG_ROOT}/state}" log() { printf '[baremetal-iso-e2e-runner] %s\n' "$*" } die() { printf '[baremetal-iso-e2e-runner] ERROR: %s\n' "$*" >&2 exit 1 } host_cpu_count() { local count count="$(getconf _NPROCESSORS_ONLN 2>/dev/null || nproc 2>/dev/null || echo 1)" if [[ ! "${count}" =~ ^[0-9]+$ ]] || (( count < 1 )); then count=1 fi printf '%s\n' "${count}" } default_local_nix_max_jobs() { local cpu_count="$1" if (( cpu_count <= 2 )); then printf '1\n' return 0 fi printf '%s\n' "$(( (cpu_count + 1) / 2 ))" } default_local_nix_build_cores() { local cpu_count="$1" local max_jobs="$2" local build_cores=1 if (( max_jobs > 0 )); then build_cores="$(( cpu_count / max_jobs ))" fi if (( build_cores < 1 )); then build_cores=1 fi printf '%s\n' "${build_cores}" } append_nix_config_line() { local line="$1" if [[ -n "${NIX_CONFIG:-}" ]]; then NIX_CONFIG+=$'\n' fi NIX_CONFIG+="${line}" } host_nested_param_path() { if [[ -f /sys/module/kvm_intel/parameters/nested ]]; then printf '%s\n' /sys/module/kvm_intel/parameters/nested elif [[ -f /sys/module/kvm_amd/parameters/nested ]]; then printf '%s\n' /sys/module/kvm_amd/parameters/nested fi } require_baremetal_kvm_host() { [[ -e /dev/kvm ]] || die "/dev/kvm is missing; baremetal-iso-e2e requires host KVM" [[ -r /dev/kvm && -w /dev/kvm ]] || die "/dev/kvm is not readable and writable for $(id -un)" } prepare_runtime_dirs() { local cpu_count default_max_jobs default_build_cores cpu_count="$(host_cpu_count)" default_max_jobs="$(default_local_nix_max_jobs "${cpu_count}")" default_build_cores="$(default_local_nix_build_cores "${cpu_count}" "${default_max_jobs}")" export ULTRACLOUD_WORK_ROOT="${WORK_ROOT}" export TMPDIR="${TMPDIR:-${WORK_ROOT}/tmp}" export XDG_CACHE_HOME="${XDG_CACHE_HOME:-${WORK_ROOT}/xdg-cache}" export ULTRACLOUD_LOCAL_NIX_MAX_JOBS="${ULTRACLOUD_LOCAL_NIX_MAX_JOBS:-${default_max_jobs}}" export ULTRACLOUD_LOCAL_NIX_BUILD_CORES="${ULTRACLOUD_LOCAL_NIX_BUILD_CORES:-${default_build_cores}}" export ULTRACLOUD_BAREMETAL_STATE_DIR="${STATE_DIR}" export ULTRACLOUD_BAREMETAL_FORCE_TCG=0 export ULTRACLOUD_REPO_ROOT="${SOURCE_FLAKE_ROOT}" export ULTRACLOUD_BAREMETAL_PROOF_MODEL="${ULTRACLOUD_BAREMETAL_PROOF_MODEL:-materialized-check-runner}" append_nix_config_line "builders =" append_nix_config_line "max-jobs = ${ULTRACLOUD_LOCAL_NIX_MAX_JOBS}" append_nix_config_line "cores = ${ULTRACLOUD_LOCAL_NIX_BUILD_CORES}" append_nix_config_line "experimental-features = nix-command flakes" append_nix_config_line "warn-dirty = false" export NIX_CONFIG mkdir -p "${TMPDIR}" "${XDG_CACHE_HOME}" "${WORK_ROOT}" "${LOG_ROOT}" "${STATE_DIR}" } git_value() { local repo_root="$1" shift if git -C "${repo_root}" rev-parse --is-inside-work-tree >/dev/null 2>&1; then git -C "${repo_root}" "$@" else printf 'unavailable\n' fi } capture_environment() { { printf 'task_id=%s\n' "${TASK_ID}" printf 'execution_model=%s\n' "${ULTRACLOUD_BAREMETAL_PROOF_MODEL}" printf 'started_at=%s\n' "$(date -Is)" printf 'source_flake_root=%s\n' "${SOURCE_FLAKE_ROOT}" printf 'invoked_from=%s\n' "${PWD}" printf 'work_root=%s\n' "${WORK_ROOT}" printf 'log_root=%s\n' "${LOG_ROOT}" printf 'state_dir=%s\n' "${STATE_DIR}" printf 'source_branch=%s\n' "$(git_value "${PWD}" branch --show-current)" printf 'source_commit=%s\n' "$(git_value "${PWD}" rev-parse HEAD)" printf 'host_cpu_count=%s\n' "$(host_cpu_count)" printf 'ultracloud_local_nix_max_jobs=%s\n' "${ULTRACLOUD_LOCAL_NIX_MAX_JOBS}" printf 'ultracloud_local_nix_build_cores=%s\n' "${ULTRACLOUD_LOCAL_NIX_BUILD_CORES}" printf 'tmpdir=%s\n' "${TMPDIR}" printf 'xdg_cache_home=%s\n' "${XDG_CACHE_HOME}" printf 'nix_version=%s\n' "$(nix --version)" printf 'nix_builders=%s\n' "$(nix config show builders 2>/dev/null | awk -F' = ' 'NR==1 { print $2 }')" printf 'kvm_present=%s\n' "$([[ -e /dev/kvm ]] && echo yes || echo no)" printf 'kvm_access=%s\n' "$([[ -r /dev/kvm && -w /dev/kvm ]] && echo rw || echo no)" if [[ -e /dev/kvm ]]; then printf 'kvm_stat=%s\n' "$(stat -c '%A %U %G %t:%T' /dev/kvm)" fi local nested_path nested_path="$(host_nested_param_path || true)" if [[ -n "${nested_path}" ]]; then printf 'nested_param_path=%s\n' "${nested_path}" printf 'nested_param_value=%s\n' "$(<"${nested_path}")" fi } >"${LOG_ROOT}/environment.txt" } run_case() { local name="$1" local timeout_secs="$2" shift 2 local logfile="${LOG_ROOT}/${name}.log" local metafile="${LOG_ROOT}/${name}.meta" local started_at ended_at rc started_at="$(date -Is)" printf 'name=%s\n' "${name}" >"${metafile}" printf 'started_at=%s\n' "${started_at}" >>"${metafile}" printf 'timeout_secs=%s\n' "${timeout_secs}" >>"${metafile}" printf 'command=' >>"${metafile}" printf '%q ' "$@" >>"${metafile}" printf '\n' >>"${metafile}" log "running ${name}: $*" set +e timeout --signal=TERM --kill-after=120 "${timeout_secs}" "$@" 2>&1 | tee "${logfile}" rc=${PIPESTATUS[0]} set -e ended_at="$(date -Is)" printf 'ended_at=%s\n' "${ended_at}" >>"${metafile}" printf 'exit_code=%s\n' "${rc}" >>"${metafile}" if (( rc == 124 )); then log "${name} timed out after ${timeout_secs}s" elif (( rc == 0 )); then log "${name} passed" else log "${name} failed with exit ${rc}" fi return "${rc}" } main() { prepare_runtime_dirs require_baremetal_kvm_host capture_environment run_case baremetal-iso-e2e 21600 \ env \ ULTRACLOUD_REPO_ROOT="${SOURCE_FLAKE_ROOT}" \ ULTRACLOUD_WORK_ROOT="${WORK_ROOT}" \ ULTRACLOUD_BAREMETAL_STATE_DIR="${STATE_DIR}" \ ULTRACLOUD_BAREMETAL_FORCE_TCG=0 \ ULTRACLOUD_BAREMETAL_PROOF_MODEL="${ULTRACLOUD_BAREMETAL_PROOF_MODEL}" \ bash "${SOURCE_FLAKE_ROOT}/nix/test-cluster/verify-baremetal-iso.sh" log "baremetal-iso-e2e exact proof passed; logs in ${LOG_ROOT}" } main "$@"