#!/bin/bash CONTS_LIST=$(lxc list | grep "RUNNING\|STOPPED" | awk {'print $2'}) let i=0 W=() while read -r line; do let i=$i+1 W+=($i "$line" off) done < <( echo "$CONTS_LIST" ) CONTS=$(dialog --checklist "Choose containers to copy" 24 80 17 "${W[@]}" 3>&2 2>&1 1>&3) DEST_IP=$(dialog --inputbox "Enter destination IP:" 25 25 --output-fd 1) DEST_PORT=$(dialog --inputbox "Enter destination SSH port(leave blank for default 22):" 25 25 --output-fd 1) [ -z "$DEST_PORT" ] && DEST_PORT=22 DEST_ZPOOL=$(echo crypt) DEST_ZPOOL_2=$(echo storage) DATASETS=$(zfs list) SNAPS=$(zfs list -t snapshot) DEST_SNAPS=$(ssh $DEST_IP -p $DEST_PORT zfs list -t snapshot) bionic_checker=$(ssh $DEST_IP -p $DEST_PORT lsb_release -c | awk {'print $2'}) for CONT in $CONTS; do CONT_VAR=$(echo "$CONTS_LIST"| sed -n "`echo "$CONT p" | sed 's/ //'`") SNAPS_CLEANED=$(echo "$SNAPS" | grep crypt | grep lxd | grep storage | grep containers | grep -E "....-..-.._........--.d" | awk {'print $1'} | grep "$CONT_VAR"@) DEST_SNAPS_CLEANED=$(echo "$DEST_SNAPS" | grep crypt | grep lxd | grep storage | grep containers | grep -E "....-..-.._........--.d" | awk {'print $1'} | grep "$CONT_VAR"@) SOURCE_DEST_IDENTICAL_SNAPS=$(grep -Fxf <(echo "$SNAPS_CLEANED") <(echo "$DEST_SNAPS_CLEANED")) SNAP_TO_SEND_FIRST=$(echo "$SOURCE_DEST_IDENTICAL_SNAPS" | tail -n1) DATASET_VAR=$(echo "$DATASETS" | grep crypt | grep lxd | grep storage | grep containers | awk {'print $1'} | grep -E "$CONT_VAR"$) SNAP_TO_SEND_FIRST_FOR_LATER_CHECK=$(echo "$SNAP_TO_SEND_FIRST") IFS=" " if [ -z "$SNAP_TO_SEND_FIRST" ] then echo "Start move "$CONT_VAR"" if [ -z "$SNAPS_CLEANED" ] then echo "Creating first snapshot" for command in $(zfSnap -n -zpool28fix -a 7d "$DATASET_VAR" | grep snapshot | grep "$DATASET_VAR") do SNAP_TO_SEND_FIRST=$(echo "$command" | awk '{print $3}') echo "Doing "$command"" eval "$command"; done else SNAP_TO_SEND_FIRST=$(echo "$SNAPS_CLEANED" | tail -n 12 | head -n 1) fi echo "Sending first snapshot" echo "Sending "$SNAP_TO_SEND_FIRST"" zfs send "$SNAP_TO_SEND_FIRST" | pv | ssh "$DEST_IP" -p $DEST_PORT zfs recv "$DEST_ZPOOL"/lxd/storage/containers/"$CONT_VAR" echo "Sleep 2" sleep 2 fi echo "Start move "$CONT_VAR"" echo "Creating second snapshot" for command in $(zfSnap -n -zpool28fix -a 7d "$DATASET_VAR" | grep snapshot | grep "$DATASET_VAR") do SNAP_TO_SEND_SECOND=$(echo "$command" | awk '{print $3}') echo "Doing "$command"" eval "$command"; done echo "Sending second snapshot" echo "Sending "$SNAP_TO_SEND_FIRST" to "$SNAP_TO_SEND_SECOND" with -I parameter" zfs send -I "$SNAP_TO_SEND_FIRST" "$SNAP_TO_SEND_SECOND" | pv | ssh "$DEST_IP" -p $DEST_PORT zfs recv "$DEST_ZPOOL"/lxd/storage/containers/"$CONT_VAR" -F echo "Sleep 2" sleep 2 echo "Creating third snapshot" for command in $(zfSnap -n -zpool28fix -a 7d "$DATASET_VAR" | grep snapshot | grep "$DATASET_VAR") do SNAP_TO_SEND_THIRD=$(echo "$command" | awk '{print $3}') echo "Doing "$command"" eval "$command"; done echo "Sending third snapshot" echo "Sending "$SNAP_TO_SEND_SECOND" to "$SNAP_TO_SEND_THIRD"" zfs send -i "$SNAP_TO_SEND_SECOND" "$SNAP_TO_SEND_THIRD" | pv | ssh "$DEST_IP" -p $DEST_PORT zfs recv "$DEST_ZPOOL"/lxd/storage/containers/"$CONT_VAR" -F echo "Sleep 2" sleep 2 echo "Creating fourth snapshot" for command in $(zfSnap -n -zpool28fix -a 7d "$DATASET_VAR" | grep snapshot | grep "$DATASET_VAR") do SNAP_TO_SEND_FOURTH=$(echo "$command" | awk '{print $3}') echo "Doing "$command"" eval "$command"; done echo "Sending fourth snapshot" echo "Sending "$SNAP_TO_SEND_THIRD" to "$SNAP_TO_SEND_FOURTH"" zfs send -i "$SNAP_TO_SEND_THIRD" "$SNAP_TO_SEND_FOURTH" | pv | ssh "$DEST_IP" -p $DEST_PORT zfs recv "$DEST_ZPOOL"/lxd/storage/containers/"$CONT_VAR" -F echo "Sleep 2" sleep 2 echo "Stopping "$CONT_VAR" on source" lxc stop "$CONT_VAR" echo "Sleep 2" sleep 2 echo "Creating fifth snapshot" for command in $(zfSnap -n -zpool28fix -a 7d "$DATASET_VAR" | grep snapshot | grep "$DATASET_VAR") do SNAP_TO_SEND_FIFTH=$(echo "$command" | awk '{print $3}') echo "Doing "$command"" eval "$command"; done echo "Sending fifth snapshot" echo "Sending "$SNAP_TO_SEND_FOURTH" to "$SNAP_TO_SEND_FIFTH"" zfs send -i "$SNAP_TO_SEND_FOURTH" "$SNAP_TO_SEND_FIFTH" | pv | ssh "$DEST_IP" -p $DEST_PORT zfs recv "$DEST_ZPOOL"/lxd/storage/containers/"$CONT_VAR" -F if [ $bionic_checker == bionic ] then if [ -z "$SNAP_TO_SEND_FIRST_FOR_LATER_CHECK" ] then echo "Setting up mountpoint on destination for "$CONT_VAR"" ssh "$DEST_IP" -p $DEST_PORT zfs set mountpoint=/var/lib/lxd/storage-pools/"$DEST_ZPOOL_2"/containers/"$CONT_VAR" "$DEST_ZPOOL"/lxd/storage/containers/"$CONT_VAR" echo "Fixing config for bionic" ssh "$DEST_IP" -p $DEST_PORT sed -i '/volatile.idmap.current/d' /var/lib/lxd/storage-pools/"$DEST_ZPOOL_2"/containers/"$CONT_VAR"/backup.yaml echo "Importing "$CONT_VAR" on destination" ssh "$DEST_IP" -p $DEST_PORT lxd import "$CONT_VAR" --force fi echo "Starting "$CONT_VAR" on destination" ssh "$DEST_IP" -p $DEST_PORT lxc start "$CONT_VAR" echo " " else if [ -z "$SNAP_TO_SEND_FIRST_FOR_LATER_CHECK" ] then echo "Setting up mountpoint on destination for "$CONT_VAR"" ssh "$DEST_IP" -p $DEST_PORT zfs set canmount=noauto "$DEST_ZPOOL"/lxd/storage/containers/"$CONT_VAR" ssh "$DEST_IP" -p $DEST_PORT zfs set mountpoint=/var/snap/lxd/common/lxd/storage-pools/"$DEST_ZPOOL_2"/containers/"$CONT_VAR" "$DEST_ZPOOL"/lxd/storage/containers/"$CONT_VAR" ssh "$DEST_IP" -p $DEST_PORT zfs mount "$DEST_ZPOOL"/lxd/storage/containers/"$CONT_VAR" ssh "$DEST_IP" -p $DEST_PORT "nsenter -t \$(cat /var/snap/lxd/common/lxd.pid) -m bash -c \"mount -t zfs "$DEST_ZPOOL"/lxd/storage/containers/"$CONT_VAR" /var/snap/lxd/common/lxd/storage-pools/"$DEST_ZPOOL_2"/containers/"$CONT_VAR"\"" echo "Importing "$CONT_VAR" on destination" ssh "$DEST_IP" -p $DEST_PORT /snap/bin/lxd import "$CONT_VAR" --force ssh "$DEST_IP" -p $DEST_PORT zfs umount "$DEST_ZPOOL"/lxd/storage/containers/"$CONT_VAR" fi echo "Starting "$CONT_VAR" on destination" ssh "$DEST_IP" -p $DEST_PORT /snap/bin/lxc start "$CONT_VAR" echo " " fi done