#!/bin/bash

set -eu
# __SILENT=TRUE
. /opt/fox_utils/crab_sys.sh
[ "${1:-}" = "--help" ] && sys::usage "$@"
### --help Info: Проверяем, что доступ до бк-ноды есть и что там достаточно места
### --help Usage: vz_cli|kvm_cli backup-bk-storage-check $VM_NAME [node_name|node_ip|--local]
### --help Usage: [ --online ] [-i/root/.ssh/id_rsa] [--skip-check_node]
### --help Example:

# Файл является копией файла бекап.
# Можно было в бекап добавить флаг --only-check, но т.к. вызываемся из агента
# опасно случайно сломать флаг и запускать бекап каждые 15 минут
# TODO2: можно вынести часть файла бекапа в инклуд или сделать поддержку инклуда в vz_backup

sys::arg_parse "$@"

. /opt/fox_utils/fox_conf vm get "$ARG_1"

if [ -f /tmp/vz_backup.$$ ]; then
	VM_NODE_BACKUP=$(</tmp/vz_backup.$$)
	rm -f /tmp/vz_backup.$$
fi
[ -n "${ARG_2:-}" ] && VM_NODE_BACKUP="$ARG_2"
[ "${ARG_LOCAL:-}" = TRUE ] && VM_NODE_BACKUP="$VM_NODE_LOCATION"

if [ -z "${VM_NODE_BACKUP:-}" ]; then
	echo 'Укажите VM_NODE_BACKUP в vm.conf или в $2'
	exit 255
fi
if [ "$VM_NODE_BACKUP" = "FALSE" ]; then
	echo "Бекап отключен VM_NODE_BACKUP = $VM_NODE_BACKUP"
	exit 0
elif [ "$VM_NODE_BACKUP" = "EXTERNAL" ]; then
	echo "Используется внешний бекап VM_NODE_BACKUP = $VM_NODE_BACKUP" >&2
	exit 0
fi
if [ -f "/opt/fox_conf/node/${VM_NODE_BACKUP}/node.conf" ]; then
	(
		NODE_STATE=
		NODE_REDIRECT=
		. "/opt/fox_conf/node/${VM_NODE_BACKUP}/node.conf"
		if [ "${NODE_STATE:-}" = "failed" ]; then
			echo "WARNING $VM_NODE_BACKUP is ${NODE_STATE:-} redirect to $NODE_REDIRECT"
			echo "$NODE_REDIRECT" > /tmp/vz_backup.$$
		fi
	)
fi

__exit(){
	exit $1
	return 0
}

TMP_IP_FIRST="${VM_IP%% *}"
VM_STATUS=""
VM_BACKUP_ONLINE="${VM_BACKUP_ONLINE:-TRUE}"
if [ "$VM_TYPE" = "vz7" ]; then
	PLOOP_NAME="$VM_NAME"
	PLOOP_PRIVATE="$VM_DISK"
	status="$(vzctl status $PLOOP_NAME)"
	if [[ "$status" == *' running'* ]]; then
		VM_STATUS=running
	fi
elif [ "$VM_TYPE" = "kvm" ]; then
	PLOOP_NAME="kvm-$VM_NAME"
	PLOOP_PRIVATE="${VM_DISK/root/private}"
	dominfo=$( virsh dominfo "$VM_NAME" ) || true
	if [[ "$dominfo" == *running* ]]; then
		VM_STATUS=running
	fi
fi

# TODO0 сделать в случае онлайн бекапа без CRIO sync внутри контейнера
# CRIO не умеет сохранять вложенные cgroups, встречается у докера
declare SKIP_SUSPEND=FALSE
if [ -d "/sys/fs/cgroup/pids/machine.slice/${VM_UUID:-}/docker" ]; then
	SKIP_SUSPEND=TRUE
fi

BK_DATESEC=$(date +%s)

if [ "${ARG_ONLINE:-}" = "TRUE" ] ;then
	VM_BACKUP_ONLINE=TRUE
fi

# ssh -oStrictHostKeyChecking=no 127.0.0.1 -o 'BatchMode=yes' 'ls'
# не используте здесь пробел -oBatchMode=yes
SSH_OPT='-oStrictHostKeyChecking=no -oBatchMode=yes '
if [ -n "${ARG_I:-}" ]; then
	SSH_OPT="${SSH_OPT} -i${ARG_I} "
elif [ -s "${VM_DIR}/backup_id_rsa" ]; then
	echo "TODO0 вернуть работу через ${VM_DIR}/backup_id_rsa"
	# chmod 0600 ${VM_DIR}/backup_id_rsa
	# SSH_OPT="${SSH_OPT} -i${VM_DIR}/backup_id_rsa "
fi

if [[ "$VM_NODE_BACKUP" == *:* ]]; then
	SSH_PORT="${VM_NODE_BACKUP#*:}"
	VM_NODE_BACKUP="${VM_NODE_BACKUP%:*}"
	SSH_OPT="${SSH_OPT} -p$SSH_PORT "
fi

BACKUP_SERVER="${VM_NODE_BACKUP}"
if [ -f "/opt/fox_conf/node/${VM_NODE_BACKUP}/node.conf" ]; then
	BACKUP_SERVER=$( . "/opt/fox_conf/node/${VM_NODE_BACKUP}/node.conf"; echo $NODE_IP; )
fi

# Для локального бекапа используем старый алгоритм
# ssh заменяется хаком
if [ "$VM_NODE_BACKUP" = "$VM_NODE_LOCATION" ]; then
	BACKUP_DST="/vz/backup/$PLOOP_NAME"
	__ssh(){
		set -e
		shift
		eval "$@"
		return 0
	}
	__rsync(){
		rsync "$@"
		return 0
	}

else
	BACKUP_DST="${BACKUP_SERVER}:/vz/backup/$PLOOP_NAME"
	__ssh(){
		set -e
		/opt/fox_utils/crab_ssh ${SSH_OPT} "$@"
		return 0
	}
	__rsync(){
		rsync -e "ssh $SSH_OPT" "$@"
		return 0
	}
fi

ssh_ok=$(__ssh $BACKUP_SERVER "echo TRUE" || true)
if [ "$ssh_ok" != TRUE ] ; then
	echo "ssh $BACKUP_SERVER $SSH_OPT \"touch /tmp/vz_backup\""
	echo "Не настроен ssh use: ssh-copy-id -i ${VM_DIR}/backup_id_rsa $BACKUP_SERVER"
	__exit 255
fi
set -o pipefail
VM_CUR_SIZE="$( du -s -B G $VM_DIR/disk/ | awk '{print $1}' )"
set +o pipefail

__ssh $BACKUP_SERVER 'mkdir -p /vz/backup/'

if [ "${ARG_SKIP_CHECK_NODE:-}" != TRUE ]; then
	exists_resource_check=$(__ssh $BACKUP_SERVER \
		'test -x /opt/fox_node/centos7fox/node_resource_check && echo TRUE; exit 0' )
	if [ "$exists_resource_check" = TRUE ]; then
		__ssh $BACKUP_SERVER /opt/fox_node/centos7fox/node_resource_check \
			--alloc-size="$VM_CUR_SIZE" --disk=/vz/backup/
	else
		node_backup_freespace=$(__ssh $BACKUP_SERVER \
			'echo $((`stat -f -c %a /vz/backup/` * 4096 /1024/1024/1024 ))' )
		if ((${VM_CUR_SIZE/G/} > $node_backup_freespace)); then
			echo "No Free space on $BACKUP_SERVER "\
				"${VM_CUR_SIZE/G/} > $node_backup_freespace"
			__exit 255
		fi
	fi
fi


exit 0
