140 lines
5.1 KiB
Shell
Executable file
140 lines
5.1 KiB
Shell
Executable file
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
[[ $# -eq 4 ]] || {
|
|
echo "usage: replace-native-recovery-beacon.sh <world-root> <candidate-image> <disk> <recovery-root>" >&2
|
|
exit 64
|
|
}
|
|
[[ ${EUID} -eq 0 ]] || {
|
|
echo "must run as root" >&2
|
|
exit 77
|
|
}
|
|
|
|
world_root=$(readlink -f "$1")
|
|
candidate=$(readlink -f "$2")
|
|
disk=$(readlink -f "$3")
|
|
recovery_root=$(readlink -m "$4")
|
|
source_root=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)
|
|
render_root=$(mktemp -d)
|
|
trap 'rm -rf "${render_root}"' EXIT
|
|
|
|
[[ ${disk} == /dev/vda ]]
|
|
[[ $(stat -c %s "${candidate}") -eq 14848 ]]
|
|
grep -q '^node_id: BS-SH-005$' "${world_root}/CURRENT.hldp"
|
|
/guanghu/bin/ghctl authorize "${world_root}" write_bootloader_and_system_partitions \
|
|
>/dev/null
|
|
|
|
partition_dump=$(sfdisk -d "${disk}")
|
|
grep -q '^label: gpt$' <<<"${partition_dump}"
|
|
grep -Eq '^/dev/vda1 : start= *2048, size= *2048,' <<<"${partition_dump}"
|
|
grep -Eq '^/dev/vda2 : start= *4096, size= *104853471,' <<<"${partition_dump}"
|
|
grep -q '^GRUB_DEFAULT=guanghu-native-once$' /etc/default/grub
|
|
grep -q "menuentry 'Ubuntu'.*'gnulinux-simple-9842d3d6-a839-4127-bda7-f19137effe71'" \
|
|
/boot/grub/grub.cfg
|
|
|
|
"${source_root}/scripts/render-native-recovery-beacon.sh" "${render_root}"
|
|
mkdir -p "${recovery_root}"
|
|
chmod 0700 "${recovery_root}"
|
|
printf '%s\n' "${partition_dump}" >"${recovery_root}/sfdisk-before.txt"
|
|
dd if="${disk}" of="${recovery_root}/first-2MiB.before.bin" \
|
|
bs=1M count=2 status=none
|
|
dd if="${disk}" of="${recovery_root}/lba34-71.before.bin" \
|
|
bs=512 skip=34 count=38 status=none
|
|
dd if="${disk}" of="${recovery_root}/lba70-71.before.bin" \
|
|
bs=512 skip=70 count=2 status=none
|
|
if ! cmp -s "${recovery_root}/lba70-71.before.bin" \
|
|
<(head -c 1024 /dev/zero); then
|
|
if ! grep -aFq 'GHOS_GHCIP_INDEX_V1' \
|
|
"${recovery_root}/lba70-71.before.bin" ||
|
|
! grep -aFq 'GHOS_GHCIP_ROOT_V1' \
|
|
"${recovery_root}/lba70-71.before.bin"; then
|
|
echo "native gestational index sectors 70-71 contain unknown data" >&2
|
|
exit 65
|
|
fi
|
|
fi
|
|
cp /boot/grub/grub.cfg "${recovery_root}/grub.cfg.before"
|
|
cp /boot/grub/grubenv "${recovery_root}/grubenv.before"
|
|
cp /etc/default/grub "${recovery_root}/default-grub.before"
|
|
tar -czf "${recovery_root}/etc-grub.d.before.tar.gz" -C /etc grub.d
|
|
|
|
dd if="${render_root}/guanghu-recovery-clear.env" of="${disk}" \
|
|
bs=512 seek=68 count=2 conv=notrunc,fsync status=none
|
|
dd if="${candidate}" of="${disk}" \
|
|
bs=512 seek=34 count=29 conv=notrunc,fsync status=none
|
|
install -m 0755 "${render_root}/08_guanghu_native_recovery" \
|
|
/etc/grub.d/08_guanghu_native_recovery
|
|
install -D -m 0644 "${render_root}/guanghu-recovery-clear.env" \
|
|
/usr/lib/guanghu-os/guanghu-recovery-clear.env
|
|
install -D -m 0755 "${source_root}/scripts/clear-native-recovery-beacon.sh" \
|
|
/usr/local/sbin/guanghu-clear-native-recovery-beacon
|
|
install -m 0644 /dev/stdin \
|
|
/etc/systemd/system/guanghu-native-recovery-beacon-clear.service <<'EOF'
|
|
[Unit]
|
|
Description=Verify and clear the Guanghu native recovery beacon
|
|
After=local-fs.target
|
|
Before=multi-user.target
|
|
|
|
[Service]
|
|
Type=oneshot
|
|
ExecStart=/usr/local/sbin/guanghu-clear-native-recovery-beacon /dev/vda /usr/lib/guanghu-os/guanghu-recovery-clear.env
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|
|
EOF
|
|
systemctl enable guanghu-native-recovery-beacon-clear.service >/dev/null
|
|
update-grub >/dev/null
|
|
grub-script-check /boot/grub/grub.cfg
|
|
|
|
grep -q "load_env --file '(hd0)68+2' guanghu_recovery" /boot/grub/grub.cfg
|
|
grep -q 'set default="guanghu-native-once"' /boot/grub/grub.cfg
|
|
grep -q "menuentry 'Guanghu OS native one-time proof'.*'guanghu-native-once'" \
|
|
/boot/grub/grub.cfg
|
|
|
|
candidate_sha=$(sha256sum "${candidate}" | awk '{print $1}')
|
|
candidate_readback_sha=$(dd if="${disk}" bs=512 skip=34 count=29 status=none |
|
|
sha256sum | awk '{print $1}')
|
|
[[ ${candidate_sha} == "${candidate_readback_sha}" ]]
|
|
beacon_sha=$(sha256sum \
|
|
"${render_root}/guanghu-recovery-clear.env" | awk '{print $1}')
|
|
beacon_readback_sha=$(dd if="${disk}" bs=512 skip=68 count=2 status=none |
|
|
sha256sum | awk '{print $1}')
|
|
[[ ${beacon_sha} == "${beacon_readback_sha}" ]]
|
|
|
|
observed_at=$(date --iso-8601=seconds)
|
|
cat >"${recovery_root}/NATIVE-RECOVERY-BEACON-INSTALL-RECEIPT.hldp" <<EOF
|
|
schema: guanghu.native-recovery-beacon-install/v1
|
|
receipt_id: GH-OS-LAB-001-NATIVE-RECOVERY-BEACON-INSTALL-001
|
|
status: CONFIGURED_NOT_REBOOTED
|
|
observed_at: ${observed_at}
|
|
node_id: BS-SH-005
|
|
instance_id: lhins-14w5y3ce
|
|
candidate:
|
|
lba_start: 34
|
|
sector_count: 29
|
|
sha256: ${candidate_sha}
|
|
readback_sha256: ${candidate_readback_sha}
|
|
recovery_beacon:
|
|
protocol: GHNRP
|
|
lba_start: 68
|
|
sector_count: 2
|
|
clear_sha256: ${beacon_sha}
|
|
readback_sha256: ${beacon_readback_sha}
|
|
grub:
|
|
raw_blocklist: (hd0)68+2
|
|
whitelisted_variable: guanghu_recovery
|
|
native_default_preserved: true
|
|
ubuntu_recovery_entry_preserved: true
|
|
hosted_fallback:
|
|
clear_service_enabled: true
|
|
rollback:
|
|
recovery_root: ${recovery_root}
|
|
first_2mib_backed_up: true
|
|
lba34_71_backed_up: true
|
|
gestational_index_preserved_for_native_verification: true
|
|
grub_configuration_backed_up: true
|
|
next_action: REBOOT_NATIVE_DEFAULT_THEN_PROVE_GHNRP_RECOVERS_UBUNTU
|
|
EOF
|
|
sha256sum "${recovery_root}"/* >"${recovery_root}/SHA256SUMS"
|
|
chmod 0400 "${recovery_root}"/*
|
|
sync
|
|
cat "${recovery_root}/NATIVE-RECOVERY-BEACON-INSTALL-RECEIPT.hldp"
|