#!/usr/bin/env bash set -Eeuo pipefail [[ $# == 3 || $# == 7 ]] || { echo 'usage: build-guanghu-cross-root-fixture.sh [ ]' >&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}"