summaryrefslogtreecommitdiff
path: root/coldfreeze.sh
blob: 151552aa41e43d63ec76b047d7b6095fb627eb08 (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
#!/bin/bash

set -euo pipefail

echo "=== Coldfreeze: Turn a full Linux install into a VM image backup ==="
read -rp "Enter source disk to freeze (e.g., /dev/sdb): " SOURCE_DISK
read -rp "Enter destination directory (e.g., /mnt/zfs/legacy-vms): " DEST_DIR

# Confirm disk exists
if [ ! -b "$SOURCE_DISK" ]; then
  echo "ERROR: $SOURCE_DISK is not a valid block device."
  exit 1
fi

# Check mountpoints
MOUNTED=$(lsblk -no MOUNTPOINT "$SOURCE_DISK" | grep -v '^$' || true)
if [ -n "$MOUNTED" ]; then
  echo "ERROR: $SOURCE_DISK has mounted partitions:"
  echo "$MOUNTED"
  echo "Please unmount them before continuing."
  exit 1
fi

# Confirm before starting
echo "About to clone $SOURCE_DISK to $DEST_DIR"
read -rp "Continue? (yes/no): " CONFIRM
[[ "$CONFIRM" != "yes" ]] && echo "Aborted." && exit 0

TIMESTAMP=$(date +%Y%m%d-%H%M%S)
OUTFILE="coldfreeze-$(basename "$SOURCE_DISK")-$TIMESTAMP.img"
OUTPATH="$DEST_DIR/$OUTFILE"

# Run dd
echo "[+] Starting dd... This may take a while."
sudo dd if="$SOURCE_DISK" of="$OUTPATH" bs=1M status=progress conv=fsync

# Compress with zstd
echo "[+] Compressing with zstd..."
zstd -T0 "$OUTPATH" && rm "$OUTPATH"
COMPRESSED_FILE="$OUTPATH.zst"

# Write metadata
echo "[+] Writing metadata..."
cat > "$DEST_DIR/$OUTFILE.txt" <<EOF
Coldfreeze Backup

Source Disk: $SOURCE_DISK
Saved As: $COMPRESSED_FILE
Created: $TIMESTAMP
Run from Host: $(hostname)
Disk Size: $(lsblk -dn -o SIZE "$SOURCE_DISK")
Note: Created with coldfreeze.sh – raw dd clone of full disk for virtualization or file recovery.

To restore or mount:
1. zstd -d $OUTFILE.zst
2. Use qemu-img convert to make a Proxmox disk
3. Or loop-mount with losetup + kpartx

EOF

echo "[✓] Disk frozen, compressed, and metadata written to:"
echo "    $COMPRESSED_FILE"