Skip to content

Instantly share code, notes, and snippets.

@thimslugga
Forked from usrflo/lxc-sync-README
Created July 11, 2021 23:46
Show Gist options
  • Save thimslugga/da0d9953651a53b7d85b139345a3c8fe to your computer and use it in GitHub Desktop.
Save thimslugga/da0d9953651a53b7d85b139345a3c8fe to your computer and use it in GitHub Desktop.
lxc copy --refresh workaround: efficient incremental ZFS snapshot sync with send/receive
LXCBIN=/snap/bin/lxc
LXDBIN=/snap/bin/lxd
ZFSBIN=/sbin/zfs
SYNCSNAPNAME=bsync
LASTSYNCSNAPNAME=bsync-last
ZFSROOT=tank/containers/
MOUNTROOT=/var/snap/lxd/common/lxd/storage-pools/
# Array of containers to synchronize
declare -A SYNCCONT
declare -A SYNCCONTDETAIL
# sample container 1
SYNCCONTDETAIL["lxcremote"]='srcserver'
SYNCCONTDETAIL["sshcmd"]='ssh -p2222 -oStrictHostKeyChecking=no root@srcserver'
string=$(declare -p SYNCCONTDETAIL)
SYNCCONT['samplecont1']=${string}
# sample container 2
SYNCCONTDETAIL["lxcremote"]='srcserver'
SYNCCONTDETAIL["sshcmd"]='ssh -p2222 -oStrictHostKeyChecking=no root@srcserver'
string=$(declare -p SYNCCONTDETAIL)
SYNCCONT['samplecont2']=${string}
#!/bin/bash
# This script is meant to run on the sync target server that syncs remote container snapshots to local;
# remote and local containers may be running; a remote container is snapshotted and this
# snapshot will be restored on the local receiving container.
#
# IMPORTANT:
# - in the local lxc configuration all remotes needs to be configured (see `lxc remote list`)
# - ssh access to the remote/source servers needs to be available to execute remote zfs send
#
# Florian Sager, [email protected], 2021-02-23
set -e
# set -x
DIR="${BASH_SOURCE%/*}"
if [[ ! -d "$DIR" ]]; then DIR="$PWD"; fi
. "$DIR/lxc-sync-config"
. "$DIR/lxc-sync-containers"
function localtargetexists {
local CONTNAME=$1
$LXCBIN info $CONTNAME > /dev/null
RETVAL=$?
return $([ "$RETVAL" == 0 ] && echo 1 || echo 0)
}
function initsync {
local CONTNAME=$1
local LXCREMOTE=$2
local SSHCMD=$3
$LXCBIN snapshot $LXCREMOTE:$CONTNAME $SYNCSNAPNAME
$LXCBIN copy $LXCREMOTE:$CONTNAME/$SYNCSNAPNAME $CONTNAME
$LXCBIN snapshot $CONTNAME $SYNCSNAPNAME
$ZFSBIN destroy -r $ZFSROOT$CONTNAME
$ZFSBIN create -o mountpoint=$MOUNTROOT$ZFSROOT$CONTNAME $ZFSROOT$CONTNAME
$SSHCMD $ZFSBIN send -c -L $ZFSROOT$CONTNAME@snapshot-$SYNCSNAPNAME | $ZFSBIN receive -Fu $ZFSROOT$CONTNAME
}
function incrementalsync {
local CONTNAME=$1
local LXCREMOTE=$2
local SSHCMD=$3
set +e
$LXCBIN delete $LXCREMOTE:$CONTNAME/$LASTSYNCSNAPNAME
set -e
$LXCBIN rename $LXCREMOTE:$CONTNAME/$SYNCSNAPNAME $LXCREMOTE:$CONTNAME/$LASTSYNCSNAPNAME
$LXCBIN snapshot $LXCREMOTE:$CONTNAME $SYNCSNAPNAME
$ZFSBIN rename $ZFSROOT$CONTNAME@snapshot-$SYNCSNAPNAME $ZFSROOT$CONTNAME@snapshot-$LASTSYNCSNAPNAME
$SSHCMD $ZFSBIN send -c -L -i $ZFSROOT$CONTNAME@snapshot-$LASTSYNCSNAPNAME $ZFSROOT$CONTNAME@snapshot-$SYNCSNAPNAME | $ZFSBIN receive -Fu $ZFSROOT$CONTNAME
$ZFSBIN destroy $ZFSROOT$CONTNAME@snapshot-$LASTSYNCSNAPNAME
$LXCBIN restore $CONTNAME $SYNCSNAPNAME
$LXDBIN sql global "UPDATE instances_snapshots SET creation_date=datetime('now') WHERE instance_id=(SELECT id FROM instances WHERE name='$CONTNAME') AND name='$SYNCSNAPNAME';" > /dev/null
}
for CONTNAME in "${!SYNCCONT[@]}"; do
eval "${SYNCCONT["$CONTNAME"]}"
set +e
localtargetexists $CONTNAME
CONTEXISTS=$?
set -e
if [ $CONTEXISTS == 0 ]; then
initsync "$CONTNAME" "${SYNCCONTDETAIL['lxcremote']}" "${SYNCCONTDETAIL['sshcmd']}"
else
incrementalsync "$CONTNAME" "${SYNCCONTDETAIL['lxcremote']}" "${SYNCCONTDETAIL['sshcmd']}"
fi
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment