#!/bin/sh set -eu repo_root=${PROJECT_ROOT:-$(pwd)} os_template=${OS_TEMPLATE:-$repo_root/tests/system/phase20-development-operating-system.scm.in} system_name=${SYSTEM_NAME:-phase20-operating-system} root_size=${ROOT_SIZE:-20g} metadata_target=${METADATA_OUT:-} root_authorized_key_file=${ROOT_AUTHORIZED_KEY_FILE:-$HOME/.ssh/id_ed25519.pub} root_ssh_private_key_file=${ROOT_SSH_PRIVATE_KEY_FILE:-$HOME/.ssh/id_ed25519} cleanup=0 if [ -n "${WORKDIR:-}" ]; then workdir=$WORKDIR mkdir -p "$workdir" else workdir=$(mktemp -d /tmp/fruix-phase20-self-hosted-native-build-xcpng.XXXXXX) cleanup=1 fi if [ "${KEEP_WORKDIR:-0}" -eq 1 ]; then cleanup=0 fi inner_metadata=$workdir/phase20-self-hosted-inner-metadata.txt metadata_file=$workdir/phase20-self-hosted-native-build-xcpng-metadata.txt action_cleanup() { if [ "$cleanup" -eq 1 ]; then rm -rf "$workdir" fi } trap action_cleanup EXIT INT TERM KEEP_WORKDIR=1 WORKDIR="$workdir/inner" METADATA_OUT="$inner_metadata" \ ROOT_AUTHORIZED_KEY_FILE="$root_authorized_key_file" \ ROOT_SSH_PRIVATE_KEY_FILE="$root_ssh_private_key_file" \ OS_TEMPLATE="$os_template" SYSTEM_NAME="$system_name" ROOT_SIZE="$root_size" \ "$repo_root/tests/system/run-phase20-development-environment-xcpng.sh" phase8_metadata=$(sed -n 's/^phase8_metadata=//p' "$inner_metadata") closure_path=$(sed -n 's/^closure_path=//p' "$inner_metadata") closure_base=$(sed -n 's/^closure_base=//p' "$inner_metadata") guest_ip=$(sed -n 's/^guest_ip=//p' "$inner_metadata") vm_id=$(sed -n 's/^vm_id=//p' "$inner_metadata") vdi_id=$(sed -n 's/^vdi_id=//p' "$inner_metadata") shepherd_pid=$(sed -n 's/^shepherd_pid=//p' "$inner_metadata") sshd_status=$(sed -n 's/^sshd_status=//p' "$inner_metadata") compat_prefix_shims=$(sed -n 's/^compat_prefix_shims=//p' "$inner_metadata") guile_module_smoke=$(sed -n 's/^guile_module_smoke=//p' "$inner_metadata") [ "$shepherd_pid" = 1 ] || { echo "shepherd was not PID 1" >&2; exit 1; } [ "$sshd_status" = running ] || { echo "sshd is not running" >&2; exit 1; } [ "$compat_prefix_shims" = absent ] || { echo "compatibility prefix shims reappeared" >&2; exit 1; } [ "$guile_module_smoke" = ok ] || { echo "guest Guile module smoke failed" >&2; exit 1; } ssh_guest() { ssh -i "$root_ssh_private_key_file" \ -o BatchMode=yes \ -o StrictHostKeyChecking=no \ -o UserKnownHostsFile=/dev/null \ -o ConnectTimeout=5 \ root@"$guest_ip" "$@" } guest_build_jobs=${GUEST_BUILD_JOBS:-$(ssh_guest 'sysctl -n hw.ncpu')} case "$guest_build_jobs" in ''|*[!0-9]*) echo "invalid guest build job count: $guest_build_jobs" >&2 exit 1 ;; esac ssh_guest '[ -x /usr/local/bin/fruix-self-hosted-native-build ]' ssh_guest '[ -L /usr/include ]' ssh_guest '[ -L /usr/share/mk ]' self_hosted_metadata=$(ssh_guest env FRUIX_SELF_HOSTED_NATIVE_BUILD_JOBS="$guest_build_jobs" /usr/local/bin/fruix-self-hosted-native-build) run_id=$(printf '%s\n' "$self_hosted_metadata" | sed -n 's/^run_id=//p') helper_version=$(printf '%s\n' "$self_hosted_metadata" | sed -n 's/^helper_version=//p') source_store=$(printf '%s\n' "$self_hosted_metadata" | sed -n 's/^source_store=//p') source_root=$(printf '%s\n' "$self_hosted_metadata" | sed -n 's/^source_root=//p') build_jobs=$(printf '%s\n' "$self_hosted_metadata" | sed -n 's/^build_jobs=//p') build_common=$(printf '%s\n' "$self_hosted_metadata" | sed -n 's/^build_common=//p') install_common=$(printf '%s\n' "$self_hosted_metadata" | sed -n 's/^install_common=//p') build_root=$(printf '%s\n' "$self_hosted_metadata" | sed -n 's/^build_root=//p') result_root=$(printf '%s\n' "$self_hosted_metadata" | sed -n 's/^result_root=//p') logdir=$(printf '%s\n' "$self_hosted_metadata" | sed -n 's/^logdir=//p') status_file=$(printf '%s\n' "$self_hosted_metadata" | sed -n 's/^status_file=//p') guest_metadata_file=$(printf '%s\n' "$self_hosted_metadata" | sed -n 's/^metadata_file=//p') world_stage=$(printf '%s\n' "$self_hosted_metadata" | sed -n 's/^world_stage=//p') kernel_stage=$(printf '%s\n' "$self_hosted_metadata" | sed -n 's/^kernel_stage=//p') kernel_artifact=$(printf '%s\n' "$self_hosted_metadata" | sed -n 's/^kernel_artifact=//p') headers_artifact=$(printf '%s\n' "$self_hosted_metadata" | sed -n 's/^headers_artifact=//p') bootloader_artifact=$(printf '%s\n' "$self_hosted_metadata" | sed -n 's/^bootloader_artifact=//p') latest_link=$(printf '%s\n' "$self_hosted_metadata" | sed -n 's/^latest_link=//p') root_df=$(printf '%s\n' "$self_hosted_metadata" | sed -n 's/^root_df=//p') build_root_size=$(printf '%s\n' "$self_hosted_metadata" | sed -n 's/^build_root_size=//p') result_root_size=$(printf '%s\n' "$self_hosted_metadata" | sed -n 's/^result_root_size=//p') kernel_artifact_size=$(printf '%s\n' "$self_hosted_metadata" | sed -n 's/^kernel_artifact_size=//p') headers_artifact_size=$(printf '%s\n' "$self_hosted_metadata" | sed -n 's/^headers_artifact_size=//p') bootloader_artifact_size=$(printf '%s\n' "$self_hosted_metadata" | sed -n 's/^bootloader_artifact_size=//p') sha_kernel=$(printf '%s\n' "$self_hosted_metadata" | sed -n 's/^sha_kernel=//p') sha_loader=$(printf '%s\n' "$self_hosted_metadata" | sed -n 's/^sha_loader=//p') sha_param=$(printf '%s\n' "$self_hosted_metadata" | sed -n 's/^sha_param=//p') buildworld_tail=$(printf '%s\n' "$self_hosted_metadata" | sed -n 's/^buildworld_tail=//p') buildkernel_tail=$(printf '%s\n' "$self_hosted_metadata" | sed -n 's/^buildkernel_tail=//p') installworld_tail=$(printf '%s\n' "$self_hosted_metadata" | sed -n 's/^installworld_tail=//p') distribution_tail=$(printf '%s\n' "$self_hosted_metadata" | sed -n 's/^distribution_tail=//p') installkernel_tail=$(printf '%s\n' "$self_hosted_metadata" | sed -n 's/^installkernel_tail=//p') self_hosted_native_build=$(printf '%s\n' "$self_hosted_metadata" | sed -n 's/^self_hosted_native_build=//p') status_value=$(ssh_guest "cat '$status_file'") latest_target=$(ssh_guest "readlink '$latest_link'") [ "$helper_version" = 2 ] || { echo "unexpected helper version: $helper_version" >&2; exit 1; } [ "$build_jobs" = "$guest_build_jobs" ] || { echo "unexpected build job count: $build_jobs" >&2; exit 1; } [ "$status_value" = ok ] || { echo "self-hosted build status is not ok: $status_value" >&2; exit 1; } [ "$latest_target" = "$result_root" ] || { echo "latest link target mismatch: $latest_target" >&2; exit 1; } [ "$self_hosted_native_build" = ok ] || { echo "self-hosted build marker missing" >&2; exit 1; } case "$source_store" in /frx/store/*-freebsd-source-*) : ;; *) echo "unexpected source store path: $source_store" >&2; exit 1 ;; esac case "$source_root" in /frx/store/*-freebsd-source-*/*) : ;; *) echo "unexpected source root path: $source_root" >&2; exit 1 ;; esac case "$build_root" in /var/tmp/fruix-self-hosted-native-builds/*) : ;; *) echo "unexpected build root: $build_root" >&2; exit 1 ;; esac case "$result_root" in /var/lib/fruix/native-builds/*) : ;; *) echo "unexpected result root: $result_root" >&2; exit 1 ;; esac case "$latest_link" in /var/lib/fruix/native-builds/latest) : ;; *) echo "unexpected latest link path: $latest_link" >&2; exit 1 ;; esac printf '%s\n' "$run_id" | grep -E '^[0-9]{8}T[0-9]{6}Z$' >/dev/null || { echo "unexpected run id: $run_id" >&2 exit 1 } printf '%s\n' "$sha_kernel" | grep -E '^[0-9a-f]{64}$' >/dev/null || { echo "invalid kernel sha256: $sha_kernel" >&2 exit 1 } printf '%s\n' "$sha_loader" | grep -E '^[0-9a-f]{64}$' >/dev/null || { echo "invalid loader sha256: $sha_loader" >&2 exit 1 } printf '%s\n' "$sha_param" | grep -E '^[0-9a-f]{64}$' >/dev/null || { echo "invalid param.h sha256: $sha_param" >&2 exit 1 } case "$buildworld_tail" in *'World build completed on'*) : ;; *) echo "buildworld log does not show completion" >&2; exit 1 ;; esac case "$buildkernel_tail" in *'Kernel(s) GENERIC built in'*) : ;; *) echo "buildkernel log does not show successful kernel build" >&2; exit 1 ;; esac case "$installworld_tail" in *'Install world completed in'*) : ;; *) echo "installworld log does not show successful completion" >&2; exit 1 ;; esac case "$installkernel_tail" in *'Install kernel(s) GENERIC completed in'*) : ;; *) echo "installkernel log does not show successful completion" >&2; exit 1 ;; esac printf '%s\n' "$build_common" | grep -F 'TARGET=amd64 TARGET_ARCH=amd64 KERNCONF=GENERIC' >/dev/null || { echo "unexpected build_common flags: $build_common" >&2 exit 1 } printf '%s\n' "$install_common" | grep -F 'DB_FROM_SRC=yes' >/dev/null || { echo "install_common is missing DB_FROM_SRC=yes" >&2 exit 1 } cat >"$metadata_file" <