diff --git a/btv b/btv index d2348b1..5646eff 100755 --- a/btv +++ b/btv @@ -8,6 +8,7 @@ import datetime import json import os import shlex +import shutil import sys import time import socket @@ -246,11 +247,14 @@ def serialize(snap, outdir, key, snap_from=None): ## final touches ## - ## add a self-check executable + ## add self-check and unpack executables with open(os.path.join(directory, "check-integrity.sh"), "w") as f: f.write("#! /bin/sh\n\nsha512sum --check manifest.sha512\n") os.chmod(f.name, 0o500) + shutil.copy("/usr/share/btv/unpack.sh", "unpack.sh") + os.chmod("unpack.sh", 0o500) + ## fix permissions and ownership of created objects outdir_stat = os.stat(outdir) os.chown(directory, outdir_stat.st_uid, outdir_stat.st_gid) diff --git a/unpack.sh b/unpack.sh new file mode 100644 index 0000000..f78a8ba --- /dev/null +++ b/unpack.sh @@ -0,0 +1,24 @@ +#! /bin/zsh + +TIMESTAMP=($(basename "$(pwd)")) +OUTDIR="$1" +KEYFILE="$2" + +function die { + >&2 echo "$2" + exit $1 +} + +[[ "$0" != "./unpack.sh" ]] && die 1 "This can only be executed from the snapshot directory itself." +[[ ! -d "$OUTDIR" ]] && die 1 "The first argument must be a directory to unpack subvolumes into." +[[ ! -f "$KEYFILE" ]] && die 1 "The second argument must be a readable keyfile." +./check-integrity.sh || die 2 "This snapshot failed integrity checks." + +### end of checks + +for ARCHIVE in *btrfs.zst.aes +do + openssl enc -d -aes-256-cbc -pbkdf2 -salt -pass "file:$KEYFILE" < "$ARCHIVE" | zstd -d | btrfs receive "$OUTDIR" || die 3 "Failed to unpack subvolume." + SUBVOL_NAME=${ARCHIVE%%.btrfs.zst.aes} + mv "${OUTDIR}/${SUBVOL_NAME}" "${OUTDIR}/${SUBVOL_NAME}.${TIMESTAMP[1]}" || die 4 "Failed to rename subvolume." +done