mirror of
https://asciireactor.com/o4data/zfs-backup.git
synced 2024-11-22 07:35:05 +00:00
Update to working state.
This commit is contained in:
parent
0990f17d87
commit
a2707d116d
226
backup.sh
226
backup.sh
@ -2,123 +2,160 @@
|
|||||||
|
|
||||||
nodes_file="nodes.txt"
|
nodes_file="nodes.txt"
|
||||||
### nodes.txt
|
### nodes.txt
|
||||||
# <local hostname> <local ssh port> <this host's root zfs> <this host's user>
|
# <origin host> <user> <ssh port> <timezone> <compressed flag>
|
||||||
# <remote host 1 address> <host 1 ssh port> <host 1 root zfs>
|
# <mirror 1 host> <user> <ssh port> <zfs root>
|
||||||
# <remote host 2 address> <host 2 ssh port> <host 2 root zfs>
|
# <mirror 2 host> <user> <ssh port> <zfs root>
|
||||||
# ...
|
# ...
|
||||||
|
|
||||||
datasets_file="datasets.txt"
|
datasets_file="datasets.txt"
|
||||||
### datasets.txt
|
### datasets.txt
|
||||||
# <dataset 1>
|
# <dataset 1>
|
||||||
# <dataset 1>/<dataset 1a>
|
# <dataset 2>
|
||||||
# <dataset 1>/<dataset 1b>
|
|
||||||
# <dataset 2>/<dataset 2a>
|
|
||||||
# <dataset 3>
|
# <dataset 3>
|
||||||
# ...
|
# ...
|
||||||
|
|
||||||
list_active_datasets()
|
if [ ! -f $nodes_file ]; then echo "No nodes specified."; exit 2; fi
|
||||||
{
|
if [ ! -f $datasets_file ]; then echo "No datasets specified."; exit 3; fi
|
||||||
zfs list | tail -n +2 | cut -d' ' -f1|grep ${BG_ROOT}
|
|
||||||
}
|
|
||||||
|
|
||||||
# compare_datasets()
|
ZFS_SEND_OPTS="-R"
|
||||||
|
ZFS_SNAPSHOT_OPTS="-r"
|
||||||
|
ZFS_RECV_OPTS="-svu"
|
||||||
|
|
||||||
create_datasets() {
|
read LOCAL_HOST LOCAL_USER LOCAL_PORT LOCAL_TZ SEND_COMPRESSED < $nodes_file
|
||||||
# should compare_datasets and only create missing or possibly error.
|
case $SEND_COMPRESSED in
|
||||||
|
[tTyY]*) ZFS_SEND_OPTS="$ZFS_SEND_OPTS -c" ;;
|
||||||
|
esac
|
||||||
|
|
||||||
for dataset in `cat ${datasets_file}`; do
|
ORIGIN_PERMS="send,snapshot,hold"
|
||||||
|
MIRROR_PERMS="compression,mountpoint,receive,create,mount"
|
||||||
|
|
||||||
|
GRAPH_DATASETS_RAW=`cat $datasets_file`
|
||||||
|
GRAPH_DATASETS=`for dataset in $GRAPH_DATASETS_RAW; do
|
||||||
case $dataset in
|
case $dataset in
|
||||||
\#*) continue;;
|
\#*) continue;;
|
||||||
esac
|
esac
|
||||||
if [ $BG_TEST_MODE = "TRUE" ]; then
|
echo -n "$dataset "
|
||||||
echo zfs create -p ${BG_ROOT}/$dataset
|
done`
|
||||||
else
|
|
||||||
zfs create -p ${BG_ROOT}/$dataset
|
list_datasets()
|
||||||
fi
|
{
|
||||||
|
for dataset in $GRAPH_DATASETS; do
|
||||||
|
zfs list -H $dataset
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
|
list_remote_datasets() {
|
||||||
|
while read addr user ssh_port zroot; do
|
||||||
|
echo "=== $user@$addr $zroot ==="
|
||||||
|
if [ $BG_TEST_MODE = "TRUE" ]; then
|
||||||
|
echo ssh -i ~/.ssh/id_rsa -o port=$ssh_port $user@$addr\
|
||||||
|
"sh -c 'for dataset in $GRAPH_DATASETS;
|
||||||
|
do zfs list -H $zroot/\$dataset;
|
||||||
|
done'"
|
||||||
|
else
|
||||||
|
ssh -i ~/.ssh/id_rsa -o port=$ssh_port $user@$addr \
|
||||||
|
"sh -c 'for dataset in $GRAPH_DATASETS;
|
||||||
|
do zfs list -H $zroot/\$dataset;
|
||||||
|
done';"
|
||||||
|
fi
|
||||||
|
done < sendnodes.tmp
|
||||||
|
}
|
||||||
|
|
||||||
get_latest_snapshot()
|
get_latest_snapshot()
|
||||||
{
|
{
|
||||||
zfs list -t snapshot |
|
zfs list -t snapshot $dataset | tail -n1 | cut -d'@' -f2 | cut -d' ' -f 1
|
||||||
grep ${BG_ROOT} |
|
|
||||||
tail -n1 |
|
|
||||||
cut -d'@' -f2 |
|
|
||||||
cut -d' ' -f 1
|
|
||||||
}
|
}
|
||||||
|
|
||||||
setup_aggregator()
|
get_latest_remote_snapshot()
|
||||||
{
|
{
|
||||||
create_datasets
|
ssh -i ~/.ssh/id_rsa -o port=$ssh_port $user@$addr \
|
||||||
|
"zfs list -t snapshot $zroot/$dataset |
|
||||||
|
tail -n1|cut -d'@' -f2|cut -d' ' -f 1"
|
||||||
|
}
|
||||||
|
|
||||||
|
zfs_allow_origin()
|
||||||
|
{
|
||||||
|
for dataset in $GRAPH_DATASETS; do
|
||||||
if [ $BG_TEST_MODE = "TRUE" ]; then
|
if [ $BG_TEST_MODE = "TRUE" ]; then
|
||||||
echo zfs allow -u ${BG_USER} send,snapshot,hold ${BG_ROOT}
|
echo zfs allow -u $LOCAL_USER $ORIGIN_PERMS $dataset
|
||||||
else
|
else
|
||||||
zfs allow -u ${BG_USER} send,snapshot,hold ${BG_ROOT}
|
zfs allow -u $LOCAL_USER $ORIGIN_PERMS $dataset
|
||||||
fi
|
fi
|
||||||
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
setup_mirror()
|
zfs_allow_mirrors()
|
||||||
{
|
{
|
||||||
|
while read addr user ssh_port zroot; do
|
||||||
|
echo "=== $user@$addr $zroot ==="
|
||||||
if [ $BG_TEST_MODE = "TRUE" ]; then
|
if [ $BG_TEST_MODE = "TRUE" ]; then
|
||||||
echo zfs allow -u ${BG_USER} send,snapshot,hold ${BG_ROOT}
|
echo ssh -i ~/.ssh/id_rsa -o port=$ssh_port $user@$addr \
|
||||||
echo zfs allow -u ${BG_USER} \
|
"for dataset in $GRAPH_DATASETS; do
|
||||||
compression,mountpoint,receive,create,mount ${BG_ROOT}
|
zfs allow -u $user $MIRROR_PERMS $zroot/\$dataset
|
||||||
|
done"
|
||||||
else
|
else
|
||||||
zfs allow -u ${BG_USER} send,snapshot,hold ${BG_ROOT}
|
ssh -i ~/.ssh/id_rsa -o port=$ssh_port $user@$addr \
|
||||||
zfs allow -u ${BG_USER} \
|
"for dataset in $GRAPH_DATASETS; do
|
||||||
compression,mountpoint,receive,create,mount ${BG_ROOT}
|
zfs allow -u $user $MIRROR_PERMS $zroot/\$dataset
|
||||||
fi
|
done"
|
||||||
}
|
|
||||||
|
|
||||||
create_snapshot()
|
|
||||||
{
|
|
||||||
id="`date -I`-`date +%s`"
|
|
||||||
if [ $BG_TEST_MODE = "TRUE" ]; then
|
|
||||||
echo zfs snapshot -r ${BG_ROOT}@${id}
|
|
||||||
else
|
|
||||||
zfs snapshot -r ${BG_ROOT}@${id}
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
send_single_snapshot()
|
|
||||||
{
|
|
||||||
BG_NEW_SNAPSHOT=`get_latest_snapshot`
|
|
||||||
tail -n +2 ${nodes_file} > sendnodes.tmp
|
|
||||||
while read BG_REMOTE_ADDR BG_REMOTE_PORT BG_REMOTE_ROOT BG_REMOTE_USER; do
|
|
||||||
case $BG_REMOTE_ADDR in
|
|
||||||
\#*) continue;;
|
|
||||||
esac
|
|
||||||
if [ $BG_TEST_MODE = "TRUE" ]; then
|
|
||||||
echo zfs send -R ${BG_ROOT}@${BG_NEW_SNAPSHOT}
|
|
||||||
echo ssh -i ~/.ssh/id_rsa -o port=${BG_REMOTE_PORT} \
|
|
||||||
${BG_REMOTE_USER}@${BG_REMOTE_ADDR} \
|
|
||||||
zfs receive -sdvu ${BG_REMOTE_ROOT}
|
|
||||||
else
|
|
||||||
zfs send -R ${BG_ROOT}@${BG_NEW_SNAPSHOT} |
|
|
||||||
ssh -i ~/.ssh/id_rsa -o port=${BG_REMOTE_PORT} \
|
|
||||||
${BG_REMOTE_USER}@${BG_REMOTE_ADDR} \
|
|
||||||
zfs receive -sdvu ${BG_REMOTE_ROOT}
|
|
||||||
fi
|
fi
|
||||||
done < sendnodes.tmp
|
done < sendnodes.tmp
|
||||||
rm sendnodes.tmp
|
|
||||||
if [ $BG_TEST_MODE = "TRUE" ]; then
|
|
||||||
:
|
|
||||||
else
|
|
||||||
echo $BG_NEW_SNAPSHOT > "old-snapshot.txt"
|
|
||||||
fi
|
|
||||||
}
|
}
|
||||||
|
|
||||||
send_incremental_snapshot()
|
create_snapshots()
|
||||||
{
|
{
|
||||||
BG_NEW_SNAPSHOT=`get_latest_snapshot`
|
snapshot_id="`date -I`-`date +%s`-$LOCAL_TZ"
|
||||||
echo Will send $BG_NEW_SNAPSHOT
|
for dataset in $GRAPH_DATASETS; do
|
||||||
#while read BG_REMOTE_ADDR BG_REMOTE_PORT BG_REMOTE_ROOT BG_REMOTE_USER; do
|
if [ $BG_TEST_MODE = "TRUE" ]; then
|
||||||
# zfs send -R -i `cat old-snapshot.txt` ${BG_ROOT}@${BG_NEW_SNAPSHOT} |
|
echo zfs snapshot $ZFS_SNAPSHOT_OPTS $dataset@$snapshot_id
|
||||||
# ssh -i ~/.ssh/id_rsa -o port=${BG_REMOTE_PORT} \
|
else
|
||||||
# ${BG_REMOTE_USER}@${BG_REMOTE_ADDR} \
|
zfs snapshot $ZFS_SNAPSHOT_OPTS $dataset@$snapshot_id
|
||||||
# zfs receive -sdvu ${BG_REMOTE_ROOT}@${BG_NEW_SNAPSHOT}
|
fi
|
||||||
#done
|
done
|
||||||
echo $BG_NEW_SNAPSHOT > "old-snapshot.txt"
|
}
|
||||||
|
|
||||||
|
send_latest()
|
||||||
|
{
|
||||||
|
while read addr user ssh_port zroot; do
|
||||||
|
echo "=== $user@$addr $zroot ==="
|
||||||
|
for dataset in $GRAPH_DATASETS; do
|
||||||
|
origin_snapshot=`get_latest_snapshot $dataset`
|
||||||
|
if [ $BG_TEST_MODE = "TRUE" ]; then
|
||||||
|
echo zfs send $ZFS_SEND_OPTS $dataset@$origin_snapshot \| \
|
||||||
|
ssh -i ~/.ssh/id_rsa -o port=$ssh_port $user@$addr \
|
||||||
|
zfs recv $ZFS_RECV_OPTS $zroot/$dataset
|
||||||
|
else
|
||||||
|
zfs send $ZFS_SEND_OPTS $dataset@$origin_snapshot |
|
||||||
|
ssh -i ~/.ssh/id_rsa -o port=$ssh_port \
|
||||||
|
$user@$addr \
|
||||||
|
zfs recv $ZFS_RECV_OPTS $zroot/$dataset
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
done < sendnodes.tmp
|
||||||
|
}
|
||||||
|
|
||||||
|
send_increment()
|
||||||
|
{
|
||||||
|
while read addr user ssh_port zroot; do
|
||||||
|
echo "=== $user@$addr $zroot ==="
|
||||||
|
for dataset in $GRAPH_DATASETS; do
|
||||||
|
origin_snapshot=`get_latest_snapshot`
|
||||||
|
remote_snapshot=`get_latest_remote_snapshot`
|
||||||
|
if [ $BG_TEST_MODE = "TRUE" ]; then
|
||||||
|
echo zfs send $ZFS_SEND_OPTS \
|
||||||
|
-i $dataset@$remote_snapshot \
|
||||||
|
$dataset@$origin_snapshot \| \
|
||||||
|
ssh -i ~/.ssh/id_rsa -o port=$ssh_port $user@$addr \
|
||||||
|
zfs recv $ZFS_RECV_OPTS $zroot/$dataset
|
||||||
|
else
|
||||||
|
zfs send $ZFS_SEND_OPTS \
|
||||||
|
-i $dataset@$remote_snapshot \
|
||||||
|
$dataset@$origin_snapshot |
|
||||||
|
ssh -i ~/.ssh/id_rsa -o port=$ssh_port $user@$addr \
|
||||||
|
zfs recv $ZFS_RECV_OPTS $zroot/$dataset
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
done < sendnodes.tmp
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -141,21 +178,18 @@ while :; do
|
|||||||
shift
|
shift
|
||||||
done
|
done
|
||||||
|
|
||||||
read BG_HOST BG_PORT BG_ROOT BG_USER < ${nodes_file}
|
tail -n +2 $nodes_file|grep -v '^#' > sendnodes.tmp
|
||||||
|
|
||||||
if [ ! -f ${nodes_file} ]; then echo "No nodes specified."; exit 2; fi
|
|
||||||
|
|
||||||
### Command
|
### Command
|
||||||
case "$1" in
|
case "$1" in
|
||||||
list) list_active_datasets ;;
|
list) list_datasets ;;
|
||||||
create) create_snapshot ;;
|
list-remote) list_remote_datasets ;;
|
||||||
setup-mirror) setup_mirror ;;
|
snapshot) create_snapshots ;;
|
||||||
setup-aggregator) setup_aggregator ;;
|
configure-mirrors) zfs_allow_mirrors ;;
|
||||||
send)
|
configure-origin) zfs_allow_origin ;;
|
||||||
if [ -f "old-snapshot.txt" ]; then
|
mirror-reset) send_latest ;;
|
||||||
send_incremental_snapshot
|
mirror-increment) send_increment ;;
|
||||||
else
|
#mirror-prune) send_increment_with_F ;;
|
||||||
send_single_snapshot
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
esac
|
esac
|
||||||
|
|
||||||
|
rm sendnodes.tmp
|
Loading…
Reference in New Issue
Block a user