#!/usr/local/bin/cbsd
#v11.1.17
globalconf="${workdir}/cbsd.conf";
MYARG=""
MYOPTARG="compress dstdir genmd5 gensize ls imgname jname"
MYDESC="Export jail into image"
CBSDMODULE="jail"
ADDHELP="compress - XZ compress level ( 0 - 9 ). Default is: 6. 0 mean is compression disabled\n\
dstdir - alternative export dir ( by default - $workdir/exports )\n\
genmd5 - generate $imgname.md5 file with md5sum of image\n\
gensize - generate $imgname.size file with size of image in bytes\n\
ls - filter for list: bls or jls\n\
imgname - alternative image dir ( by default - $jname.img\n"

. ${subr}
. ${strings}
. ${tools}

# generate md5 file?
genmd5=0
# generate size file?
gensize=0

init $*

# ClonOS ws channel
[ -z "${cbsd_queue_name}" ] && cbsd_queue_name="/clonos/jailscontainers/"
[ -z "${cbsd_queue_name2}" ] && cbsd_queue_name2="/clonos/imported/"

jexport_me()
{
	local _ret

	${ECHO} "${MAGENTA}Exporting (with compress level:${GREEN}${compress}${MAGENTA}), please stand by: ${GREEN}${jname}${NORMAL}"
	local DEST="${dstdir}/${imgname}"
	local JAILRCCONF="${jailsysdir}/${jname}/rc.conf_${jname}"

	# check for already existance and offline
	if [ ! -d "${data}" ]; then
		${ECHO} "${MAGENTA}No jail data for ${jname}: ${GREEN}${data}${NORMAL}"
		return 1
	fi

SPACER="___NCSTART_HEADER=1_ \
___NCSTART_RCCONF=1 \
___NCSTART_FSTAB=1 \
___NCSTART_PKGINFO=1 \
___NCSTART_DESCR=1 \
___NCSTART_INFO=1 \
___NCSTART_LOCALFSTAB=1
___NCSTART_SYSDATA=1 \
___NCSTART_DATA=1"

	for _part in ${SPACER}; do
		case ${_part} in
			___NCSTART_HEADER*)
				jmkrcconf jname=${jname} > ${JAILRCCONF}
				res=$( imgpart mode=pack jname=${jname} part=header emulator=${emulator} out=${DEST} )
				_ret=$?
				/bin/rm -f ${JAILRCCONF}
				[ ${_ret} -ne 0 ] && err 1 "${MAGENTA}Error in ${_part}: ${res}${NORMAL}"
				;;
			___NCSTART_RCCONF*)
				#currenlty we import/export operation for rc.conf via ascii format
				#cause diffrence node can have version of cbsd with incompattible jail schema
				#so create rc.conf for pack operation
				jmkrcconf jname=${jname} > ${JAILRCCONF}
				res=$( replacewdir file0="${JAILRCCONF}" old=${workdir} new="CBSDROOT" )
				_ret=$?
				if [ ${_ret} -ne 0 ]; then
					/bin/rm -f ${JAILRCCONF}
					err 1 "${MAGENTA}Error in ${_part} replacewdir: ${res}${NORMAL}"
				fi
				res=$( imgpart mode=pack jname=${jname} part=rcconf out=${DEST} )
				_ret=$?
				/bin/rm -f ${JAILRCCONF}
				[ ${_ret} -ne 0 ] && err 1 "${MAGENTA}Error in ${_part}: ${res}${NORMAL}"
				;;
			___NCSTART_PKGINFO*)
				res=$( imgpart mode=pack jname=${jname} part=pkginfo out=${DEST} )
				[ $? -ne 0 ] && err 1 "${MAGENTA}Error in ${_part}: ${res}${NORMAL}"
				;;
			___NCSTART_DESCR*)
				res=$( imgpart mode=pack jname=${jname} part=descr out=${DEST} )
				[ $? -ne 0 ] && err 1 "${MAGENTA}Error in ${_part}: ${res}${NORMAL}"
				;;
			___NCSTART_INFO*)
				imgpart mode=pack jname=${jname} part=info out=${DEST}
				[ $? -ne 0 ] && err 1 "${MAGENTA}Error in ${_part}: ${res}${NORMAL}"
				;;
			___NCSTART_FSTAB*)
				TMPFSTAB="${ftmpdir}/fstab.$$"
				[ ! -f "${mount_fstab}" ] && /usr/bin/touch ${mount_fstab}
				/bin/cp ${mount_fstab} ${TMPFSTAB}
				res=$( replacewdir file0="${mount_fstab}" old=${workdir} new="CBSDROOT" )
				[ $? -ne 0 ] && err 1 "${MAGENTA}Error in ${_part} replacewdir: ${res}${NORMAL}"
				res=$( imgpart mode=pack jname=${jname} part=fstab out=${DEST} )
				[ $? -ne 0 ] && err 1 "${MAGENTA}Error in ${_part}: ${res}${NORMAL}"
				/bin/mv ${TMPFSTAB} ${mount_fstab}
				;;
			___NCSTART_LOCALFSTAB*)
				# localfstab is not mandatory file. Errcode is always 0
				if [ -r ${mount_fstab}.local ]; then
					res=$( replacewdir file0="${mount_fstab}.local" old=${workdir} new="CBSDROOT" )
					[ $? -ne 0 ] && err 1 "${MAGENTA}Error in ${_part} replacewdir: ${res}${NORMAL}"
				fi
				res=$( imgpart mode=pack jname=${jname} part=localfstab out=${DEST} || true )
				[ $? -ne 0 ] && err 1 "${MAGENTA}Error in ${_part}: ${res}${NORMAL}"
				;;
			___NCSTART_SYSDATA*)
				res=$( imgpart mode=pack jname=${jname} part=sysdata out=${DEST} )
				[ $? -ne 0 ] && err 1 "${MAGENTA}Error in ${_part}: ${res}${NORMAL}"
				;;
			___NCSTART_DATA*)
				#test for zfs mounted & mount if not
				case ${zfsfeat} in
					1)
						. ${zfstool}
						zfsmnt ${data}
						if [ $? -eq 2 ]; then
							WASNOMOUNT=1
						else
							WASNOMOUNT=0
						fi
						[ ${WASNOMOUNT} -eq 1 ] && /sbin/zfs mount "${ZPOOL}"
						;;
				esac
				jmkrcconf jname=${jname} > ${JAILRCCONF}
				res=$( imgpart mode=pack jname=${jname} compress=${compress} part=data out=${DEST} 2>&1 )
				[ $? -ne 0 ] && err 1 "${MAGENTA}Error in ${_part}: ${res}${NORMAL}"
				/bin/rm -f ${JAILRCCONF}
				[ "${WASNOMOUNT}" = "1" ] && /sbin/zfs unmount "${ZPOOL}"
				;;
		esac
	done

	# Summary stat size
	if [ -s "${DEST}" ]; then
		imgfile=$( /usr/bin/basename ${DEST} )
		img_bsize=$( /usr/bin/stat -f "%z" ${DEST} 2>/dev/null )

		if [ ${gensize} -eq 1 ]; then
			echo ${img_bsize} > ${DEST}.size
		fi

		if [ ${genmd5} -eq 1 ]; then
			/sbin/md5 -q ${DEST} > ${DEST}.md5
		fi

		if conv2human "${img_bsize}"; then
			img_size=${convval}
		fi
		${ECHO} "${MAGENTA}Images size for ${imgfile}: ${GREEN}${img_size}${NORMAL}"

		return 0
	else
		${ECHO} "${MAGENTA}Unknown error in jexport${NORMAL}"
		return 1
	fi
}

