#!/usr/bin/env bash set -euo pipefail [[ $# -eq 5 ]] || { echo "usage: replace-native-physical-once.sh " >&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" <