#!/bin/bash
# To move a machine onto a new ZFS

# Load some settings
. /etc/default/zfs-backup

# To move a machine from one zpool to another
function dosql() {
 SQL="$1"
 psql -q -t -c "$SQL"
}

# 
if [ -z "$1" ] ; then
 echo Usage: $0 machine_fqdn [new-zpool]
 echo Moves the named machine onto a new zpool
 echo If the new-zpool parameter is empty, the one with the most space will automatically be chosen
 exit 1
fi

HN=$1
# Find FQDN for $HN
FQDN=`getent hosts $HN | awk ' { print $2 } '`
TGT=$2

# Which zfs is it already on?
echo Finding source ZFS for $FQDN
SOURCES=`zfs list -H -o name | grep -v  zroot | grep /$FQDN$ | sed "sZ/'$FQDN$'ZZ" | wc -l `
#echo Found $SOURCES possibilities
if [ $SOURCES != 1 ] ;then
 echo Found more than one possible ZFS for $HN
 exit 2
fi
SOURCE=`zfs list -H -o name | grep -v  zroot | grep /$FQDN$ | sed "sZ/$FQDN\\$ZZ"`
# Which target is it?
if [ -z "$TGT" ] ; then
 echo Finding a target ZFS automatically
 ZPOOL=`zfs list -H -oname -S avail -d0 | grep -v zroot | grep -v $SOURCE | head -n1`
 TGT=$ZPOOL
fi

echo moving $FQDN from $SOURCE to $TGT
set -e
RUNNING=`dosql "select count(*) from backup_log natural join backup_task natural join host where hostname='$FQDN' and ended_processing is null and started_processing is not null"`
RUNNING=`echo $RUNNING` # chomp
#echo RUNNING $RUNNING
if ! [ "$RUNNING" = 0 ] ;  then
 echo $FQDN has a job running
 exit 3
fi

# Disable this host
dosql "update host set disabled='t' where hostname='$FQDN';"
# De-queue jobs for this host
dosql "delete from backup_log where backup_task_id in (select backup_task_id from backup_task natural join host where hostname='$FQDN') and ended_processing is null and started_processing is null;"

# Update tasks
dosql "update backup_task set zfs_target=regexp_replace(zfs_target,'^$SOURCE','$TGT') where host_id in (select host_id from host where hostname='$FQDN')"


# Move ZFS
TIME=`date +%s`
zfs snapshot -r $SOURCE/$FQDN@$TIME
zfs hold zfs-moving $SOURCE/$FQDN@$TIME
SIZE=`zfs list -H -o used $SOURCE/$FQDN`
echo Sending  ZFS [ $SIZE]
zfs send -R $SOURCE/$FQDN@$TIME | mbuffer | zfs receive $TGT/$FQDN

# Re-enable tasks
echo Re-enabling backup task
dosql "update host set disabled='f' where hostname='$FQDN';"
# Tidy up
echo Removing old ZFS, snapshots etc
for SN in `zfs list -r -t snapshot -H -o name $SOURCE/$FQDN ` ; do for H in `zfs holds -H $SN | awk ' { print $2 ; } '` ; do zfs release $H $SN ; done ; done
zfs destroy -r $SOURCE/$FQDN
