summaryrefslogtreecommitdiff
path: root/kodakmoment.sh
blob: 8176e3a8cdb615cf85f04cd4620d83bd372dd2a6 (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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#!/usr/bin/env bash
set -euo pipefail

### CONFIG ###
SOURCE_DIR="/home/doc/genesis-tools"
DEST_HOST="root@backup.sshjunkie.com"
DEST_PATH="/mnt/backup/images/genesis-tools"
REMOTE_LATEST_LINK="$DEST_PATH/latest"
RETENTION_DAYS=7

# Timestamp-based vars (only when running a snapshot)
TIMESTAMP=$(date +%F_%H-%M)
SNAPSHOT_NAME="$TIMESTAMP"
REMOTE_SNAP_DIR="$DEST_PATH/$SNAPSHOT_NAME"

# --dry-run support
DRY_RUN=""
if [[ "${1:-}" == "--dry-run" ]]; then
  echo "๐Ÿงช Running in dry-run mode..."
  DRY_RUN="--dry-run"
fi

# --list support
if [[ "${1:-}" == "--list" ]]; then
  echo "๐Ÿ“‚ Available snapshots on $DEST_HOST:"
  ssh "$DEST_HOST" "ls -1 $DEST_PATH | sort"
  exit 0
fi

# --restore <timestamp> support
if [[ "${1:-}" == "--restore" && -n "${2:-}" ]]; then
  RESTORE_TIMESTAMP="$2"
  RESTORE_REMOTE_PATH="$DEST_PATH/$RESTORE_TIMESTAMP"

  echo "๐Ÿงพ Restoring snapshot $RESTORE_TIMESTAMP from $DEST_HOST..."
  ssh "$DEST_HOST" "[ -d '$RESTORE_REMOTE_PATH' ]" || {
    echo "โŒ Snapshot $RESTORE_TIMESTAMP does not exist."
    exit 1
  }

  echo "โš ๏ธ  This will overwrite files in $SOURCE_DIR with those from snapshot."
  read -rp "Continue? (y/n): " confirm
  if [[ "$confirm" != "y" ]]; then
    echo "โŒ Restore cancelled."
    exit 1
  fi

  rsync -a --delete -e ssh "$DEST_HOST:$RESTORE_REMOTE_PATH/" "$SOURCE_DIR/"
  echo "โœ… Restore from $RESTORE_TIMESTAMP complete."
  exit 0
fi

# Regular snapshot mode starts here
# Verify source directory exists
if [[ ! -d "$SOURCE_DIR" ]]; then
  echo "โŒ ERROR: Source directory $SOURCE_DIR does not exist."
  exit 1
fi

# Make sure destination path exists on the remote
echo "๐Ÿ“‚ Ensuring remote path exists..."
ssh "$DEST_HOST" "mkdir -p '$DEST_PATH'"

# Determine whether to use --link-dest based on presence of 'latest'
REMOTE_LD_OPTION=""
if ssh "$DEST_HOST" "[ -e '$REMOTE_LATEST_LINK' ]"; then
  REMOTE_LD_OPTION="--link-dest=$REMOTE_LATEST_LINK"
else
  echo "โ„น๏ธ  No 'latest' snapshot found โ€” creating full backup."
fi

# Create snapshot via rsync with optional deduplication
echo "๐Ÿ“ธ Creating snapshot: $REMOTE_SNAP_DIR"
rsync -a --delete \
  --exclude="miscellaneous/kodakmoment.sh" \
  $DRY_RUN \
  $REMOTE_LD_OPTION \
  -e ssh "$SOURCE_DIR/" "$DEST_HOST:$REMOTE_SNAP_DIR"

# Only perform post-processing if not a dry-run
if [[ -z "$DRY_RUN" ]]; then
  echo "๐Ÿ”— Updating 'latest' symlink..."
  ssh "$DEST_HOST" "rm -f '$REMOTE_LATEST_LINK'; ln -s '$REMOTE_SNAP_DIR' '$REMOTE_LATEST_LINK'"

  echo "๐Ÿงน Pruning snapshots older than $RETENTION_DAYS days..."
  ssh "$DEST_HOST" "find '$DEST_PATH' -maxdepth 1 -type d -mtime +$RETENTION_DAYS -exec rm -rf {} +"
fi

echo "โœ… KodakMoment complete."