#!/usr/local/bin/cbsd
#v12.1.6
CBSDMODULE="jail"
MYARG="node jname progress tryoffline"
MYOPTARG="sharedfs "
MYDESC="Transfer jail as slave jail to remote node"
ADDHELP="progress=0,1 show progress, by default 1, yes\n"

. ${subrdir}/nc.subr

sharedfs=0
tryoffline=0
progress=0

. ${cbsdinit}

. ${jfs}
. ${system}

[ ${sharedfs} -eq 1 ] && exit 0

. ${subrdir}/time.subr
st_time=$( ${DATE_CMD} +%s )


emulator="jail" # for jname_is_multiple
jail_list=
jname_is_multiple

# -n "name of the tools" - show <name> in Info string, e.g: -n jexec, -n "pkg install" ...
# -o uniq_name_of_the_task (one world)
j2slave_multi_init()
{
	local _jname

	while getopts "c:n:o:" opt; do
		case "${opt}" in
			c) cmd="${OPTARG}" ;;
			n) _multiple_consumer_name="${OPTARG}" ;;
			o) task_owner="${OPTARG}" ;;
		esac
		shift $(($OPTIND - 1))
	done

	[ -z "${task_owner}" ] && err 1 "${N1_COLOR}multiple_processing_spawn: empty -o multiple_task_owner${N0_COLOR}"

	. ${subrdir}/multiple.subr
	${ECHO} "${N1_COLOR}Hint: Press ${N2_COLOR}'Ctrl+t'${N1_COLOR} to see last logfile line for active task${N0_COLOR}" 1>&2
	task_id=
	task_id_cur=
	task_owner="${task_owner}"
	# spawn command for all jail
	for _jname in ${jail_list}; do
		task_id_cur=$( task mode=new logfile=/tmp/${task_owner}.${_jname}.log.$$ client_id=${_jname} autoflush=0 owner=${task_owner} /usr/bin/env NOCOLOR=1 /usr/local/bin/cbsd j2slave jname=${_jname} ${cmd} 2>/dev/null )
		sleep 0.1               # dont bruce taskdb
		if ! is_number "${task_id_cur}"; then
			task_id="${task_id} ${task_id_cur}"
		fi
	done

	multiple_task_id_all=$( echo ${task_id} | ${TR_CMD} " " "," )
	sleep 0.5
	multiple_processing_spawn -o ${task_owner} -n "${_multiple_consumer_name}"
}

[ -z "${node}" ] && log_err 1 "${N1_COLOR}Give me node${N0_COLOR}"

# MAIN for multiple jails
if [ -n "${jail_list}" ]; then
	# multiple jailsastart always non interactive
	if [ -n "${jail_list}" ]; then
		JLIST="${jail_list}"
	fi

	_args=

	# trim for jname= in "$*"
	for i in $*; do
		prefix=
		prefix6=$( substr --pos=0 --len=6 --str="${i}" )
		[ "${prefix6}" = "jname=" ] && continue
		if [ -n "${_args}" ]; then
			_args="${_args} ${i}"
		else
			_args="${i}"
		fi
	done

	task_owner="j2slave_multiple_remove"
	j2slave_multi_init -c "${_args}" -o ${task_owner} -n "j2slave"
	err 0 "${N1_COLOR}Multiple j2slave: ${N2_COLOR}done${N0_COLOR}"
fi

. ${subrdir}/rcconf.subr
[ $? -eq 1 ] && log_err 1 "${N1_COLOR}No such jail: ${N2_COLOR}${jname}${N0_COLOR}"
#[ "${emulator}" = "bhyve" ] && log_err 1 "${N1_COLOR}Not for bhyve mode${N0_COLOR}"

ip=$( cbsdsqlro nodes SELECT ip FROM nodelist WHERE nodename=\"${node}\" )

[ -z "${ip}" ] && err 1 "${N1_COLOR}No such nodedata: ${N2_COLOR}${node}${N0_COLOR}"

#test for zfs mounted & mount if not
case ${zfsfeat} in
	1)
		. ${subrdir}/zfs.subr
		zfsmnt ${data}
		[ $? -eq 2 ] && ${ZFS_CMD} mount "${ZPOOL}"
		;;
esac

