#!/usr/bin/env bash set -euo pipefail usage() { cat <<'USAGE' Usage: hermes-emergency-bundle-decrypt.sh [staging-dir] Decrypts a Hermes emergency bundle into a staging directory. Default staging-dir: /root/hermes-emergency-restore-staging/ Passphrase: Interactive GPG prompt by default. Or set BUNDLE_PASSPHRASE_FILE=/root/path/to/passphrase-file for unattended use. Safety: - Does not write into /root/.hermes or /home/uma/.hermes. - Does not overwrite live credentials. - Review extracted files, then copy only the needed files manually. USAGE } if [ "${1:-}" = "-h" ] || [ "${1:-}" = "--help" ] || [ "$#" -lt 1 ]; then usage exit 0 fi BUNDLE="$1" if [ ! -f "$BUNDLE" ]; then echo "Bundle not found: $BUNDLE" >&2 exit 1 fi base="$(basename "$BUNDLE" .gpg)" STAGING_DIR="${2:-/root/hermes-emergency-restore-staging/$base}" WORK_DIR="$(mktemp -d)" ARCHIVE="$WORK_DIR/$base" cleanup() { rm -rf "$WORK_DIR" } trap cleanup EXIT install -d -m 700 "$STAGING_DIR" gpg_args=(--decrypt --output "$ARCHIVE") if [ -n "${BUNDLE_PASSPHRASE_FILE:-}" ]; then gpg_args=(--batch --yes --pinentry-mode loopback --passphrase-file "$BUNDLE_PASSPHRASE_FILE" "${gpg_args[@]}") fi gpg "${gpg_args[@]}" "$BUNDLE" tar -C "$STAGING_DIR" -I zstd -xf "$ARCHIVE" chmod -R go-rwx "$STAGING_DIR" echo "Bundle decrypted into staging directory: $STAGING_DIR" echo echo "Included paths:" if [ -f "$STAGING_DIR/MANIFEST.paths" ]; then sed -n '1,200p' "$STAGING_DIR/MANIFEST.paths" else find "$STAGING_DIR" -type f | sed "s#^$STAGING_DIR/##" | sort | sed -n '1,200p' fi echo echo "Next step: inspect staging, then manually copy only the needed files into place."