summaryrefslogtreecommitdiff
path: root/tarship.sh
blob: 661d77b0f8313afb8caaeeb0b7131b0fa6eafe09 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#!/bin/bash
set -e
USAGE="Usage: $0 {backup /dir [user@host:]/dest | restore file.tar.gz}"
dnf install -y tar pigz pv openssh-clients &>/dev/null || exit 1

case "${1:?$USAGE}" in
backup)
    SRC="${2:?$USAGE}" DEST="${3:?$USAGE}" NAME="$(basename "$SRC").tar.gz"
    [ ! -d "$SRC" ] && echo "Error: not a directory: $SRC" && exit 1
    du -sh "$SRC"; SIZE=$(du -sb "$SRC" | awk '{print $1}'); LHASH=$(mktemp); trap "rm -f $LHASH" EXIT
    if [[ "$DEST" == *:* ]]; then # remote: tar+pigz stream over ssh, tee hash both sides
        H="${DEST%%:*}" D="${DEST#*:}"; echo "→ ${H}:${D}/${NAME}"
        RHASH=$(tar cf - "$SRC" | pv -s "$SIZE" | pigz -1 | tee >(sha256sum | awk '{print $1}' > "$LHASH") | ssh "$H" "h=\$(tee ${D}/${NAME} | sha256sum | awk '{print \$1}'); echo \$h > ${D}/${NAME}.sha256; echo \$h")
        L=$(cat "$LHASH"); echo "Local:  $L"; echo "Remote: $RHASH"
        [ "$L" = "$RHASH" ] && echo "Checksum OK" || { echo "CHECKSUM MISMATCH!"; exit 1; }
        echo "Verify:  ssh $H \"sha256sum ${D}/${NAME}\""
    else # local: tar+pigz to file, write .sha256 sidecar
        echo "→ $DEST/$NAME"
        tar cf - "$SRC" | pv -s "$SIZE" | pigz -1 > "$DEST/$NAME"
        sha256sum "$DEST/$NAME" | awk '{print $1}' > "$DEST/$NAME.sha256"
        echo "Checksum: $(cat "$DEST/$NAME.sha256")"
        echo "Verify:  sha256sum $DEST/$NAME"
    fi ;;
restore)
    FILE="${2:?$USAGE}"
    [[ "$FILE" == *.tar.gz ]] && [ -f "$FILE" ] || { echo "Error: not a .tar.gz file: $FILE"; exit 1; }
    echo "$FILE ($(numfmt --to=iec $(stat -c%s "$FILE"))) → $(pwd)"
    if [ -f "$FILE.sha256" ]; then # verify checksum before extracting
        echo "Verifying..."; EXP=$(cat "$FILE.sha256"); ACT=$(sha256sum "$FILE" | awk '{print $1}')
        [ "$EXP" = "$ACT" ] && echo "Checksum OK" || { echo "CHECKSUM MISMATCH!"; exit 1; }
    else echo "Warning: no .sha256 file, skipping verification"; fi
    pv "$FILE" | pigz -d | tar xf - ;;
*) echo "$USAGE"; exit 1 ;;
esac
echo "Done"