67 lines
		
	
	
	
		
			2.5 KiB
		
	
	
	
		
			Bash
		
	
	
	
	
	
			
		
		
	
	
			67 lines
		
	
	
	
		
			2.5 KiB
		
	
	
	
		
			Bash
		
	
	
	
	
	
| #!/bin/bash
 | |
| 
 | |
| set -eu
 | |
| 
 | |
| path=$1
 | |
| uuid=$(jq -r .client_uuid < /etc/backup/config.json)
 | |
| server=$(jq -r .server_hostname < /etc/backup/config.json)
 | |
| ssh="ssh -o ConnectTimeout=5 backup-receiver@$server"
 | |
| 
 | |
| source_dataset=$(zfs list -H -o mountpoint,name | grep -P "^$path\t" | cut -d $'\t' -f 2)
 | |
| target_dataset="tank/$uuid/$source_dataset"
 | |
| target_dataset_parent=$(echo $target_dataset | rev | cut -d / -f 2- | rev)
 | |
| bookmark_prefix="auto-backup_"
 | |
| new_bookmark="$bookmark_prefix$(date +"%Y-%m-%d_%H:%M:%S")"
 | |
| 
 | |
| for var in path uuid server ssh source_dataset target_dataset target_dataset_parent new_bookmark
 | |
| do
 | |
|   [[ -z "${!var}" ]] && echo "ERROR - $var is empty" && exit 96
 | |
| done
 | |
| 
 | |
| $ssh true || (echo "ERROR - cant ssh connect to $server" && exit 97)
 | |
| 
 | |
| echo "BACKUP ZFS DATASET - PATH: $path, SERVER: $server, UUID: $uuid, SOURCE_DATASET: $source_dataset, TARGET_DATASET: $target_dataset"
 | |
| 
 | |
| if ! $ssh sudo zfs list -t filesystem -H -o name | grep -q "^$target_dataset_parent$"
 | |
| then
 | |
|   echo "CREATING PARENT DATASET..."
 | |
|   $ssh sudo zfs create -p -o mountpoint=none "$target_dataset_parent"
 | |
| fi
 | |
| 
 | |
| zfs snap "$source_dataset@$new_bookmark"
 | |
| 
 | |
| if zfs list -t bookmark -H -o name | grep "^$source_dataset#$bookmark_prefix" | wc -l | grep -q "^0$"
 | |
| then
 | |
|   echo "INITIAL BACKUP"
 | |
|   # do in subshell, otherwise ctr+c will lead to 0 exitcode
 | |
|   $(zfs send -v "$source_dataset@$new_bookmark" | $ssh sudo zfs recv -F "$target_dataset")
 | |
| else
 | |
|   echo "INCREMENTAL BACKUP"
 | |
|   last_bookmark=$(zfs list -t bookmark -H -o name | grep "^$source_dataset#$bookmark_prefix" | sort | tail -1 | cut -d '#' -f 2)
 | |
|   [[ -z "$last_bookmark" ]] && echo "ERROR - last_bookmark is empty" && exit 98
 | |
|   $(zfs send -v -L -i "#$last_bookmark" "$source_dataset@$new_bookmark" | $ssh sudo zfs recv "$target_dataset")
 | |
| fi
 | |
| 
 | |
| if [[ "$?" == "0" ]]
 | |
| then
 | |
| 
 | |
|   # delete old local bookmarks
 | |
|   for destroyable_bookmark in $(zfs list -t bookmark -H -o name "$source_dataset" | grep "^$source_dataset#$bookmark_prefix")
 | |
|   do
 | |
|     zfs destroy "$destroyable_bookmark"
 | |
|   done
 | |
| 
 | |
|   # delete remote snapshots from bookmarks (except newest, even of not necessary; maybe for resuming tho)
 | |
|   for destroyable_snapshot in $($ssh sudo zfs list -t snapshot -H -o name "$target_dataset" | grep "^$target_dataset@$bookmark_prefix" | grep -v "$new_bookmark")
 | |
|   do
 | |
|     $ssh sudo zfs destroy "$destroyable_snapshot"
 | |
|   done
 | |
| 
 | |
|   zfs bookmark "$source_dataset@$new_bookmark" "$source_dataset#$new_bookmark"
 | |
|   zfs destroy "$source_dataset@$new_bookmark" # keep snapshots?
 | |
|   echo "SUCCESS"
 | |
| else
 | |
|   zfs destroy "$source_dataset@$new_bookmark"
 | |
|   echo "ERROR"
 | |
|   exit 99
 | |
| fi
 |