#!/usr/local/bin/cbsd
#v12.0.4
MYARG=""
MYOPTARG="alljails shownode display node header mode jname"
MYDESC="Show disk images from database"
CBSDMODULE="xen"
EXTHELP="wf_xen"
ADDHELP="alljails=1 - get jaillist from remote node\n\
shownode=1 - show nodename for jails\n\
node= only for current node\n\
header=0 don't print header\n\
display= list by comma for column. Default: jname,dsk_controller,dsk_path,dsk_size,bootable\n\
    also available: dsk_zfs_guid\n\
mode=rescan - rescan vhd and sync info in sql base\n"

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

. ${cbsdinit}
. ${subrdir}/xen.subr
. ${subrdir}/virtual.subr
[ -z "${display}" ] && display="jname,dsk_controller,dsk_path,dsk_size,bootable"

#remove commas for loop action on header
mydisplay=$( echo ${display} | ${TR_CMD} ',' '  ' )

# upper for header
myheader=$( echo ${mydisplay} | ${TR_CMD} '[:lower:]' '[:upper:]' )

show_header()
{
	local _header="${H1_COLOR}${BOLD}${myheader}${N0_COLOR}"
	[ ${header} -ne 0 ] && ${ECHO} "${_header}"
}

# if $1 = "Unregister" then overwrite status to "Unregister"
populate_output_data()
{
	local _i _val dsk_size

	_status=

	#populate values for in output string
	for _i in ${mydisplay}; do
		_val=""
		eval _val=\$$_i
		[ -z "${_val}" ] && _val="-"

		if [ "${_i}" = "dsk_size" ]; then
			if [ "${_val}" = "0" ]; then
				# no size in table? retrieve and update it
				populate_dsk_size
				_val="${dsk_size}"                      # already in human
				# update values in table
				cbsdsqlrw ${jailsysdir}/${jname}/local.sqlite UPDATE xendsk SET dsk_size=\"${dsk_bsize}\" WHERE dsk_path=\"${dsk_path}\"
			else
				# convert ${dsk_bsize} for human
				if conv2human "${dsk_bsize}"; then
					_val=${convval}
				else
					populate_dsk_size
					_val="${dsk_size}"
				fi
			fi
		fi

		if [ -z "${_status}" ]; then
			_status="${N0_COLOR}${_val}"
		else
			_status="${_status} ${_val}"
		fi
	done
}


# $1 - which file from. Eg: local
show_jaildata_from_sql()
{
	local _i

	#   set sqlfile for ". rcconf" including
	if [ -n "${1}" ]; then
		sqlfile="$1"
	else
		sqlfile="local"
	fi

	[ -n "${2}" ] && local jname="${2}"

	_status=
	_sql="SELECT jname,dsk_controller,dsk_path,dsk_slot,dsk_size,bootable,dsk_zfs_guid FROM xendsk WHERE jname=\"${jname}\""
	cbsdsqlro ${sqlfile} ${_sql}| while read jname dsk_controller dsk_path dsk_slot dsk_size bootable dsk_zfs_guid; do
		populate_output_data
		printf "${N2_COLOR}"
		printf "${_status}"
		printf "${N0_COLOR}\n"
	done
}

show_remote()
{
	show_header

	[ -z "${node}" ] && node=$(cbsd node mode=list header=0 allinfo=0)

	for _n in $node; do
		nodename="${_n}"
		show_jaildata_from_sql "inv.${_n}"
	done
}

show_local()
{
	local _errcode _status _vm _lvm

	show_header

	for _vm in ${vms}; do
		_lvm="${jailsysdir}/${_vm}/local.sqlite"
#		echo ${_lvm}
		[ -r "${_lvm}" ] && show_jaildata_from_sql ${_lvm} ${_vm}
	done
}

show_dsk()
{
	if [ -n "${node}" ]; then
		show_remote
		exit
	fi

	if [ -n "${alljails}" ]; then
		show_local
		header=0
		show_remote
	else
		show_local
	fi
}

vm_list()
{
	if [ -n "${jname}" ]; then
		vms="${jname}"
	else
		vms=$( ${miscdir}/sqlcli ${dbdir}/local.sqlite "SELECT jname FROM jails WHERE emulator = \"xen\"" | ${XARGS_CMD} )
	fi
}


rescan_dsk()
{
	local _dsk _res
	[ -z "${jname}" ] && err 1 "${N1_COLOR}Please specify ${N2_COLOR}jname=${N0_COLOR}"
	. ${subrdir}/rcconf.subr
	[ $? -eq 1 ] && err 1 "${N1_COLOR}no such jail: ${N2_COLOR}${jname}${N0_COLOR}"
	for _dsk in $( /usr/bin/find ${data} -depth 1 -maxdepth 1 -name *.vhd -exec basename {} \; ); do
		_res=$( cbsdsqlro ${jailsysdir}/${jname}/local.sqlite "SELECT dsk_path FROM xendsk WHERE jname=\"${jname}\" AND dsk_path=\"${_dsk}\"" 2>/dev/null );
		if [ -z "${_res}" ]; then
			${ECHO} "${N1_COLOR}Found new disk: ${N2_COLOR}${_dsk}${N1_COLOR} for ${N2_COLOR}${jname}${N0_COLOR}"
			cbsdsqlrw ${jailsysdir}/${jname}/local.sqlite "INSERT INTO xendsk ( jname,dsk_path,dsk_slot ) VALUES ( \"${jname}\",\"${_dsk}\","0" )"
		fi
	done
}

vms=
vm_list

#### MAIN
if [ "${mode}" = "rescan" ]; then
	rescan_dsk
	exit 0
fi

[ -z "${header}" ] && header=1
sqldelimer=" "
show_dsk | ${COLUMN_CMD} -t

exit 0
