AntonioLopardo/Backup / restore.sh
AntonioLopardo's picture
download
raw
2.76 kB
#!/usr/bin/env bash
#
# restore.sh — restore this ENCRYPTED vdc OS image bundle onto a target disk,
# bit-exact & bootable.
#
# Usage: sudo ./restore.sh /dev/TARGET_DISK
# e.g. sudo ./restore.sh /dev/vdb
# sudo ./restore.sh /dev/nvme1n1
#
# You will be prompted once for the AES-256 passphrase used when the bundle was
# created (the 60-char secret from your password manager; sha256 fingerprint
# starts ff23c993e47836f2). Each partition image is gpg-decrypted, zstd-
# decompressed, and written to the matching partition.
#
# The restored disk carries vdc's ORIGINAL UUIDs — a bit-exact clone of vdc. Do
# NOT attach it to a host that already has vdc online (UUID collision). For
# disaster recovery (replacing the disk) that is exactly what you want.
#
# Requires: gpg, zstd, sgdisk (gdisk), dd, partprobe, e2fsck. Run from the
# bundle directory (all *.gpg files + vdc.sgdisk.gpt must be alongside).
set -euo pipefail
TARGET="${1:-}"
if [[ -z "$TARGET" || ! -b "$TARGET" ]]; then
echo "usage: sudo $0 /dev/TARGET_DISK (must be a block device)" >&2
exit 1
fi
# Partition suffix: /dev/nvme0n1 -> p1, /dev/vdb -> 1
case "$TARGET" in
*[0-9]) P="p" ;; # ends in a digit (nvme, mmcblk, loop) -> needs 'p'
*) P="" ;;
esac
echo "!!! This will OVERWRITE all data on ${TARGET} !!!"
read -r -p "Type the target device again to confirm (${TARGET}): " CONFIRM
[[ "$CONFIRM" == "$TARGET" ]] || { echo "mismatch, aborting."; exit 1; }
# Read the decryption passphrase once (hidden), reuse for every file via fd 3.
read -rsp "AES-256 passphrase: " PASS; echo
dec() { # dec <file.gpg> -> plaintext (zstd stream) on stdout
gpg --batch --quiet --pinentry-mode loopback --passphrase-fd 3 --decrypt "$1" 3<<<"$PASS"
}
cd "$(dirname "$0")"
echo "== 1/6 restore GPT partition table =="
sgdisk --load-backup=vdc.sgdisk.gpt "$TARGET"
partprobe "$TARGET"
echo "== 2/6 vdc1 (BIOS boot) =="
dec vdc1.img.zst.gpg | zstd -d --long=31 | dd of="${TARGET}${P}1" bs=1M conv=fsync status=progress
echo "== 3/6 vdc2 (ESP /boot/efi) =="
dec vdc2.img.zst.gpg | zstd -d --long=31 | dd of="${TARGET}${P}2" bs=1M conv=fsync status=progress
echo "== 4/6 vdc3 (/boot ext4) =="
dec vdc3.ext4.img.zst.gpg | zstd -d --long=31 | dd of="${TARGET}${P}3" bs=8M conv=fsync status=progress
echo "== 5/6 vdc4 (root ext4) — this is the big one =="
dec vdc4.ext4.img.zst.gpg | zstd -d --long=31 | dd of="${TARGET}${P}4" bs=64M conv=fsync status=progress
echo "== 6/6 filesystem sanity check =="
e2fsck -fy "${TARGET}${P}3" || true
e2fsck -fy "${TARGET}${P}4" || true
unset PASS
echo
echo "Done. ${TARGET} is now a bit-exact bootable clone of vdc."
echo "It boots standalone (hybrid BIOS+UEFI GRUB). Verify with: lsblk -f ${TARGET}"

Xet Storage Details

Size:
2.76 kB
·
Xet hash:
92a4c8667ac0ff5df99ebfa24781bc342440359c106eeb8056b023338f3bf2d2

Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.