hololake-system-architecture/product-source/hololake-platform/guanghu-os/scripts/build-guanghu-cross-root-fixture.sh

91 lines
3.8 KiB
Shell
Executable file

#!/usr/bin/env bash
set -Eeuo pipefail
[[ $# == 3 || $# == 7 ]] || {
echo 'usage: build-guanghu-cross-root-fixture.sh <output-image> <config> <root-supervisor> [<repository-lifecycle> <lifecycle-config> <repository-backend> <expected-main>]' >&2
exit 64
}
output=$(readlink -m "$1")
config=$(readlink -f "$2")
supervisor=$(readlink -f "$3")
lifecycle=
lifecycle_config=
repository_backend=
expected_main=
if [[ $# == 7 ]]; then
lifecycle=$(readlink -f "$4")
lifecycle_config=$(readlink -f "$5")
repository_backend=$(readlink -f "$6")
expected_main=$7
[[ -x ${lifecycle} && -x ${repository_backend} && -f ${lifecycle_config} ]]
[[ ${expected_main} =~ ^[0-9a-f]{40}$ ]]
fi
root_uuid=$(sed -n 's/^root_uuid=//p' "${config}")
[[ ${root_uuid} =~ ^[0-9a-f-]{36}$ ]]
[[ -x /bin/busybox && -x ${supervisor} ]]
command -v mkfs.ext4 >/dev/null
staging=$(mktemp -d)
trap 'rm -rf "${staging}"' EXIT
mkdir -p "${staging}/bin" "${staging}/sbin" "${staging}/usr/lib/guanghu" \
"${staging}/etc/guanghu" "${staging}/run" "${staging}/dev" \
"${staging}/proc" "${staging}/sys" "${staging}/lib/modules" \
"${staging}/guanghu/receipts/repository-bridge-lifecycle" \
"${staging}/usr/share/guanghu/repository-service-equivalence" \
"$(dirname "${output}")"
install -m 0755 /bin/busybox "${staging}/bin/busybox"
for applet in sh sleep cat grep tr stat mkdir mv chmod readlink kill sync poweroff sed id httpd wget rm ip timeout mount; do
ln -s busybox "${staging}/bin/${applet}"
done
install -m 0755 "${supervisor}" "${staging}/usr/lib/guanghu/guanghu-root-supervisor"
install -m 0600 "${config}" "${staging}/etc/guanghu/first-boot-supervisor.conf"
if [[ -n ${lifecycle} ]]; then
install -m 0755 "${lifecycle}" "${staging}/usr/lib/guanghu/guanghu-repository-bridge-lifecycle"
install -m 0755 "${repository_backend}" "${staging}/usr/lib/guanghu/qemu-repository-service-equivalence-backend"
install -m 0600 "${lifecycle_config}" "${staging}/etc/guanghu/repository-bridge-lifecycle.conf"
printf '%s\n' "${expected_main}" >"${staging}/usr/share/guanghu/repository-service-equivalence/main"
fi
printf '%s\n' 'guanghu.cross-root-fixture/v1' >"${staging}/etc/guanghu/rootfs.marker"
cat >"${staging}/sbin/init" <<'EOF'
#!/bin/sh
set -eu
export PATH=/bin:/sbin
echo 'GUANGHU_SWITCH_ROOT_INIT_ACTIVE marker=guanghu.cross-root-fixture/v1'
/usr/lib/guanghu/guanghu-root-supervisor run &
supervisor_pid=$!
attempt=0
while [ ! -s /run/guanghu/root-supervisor/state.json ] && [ "${attempt}" -lt 100 ]; do
sleep 0.05
attempt=$((attempt + 1))
done
kill -0 "${supervisor_pid}"
grep -Fq '"stage":"ROOT_SUPERVISOR_ACTIVE"' /run/guanghu/root-supervisor/state.json
echo "GUANGHU_CROSS_ROOT_PERSISTENCE_VERIFIED pid=${supervisor_pid}"
if [ -x /usr/lib/guanghu/guanghu-repository-bridge-lifecycle ]; then
ip link set lo up
mount -t tmpfs -o mode=0700,size=1m tmpfs /guanghu/receipts
/usr/lib/guanghu/guanghu-repository-bridge-lifecycle run REQ-QEMU-CROSS-ROOT-001
grep -Fq '"result":"PASS_100"' /guanghu/receipts/repository-bridge-lifecycle/REQ-QEMU-CROSS-ROOT-001.json
grep -Fq '"final_state":"DORMANT"' /guanghu/receipts/repository-bridge-lifecycle/REQ-QEMU-CROSS-ROOT-001.json
if timeout 1 wget -q -O /dev/null http://127.0.0.1:39301/main; then
echo 'GUANGHU_CROSS_ROOT_REPOSITORY_SERVICE_FAIL_0: repository service remained ready after reclaim' >&2
poweroff -f
while :; do sleep 30; done
fi
echo 'GUANGHU_CROSS_ROOT_REPOSITORY_SERVICE_EQUIVALENCE_VERIFIED request=REQ-QEMU-CROSS-ROOT-001 final=DORMANT'
fi
kill "${supervisor_pid}"
wait "${supervisor_pid}"
sync
poweroff -f
while :; do sleep 30; done
EOF
chmod 0755 "${staging}/sbin/init"
truncate -s 128M "${output}"
mkfs.ext4 -q -F -U "${root_uuid}" -L GUANGHU_XROOT -d "${staging}" "${output}"
chmod 0600 "${output}"
sha256sum "${output}" >"${output}.sha256"
printf 'GUANGHU_CROSS_ROOT_FIXTURE_BUILT output=%s root_uuid=%s\n' "${output}" "${root_uuid}"