[ ! -d "${data}" ] && log_err 1 "${N1_COLOR}No such jaildir${N0_COLOR}"
cbsdlogger NOTICE ${CBSD_APP}: rsync ${jname} data, port: 1873, secrets: ${etcdir}/${jname}.secrets

# Update Redis
if [ "${mod_cbsd_redis_enabled}" = "YES" -a -z "${MOD_CBSD_REDIS_DISABLED}" ]; then
	cbsdredis publish cbsd_events '{"cmd":"j2slave", "node":"'${nodename}'", "dest":"'${node}'", "jail":"'${jname}'", "status":1}'
fi

if [ ${progress} -eq 1 ]; then
	_rs_progress="--progress"
else
	_rs_progress=""
fi

iptype ${ip}
case $? in
	1)
		rsync_ip="${ip}"
		rsync_ip_ver_opt="-4"
		;;
	2)
		rsync_ip="[${ip}]"
		rsync_ip_ver_opt="-6"
		;;
	*)
		err 1 "${N1_COLOR}${CBSD_APP}: unknown ip type: ${N2_COLOR}${ip}${N0_COLOR}"
		;;
esac

# sync for sysdata
${RSYNC_CMD} ${rsync_ip_ver_opt} --port=1873 -arzz --partial ${_rs_progress} --devices --numeric-ids --delete --exclude locked --recursive --partial --password-file=${etcdir}/${jname}.secrets ${jailsysdir}/${jname}/ rsync://${jname}@${rsync_ip}/${jname}-sysdata/ 2>${DEBLOG}
_err=$?

case ${_err} in
	0|6|24|25)
		cbsdlogger NOTICE ${CBSD_APP}: rsync ${jname} sysdata, port: 1873, secrets: ${etcdir}/${jname}.secrets success
		;;
	*)
		cbsdlogger NOTICE ${CBSD_APP}: rsync ${jname} sysdata, port: 1873, secrets: ${etcdir}/${jname}.secrets failed, see ${DEBLOG}
		${CAT_CMD} ${DEBLOG}

		# Update Redis
		if [ "${mod_cbsd_redis_enabled}" = "YES" -a -z "${MOD_CBSD_REDIS_DISABLED}" ]; then
			end_time=$( ${DATE_CMD} +%s )
			diff_time=$(( end_time - st_time ))
			cbsdredis publish cbsd_events '{"cmd":"j2slave", "node":"'${nodename}'", "dest":"'${node}'", "jail":"'${jname}'", "status":'${_err}', "duration":'${diff_time}'}'
		fi

		exit 1
		;;
esac

# sync for data
${RSYNC_CMD} ${rsync_ip_ver_opt} --port=1873 -arzz --partial ${_rs_progress} --devices --numeric-ids --delete --recursive --partial --password-file=${etcdir}/${jname}.secrets ${data}/ rsync://${jname}@${rsync_ip}/${jname}/ 2>${DEBLOG}
_err=$?

end_time=$( ${DATE_CMD} +%s )
diff_time=$(( end_time - st_time ))

case ${_err} in
	0|6|24|25)
		cbsdlogger NOTICE ${CBSD_APP}: rsync ${jname} data, port: 1873, secrets: ${etcdir}/${jname}.secrets success

		# Update Redis
		if [ "${mod_cbsd_redis_enabled}" = "YES" -a -z "${MOD_CBSD_REDIS_DISABLED}" ]; then
			cbsdredis publish cbsd_events '{"cmd":"j2slave", "node":"'${nodename}'", "dest":"'${node}'", "jail":"'${jname}'", "status":0,"duration":'${diff_time}'}'
		fi

		exit 0
		;;
	*)
		cbsdlogger NOTICE ${CBSD_APP}: rsync ${jname} data, port: 1873, secrets: ${etcdir}/${jname}.secrets failed, see ${DEBLOG}
		${CAT_CMD} ${DEBLOG}

		# Update Redis
		if [ "${mod_cbsd_redis_enabled}" = "YES" -a -z "${MOD_CBSD_REDIS_DISABLED}" ]; then
			cbsdredis publish cbsd_events '{"cmd":"j2slave", "node":"'${nodename}'", "dest":"'${node}'", "jail":"'${jname}'", "status":'${_err}',"duration":'${diff_time}'}'
		fi

		exit 1
		;;
esac

exit 0
