#!/usr/local/bin/cbsd
#v12.0.6
MYARG="node jname"
MYOPTARG="start tryoffline"
MYDESC="Cold migrate (with save status) jail to remote node, set local jail as slave"
ADDHELP="\
 start=1 for forcing jail start on the remote node\n\
"
CBSDMODULE="jail"

. ${subrdir}/nc.subr
. ${strings}
. ${system}
. ${tools}

tryoffline=0

. ${cbsdinit}

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)
jcoldmigrate_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} ${ENV_CMD} NOCOLOR=1 /usr/local/bin/cbsd jcoldmigrate 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="jcoldmigrate_multiple_remove"
	jcoldmigrate_multi_init -c "${_args}" -o ${task_owner} -n "jcoldmigrate"
	err 0 "${N1_COLOR}Multiple jcoldmigrate: ${N2_COLOR}done${N0_COLOR}"
fi

[ -z "${jname}" ] && err 1 "${N1_COLOR}Give me jname${N0_COLOR}"

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

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

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

printf "${N1_COLOR}coldmigrate.${N0_COLOR}"
j2prepare tryoffline=${tryoffline} node=${node} jname=${jname} > ${DEBLOG} 2>&1
dot "j2prepare"

j2slave tryoffline=${tryoffline} node=${node} jname=${jname} > ${DEBLOG} 2>&1
dot "j2slave: cbsdrsync daemon not running?"

if [ ${jid} -gt 0 ]; then
	## all error on this stage is dangerous
	set -e
	trap "/usr/local/bin/cbsd jstart jname=${jname} > /dev/null 2>&1 && ${ECHO} \"${N1_COLOR}Unsuccess. Restoring jail state${N0_COLOR}\" && echo \"Log message:\" && ${CAT_CMD} ${DEBLOG}" 0
	printf "${N1_COLOR}[Stopping jail: ${N2_COLOR}${jname}${N1_COLOR}]${N0_COLOR}"
	jstop jname=${jname} > ${DEBLOG} 2>&1
	dot "jstop"
	j2slave tryoffline=${tryoffline} node=${node} jname=${jname} > ${DEBLOG} 2>&1
	dot "error in j2slave: probably cbsdrsync daemon not running?"
fi

rexe tryoffline=${tryoffline} node=${node} /usr/local/bin/cbsd jregister jname=${jname} > ${DEBLOG} 2>&1
dot "cbsd rexe jregister"

[ -n "${start}" ] && jid=1

if [ ${jid} -gt 0 ]; then
	rexe tryoffline=${tryoffline} node=${node} /usr/local/bin/cbsd jstart jname=${jname} inter=0 > ${DEBLOG} 2>&1
	dot "rexe jstart"
fi

set +e
trap "" 0

jswmode jname=${jname} mode=slave > ${DEBLOG} 2>&1
dot "jswmode to slave"

${ECHO} "${N2_COLOR}ok${N0_COLOR}"

end_time=$( ${DATE_CMD} +%s )
diff_time=$(( end_time - st_time ))
diff_time=$( displaytime ${diff_time} )
${ECHO} "${N1_COLOR}${CBSD_APP} done ${N2_COLOR}in ${diff_time}${N0_COLOR}"

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

exit 0
