110 lines
4.1 KiB
Shell
Executable file
110 lines
4.1 KiB
Shell
Executable file
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
[[ $# -eq 6 ]] || {
|
|
echo "usage: replace-jd-native-final-resident-candidate.sh <world-root> <candidate-image> <recovery-root> <expected-old-sha256> <expected-new-sha256> <accepted-source-commit>" >&2
|
|
exit 64
|
|
}
|
|
[[ ${EUID} -eq 0 ]] || exit 77
|
|
|
|
world_root=$(readlink -f "$1")
|
|
candidate=$(readlink -f "$2")
|
|
recovery_root=$(readlink -m "$3")
|
|
expected_old_sha=$4
|
|
expected_new_sha=$5
|
|
accepted_source_commit=$6
|
|
|
|
grep -q '^node_id: JD-FD-PRIMARY$' "${world_root}/CURRENT.hldp"
|
|
/guanghu/bin/ghctl authorize "${world_root}" \
|
|
write_bootloader_and_system_partitions >/dev/null
|
|
[[ ${expected_old_sha} =~ ^[0-9a-f]{64}$ ]]
|
|
[[ ${expected_new_sha} =~ ^[0-9a-f]{64}$ ]]
|
|
[[ ${accepted_source_commit} =~ ^[0-9a-f]{40}$ ]]
|
|
[[ $(stat -c %s "${candidate}") -eq 14848 ]]
|
|
[[ $(sha256sum "${candidate}" | awk '{print $1}') == "${expected_new_sha}" ]]
|
|
[[ ! -e ${recovery_root} ]]
|
|
|
|
partition_dump=$(sfdisk -d /dev/vda)
|
|
grep -q '^label: dos$' <<<"${partition_dump}"
|
|
grep -q '^label-id: 0xf4bb72a5$' <<<"${partition_dump}"
|
|
grep -Eq '^/dev/vda1 : start= *2048, size= *209713119, type=83$' \
|
|
<<<"${partition_dump}"
|
|
observed_old_sha=$(dd if=/dev/vda bs=512 skip=105 count=29 status=none |
|
|
sha256sum | awk '{print $1}')
|
|
[[ ${observed_old_sha} == "${expected_old_sha}" ]]
|
|
|
|
dd if=/dev/vda bs=512 skip=135 count=1 status=none |
|
|
grep -aq '^GHOS_HLDP_WORLD_STORE_V1'
|
|
dd if=/dev/vda bs=512 skip=136 count=1 status=none |
|
|
grep -aq '^GHOS_CODE_CHANNEL_STORE_V1'
|
|
dd if=/dev/vda bs=512 skip=138 count=1 status=none |
|
|
grep -aq '^GHOS_BRANCH_MAIN_V1'
|
|
dd if=/dev/vda bs=512 skip=141 count=1 status=none |
|
|
grep -aq '^GHOS_GHCIP_INDEX_V1'
|
|
dd if=/dev/vda bs=512 skip=142 count=1 status=none |
|
|
grep -aq '^GHOS_GHCIP_ROOT_V1'
|
|
grub_default=$(awk -F= '$1 == "GRUB_DEFAULT" { print $2; found = 1 } END { if (!found) exit 1 }' \
|
|
/etc/default/grub)
|
|
case "${grub_default}" in
|
|
guanghu-jd-native-once)
|
|
grep -q 'set default="guanghu-jd-native-once"' /boot/grub/grub.cfg
|
|
;;
|
|
gnulinux-simple-9e4550a0-452b-4f28-b5a5-d5364aa450f6)
|
|
grep -q 'set default="gnulinux-simple-9e4550a0-452b-4f28-b5a5-d5364aa450f6"' \
|
|
/boot/grub/grub.cfg
|
|
;;
|
|
*)
|
|
echo "unsupported GRUB_DEFAULT for bounded native candidate replacement: ${grub_default}" >&2
|
|
exit 65
|
|
;;
|
|
esac
|
|
|
|
mkdir -m 0700 "${recovery_root}"
|
|
printf '%s\n' "${partition_dump}" >"${recovery_root}/sfdisk-before.txt"
|
|
disk_sectors=$(blockdev --getsz /dev/vda)
|
|
dd if=/dev/vda of="${recovery_root}/first-2MiB.before.bin" \
|
|
bs=1M count=2 status=none
|
|
dd if=/dev/vda of="${recovery_root}/last-2MiB.before.bin" \
|
|
bs=512 skip=$((disk_sectors - 4096)) count=4096 status=none
|
|
dd if=/dev/vda of="${recovery_root}/previous-native-candidate.img" \
|
|
bs=512 skip=105 count=29 status=none
|
|
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"
|
|
cp "${candidate}" "${recovery_root}/jd-native-final-resident.img"
|
|
|
|
dd if="${candidate}" of=/dev/vda bs=512 seek=105 count=29 \
|
|
conv=notrunc,fsync status=none
|
|
observed_new_sha=$(dd if=/dev/vda bs=512 skip=105 count=29 status=none |
|
|
sha256sum | awk '{print $1}')
|
|
[[ ${observed_new_sha} == "${expected_new_sha}" ]]
|
|
|
|
observed_at=$(date --iso-8601=seconds)
|
|
cat >"${recovery_root}/REPLACE-RECEIPT.hldp" <<EOF
|
|
schema: guanghu.jd-native-final-resident-replace/v1
|
|
receipt_id: GH-OS-JD-FD-PRIMARY-001-FINAL-RESIDENT-REPLACE
|
|
status: VERIFIED_NOT_REBOOTED
|
|
observed_at: ${observed_at}
|
|
node_id: JD-FD-PRIMARY
|
|
source:
|
|
accepted_repository_commit: ${accepted_source_commit}
|
|
candidate:
|
|
lba_start: 105
|
|
sector_count: 29
|
|
previous_sha256: ${observed_old_sha}
|
|
final_resident_sha256: ${observed_new_sha}
|
|
preserved:
|
|
proof_lba_134: true
|
|
world_and_code_store_lba_135_138: true
|
|
recovery_beacon_lba_139_140: true
|
|
gestational_index_lba_141_142: true
|
|
grub_default_unchanged: ${grub_default}
|
|
rollback:
|
|
recovery_root: ${recovery_root}
|
|
first_and_last_2mib_backed_up: true
|
|
previous_candidate_backed_up: true
|
|
next_action: START_PROTECTED_RELAY_THEN_REBOOT_TO_PHYSICAL_FINAL_RESIDENCY_GATE
|
|
EOF
|
|
chmod 0400 "${recovery_root}"/*
|
|
sync
|
|
cat "${recovery_root}/REPLACE-RECEIPT.hldp"
|