system: consume promoted native base results

This commit is contained in:
2026-04-06 06:38:23 +02:00
parent f41a916f45
commit 0e8b30434f
10 changed files with 984 additions and 109 deletions

View File

@@ -0,0 +1,73 @@
(use-modules (fruix system freebsd)
(fruix packages freebsd))
(define phase20-promoted-native-build-result
(promoted-native-build-result
#:store-path "__PROMOTED_RESULT_STORE__"))
(define phase20-promoted-native-base-operating-system
(operating-system-from-promoted-native-build-result
phase20-promoted-native-build-result
#:host-name "fruix-freebsd"
#:groups (list (user-group #:name "wheel" #:gid 0 #:system? #t)
(user-group #:name "sshd" #:gid 22 #:system? #t)
(user-group #:name "_dhcp" #:gid 65 #:system? #t)
(user-group #:name "operator" #:gid 1000 #:system? #f))
#:users (list (user-account #:name "root"
#:uid 0
#:group "wheel"
#:comment "Charlie &"
#:home "/root"
#:shell "/bin/sh"
#:system? #t)
(user-account #:name "sshd"
#:uid 22
#:group "sshd"
#:comment "Secure Shell Daemon"
#:home "/var/empty"
#:shell "/usr/sbin/nologin"
#:system? #t)
(user-account #:name "_dhcp"
#:uid 65
#:group "_dhcp"
#:comment "dhcp programs"
#:home "/var/empty"
#:shell "/usr/sbin/nologin"
#:system? #t)
(user-account #:name "operator"
#:uid 1000
#:group "operator"
#:supplementary-groups '("wheel")
#:comment "Fruix Operator"
#:home "/home/operator"
#:shell "/bin/sh"
#:system? #f))
#:file-systems (list (file-system #:device "/dev/gpt/fruix-root"
#:mount-point "/"
#:type "ufs"
#:options "rw"
#:needed-for-boot? #t)
(file-system #:device "devfs"
#:mount-point "/dev"
#:type "devfs"
#:options "rw"
#:needed-for-boot? #t)
(file-system #:device "tmpfs"
#:mount-point "/tmp"
#:type "tmpfs"
#:options "rw,size=64m"))
#:services '(shepherd ready-marker sshd)
#:loader-entries '(("autoboot_delay" . "1")
("boot_multicons" . "YES")
("boot_serial" . "YES")
("console" . "comconsole,vidconsole"))
#:rc-conf-entries '(("clear_tmp_enable" . "NO")
("hostid_enable" . "NO")
("sendmail_enable" . "NONE")
("sshd_enable" . "YES")
("ifconfig_xn0" . "SYNCDHCP")
("ifconfig_em0" . "SYNCDHCP")
("ifconfig_vtnet0" . "SYNCDHCP"))
#:init-mode 'shepherd-pid1
#:ready-marker "/var/lib/fruix/ready"
#:root-authorized-keys '("__ROOT_AUTHORIZED_KEY__")))

View File

@@ -0,0 +1,227 @@
#!/bin/sh
set -eu
repo_root=${PROJECT_ROOT:-$(pwd)}
os_template=${OS_TEMPLATE:-$repo_root/tests/system/phase20-promoted-native-base-operating-system.scm.in}
system_name=${SYSTEM_NAME:-phase20-promoted-native-base-operating-system}
root_size=${ROOT_SIZE:-12g}
result_store=${RESULT_STORE:-}
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-promoted-native-base-xcpng.XXXXXX)
cleanup=1
fi
if [ "${KEEP_WORKDIR:-0}" -eq 1 ]; then
cleanup=0
fi
promotion_metadata=$workdir/phase20-promoted-native-base-promotion-metadata.txt
prepared_template=$workdir/phase20-promoted-native-base-operating-system.scm.in
inner_metadata=$workdir/phase20-promoted-native-base-inner-metadata.txt
metadata_file=$workdir/phase20-promoted-native-base-declaration-xcpng-metadata.txt
cleanup_workdir() {
if [ "$cleanup" -eq 1 ]; then
rm -rf "$workdir"
fi
}
trap cleanup_workdir EXIT INT TERM
if [ -z "$result_store" ]; then
KEEP_WORKDIR=1 WORKDIR="$workdir/promotion" METADATA_OUT="$promotion_metadata" \
ROOT_AUTHORIZED_KEY_FILE="$root_authorized_key_file" \
ROOT_SSH_PRIVATE_KEY_FILE="$root_ssh_private_key_file" \
ROOT_SIZE=20g \
"$repo_root/tests/system/run-phase20-host-initiated-native-build-store-promotion-xcpng.sh"
result_store=$(sed -n 's/^result_store=//p' "$promotion_metadata")
fi
[ -n "$result_store" ] || { echo "missing promoted result store" >&2; exit 1; }
[ -d "$result_store" ] || { echo "promoted result store does not exist: $result_store" >&2; exit 1; }
[ -f "$result_store/.fruix-native-build-result.scm" ] || {
echo "promoted result store is missing .fruix-native-build-result.scm" >&2
exit 1
}
[ -L "$result_store/artifacts/world" ] || { echo "promoted result store is missing world artifact link" >&2; exit 1; }
[ -L "$result_store/artifacts/kernel" ] || { echo "promoted result store is missing kernel artifact link" >&2; exit 1; }
[ -L "$result_store/artifacts/headers" ] || { echo "promoted result store is missing headers artifact link" >&2; exit 1; }
[ -L "$result_store/artifacts/bootloader" ] || { echo "promoted result store is missing bootloader artifact link" >&2; exit 1; }
world_store=$(readlink "$result_store/artifacts/world")
kernel_store=$(readlink "$result_store/artifacts/kernel")
headers_store=$(readlink "$result_store/artifacts/headers")
bootloader_store=$(readlink "$result_store/artifacts/bootloader")
result_metadata_file=$result_store/.fruix-native-build-result.scm
executor_kind=$(grep -o '(executor-kind \. [^)]*)' "$result_metadata_file" | head -n 1 | sed 's/(executor-kind \. //; s/)$//')
executor_name=$(grep -o '(executor-name \. "[^"]*")' "$result_metadata_file" | head -n 1 | sed 's/(executor-name \. "//; s/")$//')
executor_version=$(grep -o '(executor-version \. "[^"]*")' "$result_metadata_file" | head -n 1 | sed 's/(executor-version \. "//; s/")$//')
[ -f "$world_store/bin/sh" ] || { echo "promoted world store is missing /bin/sh" >&2; exit 1; }
[ -f "$kernel_store/boot/kernel/kernel" ] || { echo "promoted kernel store is missing kernel" >&2; exit 1; }
[ -f "$headers_store/usr/include/sys/param.h" ] || { echo "promoted headers store is missing param.h" >&2; exit 1; }
[ -f "$bootloader_store/boot/loader.efi" ] || { echo "promoted bootloader store is missing loader.efi" >&2; exit 1; }
sed "s|__PROMOTED_RESULT_STORE__|$result_store|g" "$os_template" > "$prepared_template"
action_metadata=${promotion_metadata:-}
ROOT_SIZE="$root_size" KEEP_WORKDIR=1 WORKDIR="$workdir/boot" METADATA_OUT="$inner_metadata" \
ROOT_AUTHORIZED_KEY_FILE="$root_authorized_key_file" \
ROOT_SSH_PRIVATE_KEY_FILE="$root_ssh_private_key_file" \
OS_TEMPLATE="$prepared_template" SYSTEM_NAME="$system_name" \
"$repo_root/tests/system/run-phase11-shepherd-pid1-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")
activate_log=$(sed -n 's/^activate_log=//p' "$inner_metadata")
promoted_result_file=$closure_path/metadata/promoted-native-build-result.scm
store_layout_file=$closure_path/metadata/store-layout.scm
[ "$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; }
case "$activate_log" in
*fruix-activate:done*) : ;;
*) echo "activation log does not show success" >&2; exit 1 ;;
esac
[ -f "$promoted_result_file" ] || { echo "closure is missing promoted native build result metadata" >&2; exit 1; }
[ -f "$store_layout_file" ] || { echo "closure is missing store layout metadata" >&2; exit 1; }
grep -F "$result_store" "$promoted_result_file" >/dev/null || {
echo "closure promoted result metadata does not reference the selected result store" >&2
exit 1
}
grep -F "$result_store" "$closure_path/.references" >/dev/null || {
echo "closure references do not retain the promoted result store" >&2
exit 1
}
grep -F "$kernel_store" "$promoted_result_file" >/dev/null || {
echo "closure promoted result metadata does not reference the promoted kernel store" >&2
exit 1
}
grep -F "$bootloader_store" "$promoted_result_file" >/dev/null || {
echo "closure promoted result metadata does not reference the promoted bootloader store" >&2
exit 1
}
grep -F "$result_store" "$store_layout_file" >/dev/null || {
echo "store layout metadata does not record the promoted result store" >&2
exit 1
}
kernel_link=$(readlink "$closure_path/boot/kernel/kernel")
bootloader_link=$(readlink "$closure_path/boot/loader.efi")
[ "$kernel_link" = "$kernel_store/boot/kernel/kernel" ] || {
echo "closure kernel link does not target the promoted kernel store" >&2
exit 1
}
[ "$bootloader_link" = "$bootloader_store/boot/loader.efi" ] || {
echo "closure bootloader link does not target the promoted bootloader store" >&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_promoted_metadata=$(ssh -i "$root_ssh_private_key_file" \
-o BatchMode=yes \
-o StrictHostKeyChecking=no \
-o UserKnownHostsFile=/dev/null \
-o ConnectTimeout=5 \
root@"$guest_ip" 'sh -s' <<EOF
set -eu
[ -f /run/current-system/metadata/promoted-native-build-result.scm ]
grep -F '$result_store' /run/current-system/metadata/promoted-native-build-result.scm >/dev/null
grep -F '$result_store' /run/current-system/.references >/dev/null
kernel_link=$(readlink /run/current-system/boot/kernel/kernel)
bootloader_link=$(readlink /run/current-system/boot/loader.efi)
[ "$kernel_link" = "$kernel_store/boot/kernel/kernel" ]
[ "$bootloader_link" = "$bootloader_store/boot/loader.efi" ]
[ -x /bin/sh ]
[ -x /usr/sbin/sshd ]
printf 'kernel_link=%s\n' "$kernel_link"
printf 'bootloader_link=%s\n' "$bootloader_link"
printf 'uname=%s\n' "$(uname -sr)"
printf 'promoted_result_store=%s\n' '$result_store'
EOF
)
guest_kernel_link=$(printf '%s\n' "$guest_promoted_metadata" | sed -n 's/^kernel_link=//p')
guest_bootloader_link=$(printf '%s\n' "$guest_promoted_metadata" | sed -n 's/^bootloader_link=//p')
guest_uname=$(printf '%s\n' "$guest_promoted_metadata" | sed -n 's/^uname=//p')
[ "$guest_kernel_link" = "$kernel_store/boot/kernel/kernel" ] || {
echo "guest kernel link does not target the promoted kernel store" >&2
exit 1
}
[ "$guest_bootloader_link" = "$bootloader_store/boot/loader.efi" ] || {
echo "guest bootloader link does not target the promoted bootloader store" >&2
exit 1
}
cat >"$metadata_file" <<EOF
workdir=$workdir
promotion_metadata=$promotion_metadata
inner_metadata=$inner_metadata
phase8_metadata=$phase8_metadata
closure_path=$closure_path
closure_base=$closure_base
vm_id=$vm_id
vdi_id=$vdi_id
guest_ip=$guest_ip
root_size=$root_size
result_store=$result_store
result_metadata_file=$result_metadata_file
executor_kind=$executor_kind
executor_name=$executor_name
executor_version=$executor_version
world_store=$world_store
kernel_store=$kernel_store
headers_store=$headers_store
bootloader_store=$bootloader_store
promoted_result_file=$promoted_result_file
store_layout_file=$store_layout_file
kernel_link=$kernel_link
bootloader_link=$bootloader_link
guest_kernel_link=$guest_kernel_link
guest_bootloader_link=$guest_bootloader_link
guest_uname=$guest_uname
boot_backend=xcp-ng-xo-cli
init_mode=shepherd-pid1
promoted_native_base_declaration=ok
EOF
if [ -n "$metadata_target" ]; then
mkdir -p "$(dirname "$metadata_target")"
cp "$metadata_file" "$metadata_target"
fi
printf 'PASS phase20-promoted-native-base-declaration-xcpng\n'
printf 'Work directory: %s\n' "$workdir"
printf 'Metadata file: %s\n' "$metadata_file"
if [ -n "$metadata_target" ]; then
printf 'Copied metadata to: %s\n' "$metadata_target"
fi
printf '%s\n' '--- metadata ---'
cat "$metadata_file"