123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219 |
- #!/bin/bash
- CONTS_LIST=$(lxc list | grep "RUNNING\|STOPPED" | awk {'print $2'})
- if [ $# -eq 0 ]
- then
- echo "No arguments supplied, doing interactive mode"
- sleep 1
- 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)
- fi
- if [[ ! -z "$1" ]]; then
- if [[ ! -z "$2" ]]; then
- CONTS=$(echo "$CONTS_LIST" | nl | grep "$1" | awk {'print $1'})
- DEST_IP="$2"
- DEST_PORT="$3"
- fi
- fi
- [ -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); (($? != 0)) && { echo "SSH command to fill DEST_SNAPS exited with non-zero"; exit 1; }
- bionic_checker=$(ssh $DEST_IP -p $DEST_PORT lsb_release -c | awk {'print $2'}); (($? != 0)) && { echo "SSH command to fill bionic_checker exited with non-zero"; exit 1; }
- 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"$)
- DATASET_RECORDSIZE_VAR=$(zfs get recordsize -H -o value "$DATASET_VAR")
- DATASET_ATIME_VAR=$(zfs get atime -H -o value "$DATASET_VAR")
- DATASET_RELATIME_VAR=$(zfs get relatime -H -o value "$DATASET_VAR")
- DATASET_QUOTA_VAR=$(zfs get quota -H -o value "$DATASET_VAR")
- SNAP_TO_SEND_FIRST_FOR_LATER_CHECK=$(echo "$SNAP_TO_SEND_FIRST")
- IFS="
- "
- echo "Start move "$CONT_VAR""
- if [ -z "$SNAP_TO_SEND_FIRST" ]
- then
- 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 48 | head -n 1)
- fi
- echo "Sending first snapshot"
- echo "Sending "$SNAP_TO_SEND_FIRST""
- zfs send "$SNAP_TO_SEND_FIRST" | lzop | pv | ssh "$DEST_IP" -p $DEST_PORT "lzop -d | zfs recv -o recordsize="$DATASET_RECORDSIZE_VAR" -o atime="$DATASET_ATIME_VAR" -o relatime="$DATASET_RELATIME_VAR" -o quota="$DATASET_QUOTA_VAR" "$DEST_ZPOOL"/lxd/storage/containers/"$CONT_VAR""; (($? != 0)) && { echo "SSH command to send first snapshot exited with non-zero"; exit 1; }
- echo "Sleep 2"
- sleep 2
- fi
- 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" | lzop | pv | ssh "$DEST_IP" -p $DEST_PORT "lzop -d | zfs recv -o recordsize="$DATASET_RECORDSIZE_VAR" -o atime="$DATASET_ATIME_VAR" -o relatime="$DATASET_RELATIME_VAR" -o quota="$DATASET_QUOTA_VAR" "$DEST_ZPOOL"/lxd/storage/containers/"$CONT_VAR" -F"; (($? != 0)) && { echo "SSH command to send second snapshot exited with non-zero"; exit 1; }
- 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" | lzop | pv | ssh "$DEST_IP" -p $DEST_PORT "lzop -d | zfs recv -o recordsize="$DATASET_RECORDSIZE_VAR" -o atime="$DATASET_ATIME_VAR" -o relatime="$DATASET_RELATIME_VAR" -o quota="$DATASET_QUOTA_VAR" "$DEST_ZPOOL"/lxd/storage/containers/"$CONT_VAR" -F"; (($? != 0)) && { echo "SSH command to send third snapshot exited with non-zero"; exit 1; }
- 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" | lzop | pv | ssh "$DEST_IP" -p $DEST_PORT "lzop -d | zfs recv -o recordsize="$DATASET_RECORDSIZE_VAR" -o atime="$DATASET_ATIME_VAR" -o relatime="$DATASET_RELATIME_VAR" -o quota="$DATASET_QUOTA_VAR" "$DEST_ZPOOL"/lxd/storage/containers/"$CONT_VAR" -F"; (($? != 0)) && { echo "SSH command to send fourth snapshot exited with non-zero"; exit 1; }
- echo "Sleep 2"
- sleep 2
- echo "Stopping "$CONT_VAR" on source"
- lxc stop "$CONT_VAR" --timeout 30; (($? != 0)) && echo "lxc stop timed-out after 30 seconds, doing with force parameter" && lxc stop "$CONT_VAR" --force
- 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" | lzop | pv | ssh "$DEST_IP" -p $DEST_PORT "lzop -d | zfs recv -o recordsize="$DATASET_RECORDSIZE_VAR" -o atime="$DATASET_ATIME_VAR" -o relatime="$DATASET_RELATIME_VAR" -o quota="$DATASET_QUOTA_VAR" "$DEST_ZPOOL"/lxd/storage/containers/"$CONT_VAR" -F"; (($? != 0)) && { echo "SSH command to send fifth snapshot exited with non-zero"; exit 1; }
- 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"; (($? != 0)) && { echo "SSH command to setup mountpoint on destination exited with non-zero"; exit 1; }
- 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; (($? != 0)) && { echo "SSH command to setup volatile.idmap exited with non-zero"; exit 1; }
- ssh "$DEST_IP" -p $DEST_PORT sed -i '/volatile.uuid/d' /var/lib/lxd/storage-pools/"$DEST_ZPOOL_2"/containers/"$CONT_VAR"/backup.yaml; (($? != 0)) && { echo "SSH command to setup volatile.uuid exited with non-zero"; exit 1; }
- ssh "$DEST_IP" -p $DEST_PORT sed -i '/volatile.cloud-init.instance-id/d' /var/lib/lxd/storage-pools/"$DEST_ZPOOL_2"/containers/"$CONT_VAR"/backup.yaml; (($? != 0)) && { echo "SSH command to setup volatile.cloud-init.instance-id exited with non-zero"; exit 1; }
- ssh "$DEST_IP" -p $DEST_PORT sed -i '/volatile.last_state.ready/d' /var/lib/lxd/storage-pools/"$DEST_ZPOOL_2"/containers/"$CONT_VAR"/backup.yaml; (($? != 0)) && { echo "SSH command to setup volatile.last_state.ready exited with non-zero"; exit 1; }
- echo "Importing "$CONT_VAR" on destination"
- ssh "$DEST_IP" -p $DEST_PORT lxd import "$CONT_VAR" --force; (($? != 0)) && { echo "SSH command to import container exited with non-zero"; exit 1; }
- fi
- echo "Starting "$CONT_VAR" on destination"
- ssh "$DEST_IP" -p $DEST_PORT lxc start "$CONT_VAR"; (($? != 0)) && { echo "SSH command to start container exited with non-zero"; exit 1; }
- echo " "
- else
- if [ -z "$SNAP_TO_SEND_FIRST_FOR_LATER_CHECK" ]
- then
- echo "Setting up mountpoint on destination for "$CONT_VAR""
- target_snap_version=$(ssh "$DEST_IP" -p $DEST_PORT snap info lxd| grep tracking: | awk {'print $2'} | cut -d"/" -f-1 | cut -d"." -f-1); (($? != 0)) && { echo "SSH command to fill target_snap_version exited with non-zero"; exit 1; }
- if [[ "$target_snap_version" == 4 ]]
- then
- ssh "$DEST_IP" -p $DEST_PORT zfs set canmount=noauto "$DEST_ZPOOL"/lxd/storage/containers/"$CONT_VAR"; (($? != 0)) && { echo "SSH command to setup mountpoint on destination exited with non-zero"; exit 1; }
- 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"; (($? != 0)) && { echo "SSH command to setup mountpoint on destination exited with non-zero"; exit 1; }
- ssh "$DEST_IP" -p $DEST_PORT zfs mount "$DEST_ZPOOL"/lxd/storage/containers/"$CONT_VAR"; (($? != 0)) && { echo "SSH command to setup mountpoint on destination exited with non-zero"; exit 1; }
- REMOTE_LXD_PID=$(ssh "$DEST_IP" -p $DEST_PORT cat /var/snap/lxd/common/lxd.pid); (($? != 0)) && { echo "SSH command to get REMOTE_LXD_PID on destination exited with non-zero"; exit 1; }
- ssh "$DEST_IP" -p $DEST_PORT "nsenter -t $REMOTE_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"\""; (($? != 0)) && { echo "SSH command to set REMOTE_LXD_PID on destination exited with non-zero"; exit 1; }
- echo "Fixing config for lxd version 4"
- ssh "$DEST_IP" -p $DEST_PORT sed -i '/volatile.cloud-init.instance-id/d' /var/snap/lxd/common/lxd/storage-pools/"$DEST_ZPOOL_2"/containers/"$CONT_VAR"/backup.yaml; (($? != 0)) && { echo "SSH command to setup volatile.cloud-init.instance-id exited with non-zero"; exit 1; }
- ssh "$DEST_IP" -p $DEST_PORT sed -i '/volatile.last_state.ready/d' /var/snap/lxd/common/lxd/storage-pools/"$DEST_ZPOOL_2"/containers/"$CONT_VAR"/backup.yaml; (($? != 0)) && { echo "SSH command to setup volatile.last_state.ready exited with non-zero"; exit 1; }
- echo "Importing "$CONT_VAR" on destination"
- ssh "$DEST_IP" -p $DEST_PORT /snap/bin/lxd import "$CONT_VAR" --force; (($? != 0)) && { echo "SSH command to import container exited with non-zero"; exit 1; }
- ssh "$DEST_IP" -p $DEST_PORT zfs umount "$DEST_ZPOOL"/lxd/storage/containers/"$CONT_VAR"; (($? != 0)) && { echo "SSH command to import container exited with non-zero"; exit 1; }
- else
- echo "Doing lxd recover"
- ssh "$DEST_IP" -p $DEST_PORT zfs set mountpoint=legacy "$DEST_ZPOOL"/lxd/storage/containers/"$CONT_VAR"; (($? != 0)) && { echo "SSH command to setup mountpoint=legacy on destination exited with non-zero"; exit 1; }
- ssh "$DEST_IP" -p $DEST_PORT "cat <<EOF | lxd recover
- no
- yes
- yes
- EOF"; (($? != 0)) && { echo "SSH command lxd recover exited with non-zero"; exit 1; }
- fi
- fi
- echo "Starting "$CONT_VAR" on destination"
- ssh "$DEST_IP" -p $DEST_PORT /snap/bin/lxc start "$CONT_VAR"; (($? != 0)) && { echo "SSH command to start container exited with non-zero"; exit 1; }
- echo " "
- fi
- done
|