#!/usr/bin/env bash set -euo pipefail usage() { cat <<'EOF' Usage: remote_flash_titan_image.sh Copy a prepared Titan replacement image to a remote flashing station and write it to the specified removable block device. Example: ./scripts/remote_flash_titan_image.sh tethys titan-13 /dev/sdd EOF } if [ "${3:-}" = "" ] || [ "${1:-}" = "-h" ] || [ "${1:-}" = "--help" ]; then usage exit 0 fi remote_host="$1" node="$2" device="$3" repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" remote_dir="${METIS_REMOTE_DIR:-/tmp/metis-images}" image_path="${repo_root}/artifacts/${node}.img" max_bytes="${METIS_SD_MAX_BYTES:-300000000000}" if [ ! -f "${image_path}" ]; then echo "Missing local image: ${image_path}" >&2 exit 1 fi case "${device}" in /dev/sd*|/dev/mmcblk*|/dev/nvme*n1) ;; *) echo "Refusing suspicious device path: ${device}" >&2 exit 1 ;; esac device_info="$(ssh "${remote_host}" "lsblk -b -dn -o NAME,TRAN,RM,HOTPLUG,SIZE '${device}' 2>/dev/null" || true)" if [ -z "${device_info}" ]; then echo "Could not inspect remote device ${device} on ${remote_host}" >&2 exit 1 fi read -r remote_name remote_tran remote_rm remote_hotplug remote_size <<<"${device_info}" if [ "/dev/${remote_name}" != "${device}" ]; then echo "Remote device mismatch: expected ${device}, got /dev/${remote_name}" >&2 exit 1 fi if [ "${remote_size}" -gt "${max_bytes}" ]; then echo "Refusing to flash ${device}: size ${remote_size} is larger than ${max_bytes} bytes" >&2 exit 1 fi if [ "${remote_tran}" != "usb" ] && [ "${remote_rm}" != "1" ] && [ "${remote_hotplug}" != "1" ]; then echo "Refusing to flash ${device}: not detected as removable/hotplug media (${device_info})" >&2 exit 1 fi echo "Copying ${image_path} to ${remote_host}:${remote_dir}/${node}.img ..." ssh "${remote_host}" "mkdir -p '${remote_dir}'" scp "${image_path}" "${remote_host}:${remote_dir}/${node}.img" local_sha="$(sha256sum "${image_path}" | awk '{print $1}')" remote_sha="$(ssh "${remote_host}" "sha256sum '${remote_dir}/${node}.img' | awk '{print \\$1}'")" if [ "${local_sha}" != "${remote_sha}" ]; then echo "Checksum mismatch after copy: local=${local_sha} remote=${remote_sha}" >&2 exit 1 fi echo "About to flash ${node}.img to ${device} on ${remote_host}." echo "You will be prompted for the remote sudo password." ssh -t "${remote_host}" "lsblk '${device}' && sudo dd if='${remote_dir}/${node}.img' of='${device}' bs=4M conv=fsync status=progress && sync && sudo blockdev --flushbufs '${device}'" cat <