98 lines
3.7 KiB
Shell
Executable file
98 lines
3.7 KiB
Shell
Executable file
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
[[ $# -eq 5 ]] || {
|
|
echo "usage: replace-native-physical-once.sh <world-root> <candidate-image> <disk> <recovery-root> <expected-installed-sha256>" >&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")
|
|
expected_installed_sha=$5
|
|
|
|
[[ ${disk} == /dev/vda ]]
|
|
[[ ${expected_installed_sha} =~ ^[0-9a-f]{64}$ ]]
|
|
grep -q '^node_id: BS-SH-005$' "${world_root}/CURRENT.hldp"
|
|
/guanghu/bin/ghctl authorize "${world_root}" \
|
|
write_bootloader_and_system_partitions >/dev/null
|
|
[[ $(stat -c %s "${candidate}") -eq 14848 ]]
|
|
[[ ! -e ${recovery_root} ]]
|
|
|
|
partition_dump=$(sfdisk -d "${disk}")
|
|
grep -q '^label: gpt$' <<<"${partition_dump}"
|
|
grep -q '^label-id: E549327B-8DC7-4797-944F-DC6185D1B550$' \
|
|
<<<"${partition_dump}"
|
|
grep -Eq '^/dev/vda1 : start= *2048, size= *2048,' <<<"${partition_dump}"
|
|
grep -Eq '^/dev/vda2 : start= *4096, size= *104853471,' <<<"${partition_dump}"
|
|
|
|
legacy_installed_before=$(mktemp)
|
|
kernel_region_before=$(mktemp)
|
|
proof_before=$(mktemp)
|
|
trap 'rm -f "${legacy_installed_before}" "${kernel_region_before}" "${proof_before}"' EXIT
|
|
dd if="${disk}" of="${legacy_installed_before}" bs=512 skip=34 count=16 status=none
|
|
installed_sha=$(sha256sum "${legacy_installed_before}" | awk '{print $1}')
|
|
[[ ${installed_sha} == "${expected_installed_sha}" ]]
|
|
dd if="${disk}" of="${kernel_region_before}" bs=512 skip=34 count=29 status=none
|
|
dd if="${disk}" of="${proof_before}" bs=512 skip=63 count=1 status=none
|
|
cmp -s "${proof_before}" <(head -c 512 /dev/zero)
|
|
|
|
mkdir -m 0700 "${recovery_root}"
|
|
printf '%s\n' "${partition_dump}" >"${recovery_root}/sfdisk-before.txt"
|
|
cp "${kernel_region_before}" "${recovery_root}/lba34-62.before.bin"
|
|
cp "${proof_before}" "${recovery_root}/lba63.before.bin"
|
|
dd if="${disk}" of="${recovery_root}/first-2MiB.before.bin" \
|
|
bs=1M count=2 status=none
|
|
disk_sectors=$(blockdev --getsz "${disk}")
|
|
dd if="${disk}" of="${recovery_root}/last-2MiB.before.bin" \
|
|
bs=512 skip=$((disk_sectors - 4096)) count=4096 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 /etc/grub.d/40_custom "${recovery_root}/40_custom.before"
|
|
cp "${candidate}" "${recovery_root}/guanghu-os-physical-candidate.img"
|
|
|
|
dd if="${candidate}" of="${disk}" bs=512 seek=34 count=29 \
|
|
conv=notrunc,fsync status=none
|
|
candidate_sha=$(sha256sum "${candidate}" | awk '{print $1}')
|
|
readback_sha=$(dd if="${disk}" bs=512 skip=34 count=29 status=none |
|
|
sha256sum | awk '{print $1}')
|
|
[[ ${candidate_sha} == "${readback_sha}" ]]
|
|
dd if="${disk}" of="${proof_before}" bs=512 skip=63 count=1 status=none
|
|
cmp -s "${proof_before}" <(head -c 512 /dev/zero)
|
|
|
|
sha256sum "${recovery_root}"/* >"${recovery_root}/SHA256SUMS"
|
|
chmod 0400 "${recovery_root}"/*
|
|
observed_at=$(date --iso-8601=seconds)
|
|
cat >"${recovery_root}/REPLACE-RECEIPT.hldp" <<EOF
|
|
schema: guanghu.native-physical-replacement/v1
|
|
receipt_id: GH-OS-LAB-001-NATIVE-PHYSICAL-REPLACEMENT
|
|
status: VERIFIED_NOT_ARMED
|
|
observed_at: ${observed_at}
|
|
node_id: BS-SH-005
|
|
instance_id: lhins-14w5y3ce
|
|
disk:
|
|
path: /dev/vda
|
|
candidate_start_lba: 34
|
|
candidate_sector_count: 29
|
|
proof_lba: 63
|
|
candidate:
|
|
replaced_sha256: ${installed_sha}
|
|
new_sha256: ${candidate_sha}
|
|
readback_sha256: ${readback_sha}
|
|
proof_before_and_after: EMPTY
|
|
recovery:
|
|
directory: ${recovery_root}
|
|
disk_edges_and_grub_backed_up: true
|
|
grub:
|
|
entry_id: guanghu-native-once
|
|
armed: false
|
|
next_action: ARM_ONE_TIME_ENTRY_AND_REBOOT
|
|
EOF
|
|
chmod 0400 "${recovery_root}/REPLACE-RECEIPT.hldp"
|
|
cat "${recovery_root}/REPLACE-RECEIPT.hldp"
|