[ -z "${compress}" ] && compress=6
[ -z "${dstdir}" ] && dstdir="${exportdir}"
[ ! -d "${dstdir}" ] && /bin/mkdir -p ${dstdir}

if [ -z "${ls}" ]; then
	ls="jls"
else
	shift
fi

[ -z "${jname}" -a -n "${1}" ] && jname="${1}"

if [ -n "${jname}" ]; then

	case "${ls}" in
		bls)
			emulator="bhyve"	# for jname_is_multiple
			;;
		*)
			emulator="jail"		# for jname_is_multiple
			;;
	esac
	jname_is_multiple

	if [ -n "${jail_list}" ]; then
		# recursion for masked jails
		for i in ${jail_list}; do
			jexport jname=${i} compress=${compress}
		done
		exit 0
	fi
else
	select_jail_by_list -s "List of all jails" -e ${ls}
	[ -z "${jname}" ] && err 1 "${MAGENTA}Give me jname${NORMAL}"
fi

if [ -z "${imgname}" ]; then
	imgname="${jname}.img"
else
	imgname="${imgname}.img"
fi

. ${jrcconf}

[ $? -eq 1 ] && err 1 "${MAGENTA}No such jail: ${GREEN}${jname}${NORMAL}"

if [ ${jid} -ne 0 -a "${emulator}" = "bhyve" ]; then
	err 1 "${MAGENTA}VM is online${NORMAL}"
