#!/bin/bash # zfs-replicate - Replicate ZFS datasets to TrueNAS # # Usage: # zfs-replicate # Replicate all configured datasets # zfs-replicate [dataset] # Replicate specific dataset set -e # TrueNAS Configuration # Try local network first, fall back to tailscale TRUENAS_LOCAL="truenas.local" TRUENAS_TAILSCALE="truenas" TRUENAS_USER="root" TRUENAS_POOL="vault" BACKUP_PATH="backups" # TODO: Configure actual path # Datasets to replicate DATASETS="zroot/ROOT/default zroot/home zroot/media zroot/vms" # Colors GREEN='\033[0;32m' YELLOW='\033[1;33m' RED='\033[0;31m' NC='\033[0m' info() { echo -e "${GREEN}[INFO]${NC} $1"; } warn() { echo -e "${YELLOW}[WARN]${NC} $1"; } error() { echo -e "${RED}[ERROR]${NC} $1"; exit 1; } command -v syncoid >/dev/null 2>&1 || error "syncoid not found. Install sanoid package." # Determine which host to use determine_host() { if ping -c 1 -W 2 "$TRUENAS_LOCAL" &>/dev/null; then echo "$TRUENAS_LOCAL" elif ping -c 1 -W 2 "$TRUENAS_TAILSCALE" &>/dev/null; then echo "$TRUENAS_TAILSCALE" else error "Cannot reach TrueNAS at $TRUENAS_LOCAL or $TRUENAS_TAILSCALE" fi } TRUENAS_HOST=$(determine_host) info "Using TrueNAS host: $TRUENAS_HOST" # Single dataset mode if [[ -n "$1" ]]; then dataset="$1" dest="$TRUENAS_USER@$TRUENAS_HOST:$TRUENAS_POOL/$BACKUP_PATH/${dataset#zroot/}" info "Replicating $dataset -> $dest" syncoid --recursive "$dataset" "$dest" exit 0 fi # Full replication info "Starting ZFS replication to $TRUENAS_HOST" echo "" for dataset in $DATASETS; do dest="$TRUENAS_USER@$TRUENAS_HOST:$TRUENAS_POOL/$BACKUP_PATH/${dataset#zroot/}" info "Replicating $dataset -> $dest" if syncoid --recursive "$dataset" "$dest"; then info " Success" else warn " Failed (will retry next run)" fi echo "" done info "Replication complete."