fi

# CBSD QUEUE
if [ -x "${moduledir}/cbsd_queue.d/cbsd_queue" ]; then

	case "${emulator}" in
		jail)
			cbsd_queue_name="/clonos/jailscontainers/"
			;;
		bhyve)
			cbsd_queue_name="/clonos/bhyvevms/"
			;;
	esac

	[ "${cbsd_queue_name}" != "none" ] && cbsd_queue cbsd_queue_name=${cbsd_queue_name} id=${jname} cmd=jexport status=1

	if [ "${cbsd_queue_name2}" != "none" ]; then
		cbsd_queue cbsd_queue_name=${cbsd_queue_name2} cmd=message msg="{\"id\":\"${jname}.img\",\"cmd\":\"jexport\",\"status\":\"1\",\"data\":{\"status\":\"1\",\"node\":\"local\",\"jname\":\"${jname}.img\",\"impsize\":\"0\",\"imptype\":\"${emulator}\"}}"
		cbsd_queue cbsd_queue_name=${cbsd_queue_name2} cmd=message msg="{\"cmd\":\"tooltip\",\"type\":\"information\",\"timeout\":10000,\"author\":\"Export\",\"msg\":\"${jname}#export#started...\"}"
	fi
fi

jexport_me
ret=$?

# CBSD QUEUE
if [ -x "${moduledir}/cbsd_queue.d/cbsd_queue" ]; then

	[ "${cbsd_queue_name}" != "none" ] && cbsd_queue cbsd_queue_name=${cbsd_queue_name} id=${jname} cmd=jexport status=2

	if [ "${cbsd_queue_name2}" != "none" ]; then
		cbsd_queue cbsd_queue_name=${cbsd_queue_name2} id=${jname}.img cmd=update impsize=${img_bsize} status=1
		cbsd_queue cbsd_queue_name=${cbsd_queue_name2} cmd=message msg="{\"id\":\"${jname}.img\",\"cmd\":\"jexport\",\"status\":\"2\",\"data\":{\"status\":\"2\",\"node\":\"local\",\"jname\":\"${jname}.img\",\"impsize\":\"${img_bsize}\",\"imptype\":\"${emulator}\"}}"
		tmp_img_size=$( echo ${img_size} | /usr/bin/tr ' ' '#' )
		cbsd_queue cbsd_queue_name=${cbsd_queue_name2} cmd=message msg="{\"cmd\":\"tooltip\",\"type\":\"success\",\"timeout\":10000,\"author\":\"Export\",\"msg\":\"${jname}#export#completed:${tmp_img_size}\"}"
	fi
fi

exit ${ret}
