#!/bin/sh 
#
# Copyright 2006-2016 Hunan Kylin, Inc.  All Rights Reserved.
# 
# NOTICE: ALL INFORMATION CONTAINED HEREIN IS, AND REMAINS THE PROPERTY OF
# HUNAN KYLIN, INC. AND ITS SUPPLIERS, IF ANY. THE INTELLECTUAL AND
# TECHNICAL CONCEPTS CONTAINED HEREIN ARE PROPRIETARY TO HUNAN KYLIN, INC.
# AND ITS SUPPLIERS AND MAY BE COVERED BY U.S. AND FOREIGN PATENTS, PATENTS IN
# PROCESS, AND ARE PROTECTED BY TRADE SECRET OR COPYRIGHT LAW. DISSEMINATION
# OF THIS INFORMATION OR REPRODUCTION OF THIS MATERIAL IS STRICTLY FORBIDDEN
# UNLESS PRIOR WRITTEN PERMISSION IS OBTAINED FROM HUNAN KYLIN, INC.

usage()
{
	cat <<EOT
Usage: ksvd-config [options] [-h|-u|-m|-i|<none>]

  -h       print this help message
  -u       unattended installation
  -P       postinstall mode from packager
  -m       menu-based configuration
  -i       interview-based configuration
  <none>   if $PRODPKGNAME has already been configured on this server, sets up some 
           system files and restarts $PRODPKGNAME. otherwise, an unattended
           installation is performed (with optional parameters provided via 
           KSVD_CONFIG_CMDLINE)

Options:
  -f file  answer-file based configuration (requires -u, -m or -i)
  -l       local configuration only, i.e. only changes settings.node
  -v       debugging mode
  -n       do not restart $PRODPKGNAME when done

Environment Variables:
  KSVD_CONFIG_CMDLINE   command line options may be provided via this variable
	 e.g. KSVD_CONFIG_CMDLINE="-f /home/ksvd/answer.txt -u" $BINPATH/ksvd-config
	 when using this variable, do not pass any on the actual command line
EOT
}

warn()
{
	echo "${ansi_black_on_yellow}$@" "[m"
}

error()
{
	echo "${ansi_black_on_yellow}$@" "[m"
}

fatal()
{
	error "$@"
	exit 1
}

init_colors()
{
	ansi_black_on_yellow="[30;43m"
	ansi_purple="[01;35m"

	ansi_on="$ansi_purple"
	ansi_off="[m"
}

mc_runas()
{
	path_=$prog
	case $path_ in
	/*) ;;
	*) path_=`pwd`/$path_
	esac
	# using sudo instead of su, as it returns the exit code
	sudo -u "$UNIQB_MC_USER" -H -- $path_ $verbosity --internal $1 $2 $3 $4 $5 $6
}

config_init()
{
	umask 022

	# set environment
	unset UNIQB_PREFIX_DEV
	bin_dir=`dirname $prog`
	eval `$bin_dir/uniqbenv`

	# set fixed paths (others are relative to MC_USER)
	pre_55_global="$VARPREFIX/settings.global"
	pre_55_branch="$VARPREFIX/settings.branch"
	settings_node="$VARPREFIX/settings.node"

	is_fresh_install=

	eof_marker="### DO NOT EDIT THIS LINE OR ABOVE IT ###"

	tmpfile="/tmp/vc.$pid.prompt"

	trap tmp_file_cleanup 2
}

load_from_mc_user_home()
{
	get_mc_user_home mc_home_
	settings_branch="$mc_home_/.ksvd-local/settings.branch"
	settings_cluster="$mc_home_/.ksvd-local/settings.cluster"

	if [ -n "$is_upgrade_from_pre_55" ]; then
		[ -f "$settings_cluster" ] &&
			warn "$settings_cluster already exists, possibly from an upgrade of another server in this cluster."
		if [ "$run_mode" = "restart-only" ] ; then
			run_mode="unattended"
			if [ -f "$settings_cluster" ] ; then
				warn "Will not overwrite $settings_cluster"
				do_local_only=1
			fi
		fi
	fi

	if [ -e "$settings_cluster" ];then
		. "$settings_cluster"
		if [ -z "$KSVD_CLUSTER_UUID" ];then
			warn "KSVD_CLUSTER_UUID is null, 2sec later, auto try again"
			sleep 2
			. "$settings_cluster"
			[ -z "$KSVD_CLUSTER_UUID" ] && warn "KSVD_CLUSTER_UUID is still null"
		fi
		settings_cluster_custom=`sed -e "1,/^$eof_marker/d" "$settings_cluster"`
	else
		warn "$settings_cluster does not exist "
	fi
	if [ -z "$KSVD_USE_PAM" ] ; then
		case "$UNIQB_FIRST_INSTALLED_VERSION" in
		r4*|r5*)
			KSVD_USE_PAM="yes"
			if [ "$run_mode" = "restart-only" ] ; then
				run_mode="unattended"
			fi
			;;
		*)	KSVD_USE_PAM="<undefined>";;
		esac
	fi

	[ -e "$settings_branch" ] && . $settings_branch

	if [ -z "$KSVD_DBMOND_LOCK_TYPE" ] ; then
		sudo -u "$UNIQB_MC_USER" -H -- $bin_dir/ksvd-dbmond -lock-test $mc_home_
		
		case $? in
		0) KSVD_DBMOND_LOCK_TYPE="posix";;
		1) KSVD_DBMOND_LOCK_TYPE="symlink";;
		*) fatal "cannot determine a locking type for ksvd-dbmond";;
		esac
	fi
}

load_settings_and_defaults()
{
	# default values
	UNIQB_MC_USER="kylin-ksvd"

	# mc user must be loaded from the answer file, if one is available
	if [ -n "$do_answer_file" -a "$run_mode" != "restart-only" ]; then
		# get the new user name
		answer_tmp="/tmp/vc.$pid.answer"
		grep "^mc_user=" "$do_answer_file" > $answer_tmp
		[ -s $answer_tmp ] && {
			# not using eval due to its handling of spaces
			. $answer_tmp
			UNIQB_MC_USER="$mc_user"
		}
	fi

	local hostname=`hostname`
	UNIQB_FIRST_INSTALLED_VERSION="$PRODBLD"
	UNIQB_SERVER_ROLE="CM_VDI"
	UNIQB_KSVD_PUBADDR=`cat /etc/hosts|grep "manage${hostname}$"|awk '{print $1}'`
	KSVD_USER_PUBADDR=
	UNIQB_NAT_SUBNET="192.168.84"
	UNIQB_TOMCAT_PORT=8443
	UNIQB_LEAF_UPDATE_PORT=8080
	KSVD_SERVER_UUID=`uuidgen`
	UNIQB_USERNAME_SPACE_REPLACEMENT="^"
	UNIQB_DBG_MOD_ALL="info"
	UNIQB_MAX_LOG_NUM="10"
	KSVD_ISOLATED_GATEWAY="no"
	KSVD_GATEWAY_CM_LIST=""
	KSVD_INITIAL_RESOURCE_TAGS=""
	UNIQB_USERIMG_MAX_SIZE="1024"
	UNIQB_SYSIMG_MAX_SIZE="1024"
	UNIQB_BRANCH_USER_DATA_SYNC_TIME="1:00"
	KSVD_BRANCH_SYNC_INTERVAL="5"

	KSVD_CACHEIO_SYNC_INTERVAL="1"
	KSVD_CACHEIO_DIR="/home/cacheio/read"
	KSVD_STORAGE_TYPE="LOCAL"
	KSVD_STORAGE_VOLUME="NONE"
	UNIQB_SNAP_DIR="/home/cacheio/write"

	KSVD_DISABLE_CPUFREQ="no"

	# KSVD 5.5 settings:
	#   $VARPREFIX/settings.node
	#   $MC_USER_HOME/.ksvd-local/settings.cluster
	#   $MC_USER_HOME/.ksvd-local/settings.branch
	# pre-KSVD 5.5 settings:
	#   $VARPREFIX/settings.global
	#   $VARPREFIX/settings.branch

	if [ -e "$settings_node" ] ; then
		. "$settings_node"
		settings_node_custom=`sed -e "1,/^$eof_marker/d" "$settings_node"`
	else
		if [ -e "$pre_55_global" ] ; then
			. "$pre_55_global"
			is_upgrade_from_pre_55=1
			warn "Upgrading from a pre-KSVD-5.5 configuration"
			[ -e "$pre_55_branch" ] && . "$pre_55_branch"
			# Set arbitrarily to an r510 version that precedes 5.5
			UNIQB_FIRST_INSTALLED_VERSION="r510.9872"
		else
			warn "First-time $PRODPKGNAME configuration of this server"
			is_fresh_install=1
		fi
	fi

	export LD_LIBRARY_PATH=/opt/gmssl/lib/:/usr/lib64:$LD_LIBRARY_PATH
	if [ -x /usr/libexec/qemu-kvm ] ; then
		KSVD_KVM_VER=`/usr/libexec/qemu-kvm --version |grep version | awk '{print $4}'`
		if [ $KSVD_KVM_VER == "4.1.0" ] ; then
			KSVD_KVM_VER="410"
		elif [ $KSVD_KVM_VER == "2.12.0" ] ; then
			KSVD_KVM_VER="210"
		elif [ $KSVD_KVM_VER == "2.10.0" ] ; then
			KSVD_KVM_VER="210"
		else
			KSVD_KVM_VER=""
		fi
	else
		KSVD_KVM_VER=""
	fi
	# mc user might be set later, from answer file or interactively
	check_user_existence "$UNIQB_MC_USER" "silent" || return

	get_mc_user_home mc_home_
	settings_cluster="$mc_home_/.ksvd-local/settings.cluster"

	if [ "$run_mode" = "restart-only" -a -f "$settings_node" -a ! -f "$settings_cluster" ] ; then
		run_mode="upgrade-without-mc-home"
		return
	fi

	if [ -f "$settings_node" -a ! -f "$settings_cluster" -a ! -d "$mc_home_/.ksvd-users" ] ; then
		warn "First-time $PRODPKGNAME configuration of this server (even though settings.node exists)"
		is_fresh_install=1
	fi

	load_from_mc_user_home
}

generate_settings_branch()
{
	[ -z "$CLOUD_PASSWORD" ] && return

	# encode only if a new password was entered
	case $CLOUD_PASSWORD in
	PASSWORD=*) encoded="$CLOUD_PASSWORD";;
	*) encoded=`echo "$CLOUD_PASSWORD" | $bin_dir/ksvd-util --encrypt-password`
	   encoded="PASSWORD=$encoded"
	   ;;
	esac

	cat >$1 <<EOF
# $PRODPKGNAME Branch server settings
UNIQB_BRANCH_USER_DATA_SYNC_TIME="$UNIQB_BRANCH_USER_DATA_SYNC_TIME"
EOF
	[ -n "$CLOUD_PASSWORD" ] && {
		cat >>$1 <<EOF
CLOUD_USERNAME="$CLOUD_USERNAME"
CLOUD_PASSWORD="$encoded"
CLOUD_ADDR="$CLOUD_ADDR"
EOF
	}
	[ -n "$SAME_AS_CENTER" ] && echo "SAME_AS_CENTER=\"${SAME_AS_CENTER}\"" >> $1
	[ -n "$STORAGE_LOCATION" ] && echo "STORAGE_LOCATION=\"${STORAGE_LOCATION}\"" >> $1
	[ -n "$AVAILABLE" ] && echo "AVAILABLE=\"${AVAILABLE}\"" >> $1
}

generate_settings_node()
{
	[ "$UNIQB_SERVER_ROLE" != "Gateway" ] && KSVD_ISOLATED_GATEWAY="no"

	cat >$1 <<EOF
# $PRODPKGNAME Node configuration, automatically created by ksvd-config
UNIQB_MC_USER="$UNIQB_MC_USER"
UNIQB_SERVER_ROLE="$UNIQB_SERVER_ROLE"
KSVD_SERVER_UUID="$KSVD_SERVER_UUID"
UNIQB_DBG_MOD_ALL="$UNIQB_DBG_MOD_ALL"
UNIQB_MAX_LOG_NUM="$UNIQB_MAX_LOG_NUM"
KSVD_ISOLATED_GATEWAY="$KSVD_ISOLATED_GATEWAY"
KSVD_GATEWAY_CM_LIST="$KSVD_GATEWAY_CM_LIST"
KSVD_INITIAL_RESOURCE_TAGS="$KSVD_INITIAL_RESOURCE_TAGS"
EOF
	[ -n "$UNIQB_KSVD_PUBADDR" ] && printf "UNIQB_KSVD_PUBADDR=\"$UNIQB_KSVD_PUBADDR\"\n" >> $1
	[ -n "$KSVD_USER_PUBADDR" ] && printf "KSVD_USER_PUBADDR=\"$KSVD_USER_PUBADDR\"\n" >> $1
	[ -n "$UNIQB_NAT_SUBNET" ] && printf "UNIQB_NAT_SUBNET=\"$UNIQB_NAT_SUBNET\"\n" >> $1
	[ -n "$KSVD_KVM_VER" ] && printf "KSVD_KVM_VER=\"$KSVD_KVM_VER\"\n" >> $1
	[ -n "$UNIQB_USER_DATA_HOME" ] && printf "UNIQB_USER_DATA_HOME=\"$UNIQB_USER_DATA_HOME\"\n" >> $1
	[ -n "$UNIQB_GOLD_AS_DATA" ] && printf "UNIQB_GOLD_AS_DATA=\"$UNIQB_GOLD_AS_DATA\"\n" >> $1
	[ -n "$UNIQB_USER_LOG_AS_DATA" ] && printf "UNIQB_USER_LOG_AS_DATA=\"$UNIQB_USER_LOG_AS_DATA\"\n" >> $1

	cat >>$1 <<EOF
KSVD_DISABLE_CPUFREQ="$KSVD_DISABLE_CPUFREQ"
$eof_marker
$settings_node_custom
EOF
}

generate_settings_cluster()
{
	[ "$KSVD_USE_PAM" = "<undefined>" ] && KSVD_USE_PAM="no"
	[ -z "$KSVD_CLUSTER_UUID" ] && KSVD_CLUSTER_UUID=$KSVD_SERVER_UUID

	cat >$1 <<EOF
# $PRODPKGNAME Cluster configuration, automatically created by ksvd-config
UNIQB_FIRST_INSTALLED_VERSION="$UNIQB_FIRST_INSTALLED_VERSION"
UNIQB_TOMCAT_PORT="$UNIQB_TOMCAT_PORT"
KSVD_USE_PAM="$KSVD_USE_PAM"
UNIQB_LEAF_UPDATE_PORT="$UNIQB_LEAF_UPDATE_PORT"
KSVD_CLUSTER_UUID="$KSVD_CLUSTER_UUID"
UNIQB_USERNAME_SPACE_REPLACEMENT="$UNIQB_USERNAME_SPACE_REPLACEMENT"
KSVD_BRANCH_SYNC_INTERVAL="$KSVD_BRANCH_SYNC_INTERVAL"
KSVD_CACHEIO_DIR="$KSVD_CACHEIO_DIR"
KSVD_CACHEIO_SYNC_INTERVAL="$KSVD_CACHEIO_SYNC_INTERVAL"
KSVD_STORAGE_TYPE="$KSVD_STORAGE_TYPE"
KSVD_STORAGE_VOLUME="$KSVD_STORAGE_VOLUME"
UNIQB_SNAP_DIR="$UNIQB_SNAP_DIR"
KSVD_DBMOND_LOCK_TYPE="$KSVD_DBMOND_LOCK_TYPE"
UNIQB_USERIMG_MAX_SIZE="$UNIQB_USERIMG_MAX_SIZE"
UNIQB_SYSIMG_MAX_SIZE="$UNIQB_SYSIMG_MAX_SIZE"
UNIQB_DEV_USB_SCHEME="all"
#NOTE:the seperator "|" means that the variable has muliple values 
#and each variable just select one variable 
#KSVD_DBG_IMMEDIATE_SPICE_AVAILABILITY="no"
#KSVD_DBG_RDP_THROUGH_INNER_NIC="no | yes"
#KSVD_DISK_IMAGE_TYPE="gow3 | qcow2"
#KSVD_NATIVE_USB_NUM="6"
#KSVD_NATIVE_USB_MODE="2 | 3"
#UNIQB_HARD_DRIVE_TYPE="ide | virtio" 
#UNIQB_SPICE_STREAMING_VIDEO="off | all | filter"
#UNIQB_MAX_LOG_NUM="10"
#KSVD_CLIENT_CONNECTION_SCHEDULING="1 | 0"
#UNIQB_USERIMG_MAX_SIZE="1024
#UNIQB_SYSIMG_MAX_SIZE="1024"
#UNIQB_KVM_HD0_CACHE_VALUE="unsafe | none | writeback | writethrough"
#UNIQB_KVM_HD1_CACHE_VALUE="unsafe | none | writeback | writethrough"
#KSVD_LINUX_GUEST_HOMES="1"
#UNIQB_DBG_MAX_LINES_PER_LOGFILE="100000"
$eof_marker
$settings_cluster_custom
EOF
}

# this function may be called on one server while KSVD is already running on another
system_file_setup_as_mc_user()
{
	etcpath_=$1
	multi_tenant_mode=$2
	home_=$HOME

	# fix: lack ksvd-orgs and waste a lot of time when chmod -R 
	multi_users_dir="$home_/ksvd-orgs/org-0/users"
	if [ ! -e "$multi_users_dir" ] ; then
		mkdir -p "$multi_users_dir"
		chmod 0755 "$multi_users_dir"
		chmod 0755 -R "$home_/ksvd-orgs" 
	fi

	if [ -n "$multi_tenant_mode" ] ; then
		users_dir="$home_/ksvd-orgs/org-0/users"
	else
		users_dir="$home_/.ksvd-users"
	fi

	pool_dir="$home_/.ksvd-pools"
	ksvdcommon_dir="$home_/ksvd-custom/ksvdcommon"
	local network_dir="$home_/network/"
	local heketi_dir="$home_/heketi/"

	mkdir -p "$home_/.LEAF" "$home_/.spool" "$ksvdcommon_dir" "$users_dir" "$pool_dir" "$network_dir" "$heketi_dir"
	chmod 0755 "$home_" "$home_/.ksvd" "$home_/.ksvd-local" "$ksvdcommon_dir" "$users_dir" "$pool_dir" "$network_dir"

	# WARNING: a race may be possible here. 
	# it would be a problem, though, only if settings.global.mc is 
	# simultaneously being written by the MC and by ksvd-config
	settings_global_mc="$home_/.ksvd/settings.global.mc"
	if [ ! -f "$settings_global_mc" ] ; then
		settings_global_mc_tmp="/tmp/vc.$$.settings.global.mc"
		cat <<EOF >"$settings_global_mc_tmp"
:
# DO NOT EDIT THIS FILE DIRECTLY
EOF
		mv "$settings_global_mc_tmp" "$settings_global_mc"
	fi

	# settings.branch must be readable by owner only, as it contains
	# login credentials
	settings_branch="$home_/.ksvd-local/settings.branch"
	[ -e "$settings_branch" ] && chmod 600 $settings_branch
}

# This function runs as root, any modifications to files or permissions
# in mc_home must be done in system_file_setup_as_mc_user
# (PAM mode is a small exception)
system_file_setup()
{
	[ -z "$UNIQB_MC_USER" ] && fatal "no UNIQB_MC_USER in system_file_setup"

	get_mc_user_home mc_home
	mc_gid=`id -g "$UNIQB_MC_USER"`

	leaf_root="$mc_home/.LEAF"

	[ -n "$is_fresh_install" -a "$KSVD_USE_PAM" != "yes" ] && multi_tenant_mode=1
 
	if [ "$run_mode" != "upgrade-without-mc-home" ] ; then
		mc_runas system_file_setup_as_mc_user "$ETCPATH" "$multi_tenant_mode"

		if [ "$KSVD_USE_PAM" = "yes" ] ; then
			users_dir="$mc_home/.ksvd-users"

			chown -R "$UNIQB_MC_USER:$mc_gid" "$leaf_root" "$users_dir"
		fi
	fi

	# no conflict with other systems, this is local
	rm -rf "$VARPREFIX/mc"
	mkdir -p "$VARPREFIX/mc/tmp" "$KSVD_CACHEIO_DIR"

	chmod a+r /etc/shadow
	chmod 644 $settings_node

	chown "$UNIQB_MC_USER:$mc_gid" \
		"$VARPREFIX" "$VARPREFIX/mc" "$VARPREFIX/mc/tmp" \
		"$KSVD_CACHEIO_DIR"
}

do_prompt()
{
	echo_off=
	accept_empty=

	prompt="$1"
	assigned_var="$2"  # default value

	# supported options (in 3'rd argument):
	# echo_off - use for passwords
	# empty_ok - accept an empty string as value (not the same 
	#            as accepting existing value)

	case "$3" in 
	echo_off) echo_off=1;;
	*) ;;
	esac

	case "$3" in 
	accept_empty) accept_empty=1;;
	*) ;;
	esac

	if [ -n "$echo_off" ]; then
		stty_save=`stty -g`
		stty -echo
	fi

	[ -n "$accept_empty" ] && prompt="$prompt(^D for empty string) "
	# read from tty so that it works when installing the KSVD package
	read -p "$prompt" answer < /dev/tty

	if [ $? -gt 0 ]; then
		# set to empty string
		echo
		eval "$assigned_var="
		return
	fi

	if [ -n "$answer" ]; then
		# eval does not handle spaces and back slashes well, so resort
		# to source if value contains backslashes
		# we do not support backslashes in passwords
		echo "$answer" | grep '[\\ \t]' > /dev/null
		if [ -z "$echo_off" -a "$?" != "0" ]; then
			eval "$assigned_var=\"$answer\""
		else
			echo "$assigned_var='$answer'" |sed 's/\\/\\\\/g' > $tmpfile
			. $tmpfile
			rm $tmpfile
		fi
	fi

	[ -n "$echo_off" ] && stty $stty_save
	echo
}

check_time()
{
	[ "$2" = "NEVER" ] && return 0
	time="$2";
	hours=`echo $time|sed 's/^\([0-9]*\):.*/\1/'`
	minutes=`echo $time|sed 's/.*:\([0-9]*\)$/\1/'`
	time2="${hours}:${minutes}"
	if [ "$time" != "$time2" ] ; then
		error "$1 does not match format"
		return 1
	fi
	if [ $hours -gt 23 -o $minutes -gt 59 ] ; then
		error "$1 is out of range"
		return 1
	fi
	return 0
}

# home directory is returned in the first argument
get_mc_user_home()
{
	check_user_existence "$UNIQB_MC_USER" || {
		exit 1
	}

	home_=`su - "$UNIQB_MC_USER" -c 'pwd'`
	[ -d "$home_" ] || {
		printf "Home directory of user '%s' not found\n" "$UNIQB_MC_USER"
		exit 1
	}
	eval "$1=\"$home_\""
}

check_server_role()
{
	case "$1" in
	CM_Only)   return 0;;
	CM_VDI)    return 0;;
	VDI_Only)  return 0;;
	Gateway)   return 0;;
	Arbiter)   return 0;;
	*)	   return 1;;
	esac
}

check_file()
{
	[ -r "$1" ] && return 0
	error "File $1 does not exist/is not readable"
	return 1
}

check_directory()
{
	[ -d "$1" ] && return 0
	error "Directory $1 does not exist"
	return 1
}

check_integer()
{
	val_="$1"
	min_="$2"
	max_="$3"
	[ "$val_" -ge "$min_" -a "$val_" -le "$max_" ] && return 0
	return 1
}

check_tomcat_port()
{
	if [ "$2" -le 1024 ] ; then
		error "The $PRODPKGNAME Console port must be greater than 1024"
		return 1
	fi
	if [ "$2" = 8080 -o "$2" = 8009 -o "$2" = 8005 ] ; then
		error "The $PRODPKGNAME Console port canot be set to 8080, 8009 or 8005"
		return 1
	fi
	return 0
}

check_leaf_update_port()
{
	if [ "$2" = "$UNIQB_TOMCAT_PORT" ] ; then
		error "The LEAF updates and the $PRODPKGNAME Console port must be assigned different ports"
		return 1
	fi
	[ "$2" -gt "1024" ] && return 0
	error "Port $2 is privilaged, $1 must be greater than 1024."
	return 1
}

check_user_existence()
{
	id -u "$1" 2>/dev/null >/dev/null && return 0
	# echo does not treat backslashes correctly, so use printf
	[ "$2" != "silent" ] && printf "${ansi_black_on_yellow}User '%s' does not exist[m\n" $1 
	return 1
}

interview_get_database_users()
{
	get_mc_user_home mc_home
	configFile=$mc_home"/.ksvd-local/mc-database-config.properties"

	ksvdInstallDir="/usr/lib/ksvd"
	hsqldb_dir=$ksvdInstallDir"/etc/hsqldb/"
	server_properties_file=$hsqldb_dir"server.properties"
	sqltool_file=$hsqldb_dir"sqltool.rc"
	sqltool=$hsqldb_dir"ksvd-hsqldb.sh"

	local_server_properties_file=$mc_home"/server.properties"
	local_sqltool_file=$mc_home"/sqltool.rc"

	tomcat_tool=$ksvdInstallDir"/bin/ksvd-start-tomcat.sh"

	IFS=$'\n'
	for line in `cat $configFile`
	do
		IFS='='
		a=($line)
		datasource=${a[0]}
		value=${a[1]}
		IFS=$'\n'

		if [ "$datasource" == "dataSource.username" ]
		then
			adminUser=$value
		fi
		if [ "$datasource" == "dataSource.password" ]
		then
			adminPass=$value
		fi
		if [ "$datasource" == "dataSource_ksvd.username" ]
		then
			rtUser=$value
		fi
		if [ "$datasource" == "dataSource_ksvd.password" ]
		then
			rtPass=$value
		fi
	done

	do_prompt "Enter Database Admin user name [$adminUser] " "newAdminUser"
	do_prompt "Enter Database Admin user password [$adminPass] " "newAdminPass"
	do_prompt "Enter Database Runtime user name [$rtUser] " "newRtUser"
	do_prompt "Enter Database Runtime user password [$rtPass] " "newRtPass"

	if [ "$newAdminUser" == "" ]
	then
		newAdminUser=$adminUser
	fi

	if [ "$newAdminPass" == "" ]
	then
		newAdminPass=$adminPass
	fi

	if [ "$newRtUser" == "" ]
	then
		newRtUser=$rtUser
	fi

	if [ "$newRtPass" == "" ]
	then
		newRtPass=$rtPass
	fi

	"$sqltool" sql "SELECT ROLE_NAME FROM INFORMATION_SCHEMA.APPLICABLE_ROLES;"
	[ $? != 0 ] && error "execut select role_name sql failed!" && return

	roles=`"$sqltool" sql "SELECT ROLE_NAME FROM INFORMATION_SCHEMA.APPLICABLE_ROLES;" | grep KSVD_ROLE`
	echo "Roles: $roles"
	if [ "$roles" == "" ]
	then
		"$sqltool" sql "CREATE ROLE KSVD_ROLE;commit;"
	fi

	rtnedUsers=`"$sqltool" sql "SELECT USER_NAME FROM INFORMATION_SCHEMA.SYSTEM_USERS WHERE USER_NAME='${newRtUser^^}';"`
	if [ "$rtnedUsers" == "" ]
	then
		"$sqltool" sql "CREATE USER ${newRtUser^^} PASSWORD \"$newRtPass\";commit;"
		"$sqltool" sql "ALTER USER ${newRtUser^^} SET LOCAL TRUE;commit;"
		"$sqltool" sql "GRANT KSVD_ROLE to ${newRtUser^^};commit;"
	else
		"$sqltool" sql "ALTER USER ${newRtUser^^} SET PASSWORD \"$newRtPass\";commit;"
	fi

	rtnedUsers=`"$sqltool" sql "SELECT USER_NAME FROM INFORMATION_SCHEMA.SYSTEM_USERS WHERE USER_NAME='${newAdminUser^^}';"`
	if [ "$rtnedUsers" == "" ]
	then
		"$sqltool" sql "CREATE USER ${newAdminUser^^} PASSWORD \"$newAdminPass\" ADMIN;commit;"
		"$sqltool" sql "ALTER USER ${newAdminUser^^} SET LOCAL TRUE;commit;"
	else
		"$sqltool" sql "SET PASSWORD \"$newAdminPass\";commit;"
	fi

    cat <<EOM >$configFile
dataSource.username=${newAdminUser^^}
dataSource.password=$newAdminPass
dataSource_ksvd.username=${newRtUser^^}
dataSource_ksvd.password=$newRtPass
EOM

    tmp_properties_file=$mc_home"/server.properties.new"

    IFS=$'\n'
    if [ -f $tmp_properties_file ]
    then
        rm $tmp_properties_file
    fi

	for line in `cat $server_properties_file`
	do
		isThere=`echo $line | grep "server.database"`
		ndx=`echo ${#isThere}`
		if [ $ndx == 0 ]
		then
			echo $line >>$tmp_properties_file
		else
			isThere=`echo $line | grep "username"`
			ndx=`echo ${#isThere}`
			if [ $ndx == 0 ]
			then
				tmp=$line
			else
				ndx=`echo $line | grep -bo ";username" | cut -d':' -f1`
				tmp=`echo ${line:0:$ndx}`
			fi
			echo $tmp";username=\""${newAdminUser^^}"\";password=\""$newAdminPass"\"" >>$tmp_properties_file
		fi
	done

    mv $server_properties_file $server_properties_file".bak"
    cp $tmp_properties_file $server_properties_file
    mv $tmp_properties_file $local_server_properties_file

    tmp_sql_file=$mc_home"/sqltool.rc.new"
    IFS=$'\n'
    if [ -f $tmp_sql_file ]
    then
        rm $tmp_sql_file
    fi

    for line in `cat $sqltool_file`
    do
        isThere=`echo $line | grep "username"`
        ndx=`echo ${#isThere}`
        if [ $ndx != 0 ]
        then
            echo "username "${newAdminUser^^} >>$tmp_sql_file
        else
			isThere=`echo $line | grep "password"`
			ndx=`echo ${#isThere}`
			if [ $ndx != 0 ]
			then
	            echo "password "$newAdminPass >>$tmp_sql_file
	        else
	            echo $line >>$tmp_sql_file
	        fi
	    fi
    done
    mv $sqltool_file $sqltool_file".bak"
    cp $tmp_sql_file $sqltool_file
    mv $tmp_sql_file $local_sqltool_file

	"$tomcat_tool" restart
}

interview_get_role()
{
	case "$UNIQB_SERVER_ROLE" in
	CM_Only) role=1;;
	CM_VDI) role=2;;
	VDI_Only) role=3;;
	Gateway) role=4;;
	*) role= ;;
	esac

	while [ "forever" ] ; do
		cat <<EOT
What is the role of this server? [$role]
1) $PRODPKGNAME Cluster Master + $PRODPKGNAME Console (does not host VDI sessions)
2) $PRODPKGNAME Cluster Master + $PRODPKGNAME Console + $PRODPKGNAME VDI Server
3) $PRODPKGNAME VDI Server only (cluster node)
4) $PRODPKGNAME Gateway only (connection broker)
EOT
		p="Select [1-4]: "
		do_prompt "$p" "role"

		case "$role" in
		1) UNIQB_SERVER_ROLE="CM_Only"; break;;
		2) UNIQB_SERVER_ROLE="CM_VDI"; break;;
		3) UNIQB_SERVER_ROLE="VDI_Only"; break;;
		4) UNIQB_SERVER_ROLE="Gateway"; break;;
		*) ;;
		esac

	done
}

interview_get_public_address()
{
	needs_pubaddr=
	needs_user_pubaddr=

	case "$UNIQB_SERVER_ROLE" in
	VDI_Only) needs_user_pubaddr=1; needs_pubaddr=1;;
	CM_VDI)   needs_user_pubaddr=1; needs_pubaddr=1;;
	Gateway)  needs_user_pubaddr=1; needs_pubaddr=1;;
	*)        needs_pubaddr=1;;
	esac

	if [ -n "$needs_pubaddr" ] ; then
		while [ "forever" ] ; do
			p="What is the public IP address or FQDN of this server, to be used for management traffic [$UNIQB_KSVD_PUBADDR]? "
			do_prompt "$p" "UNIQB_KSVD_PUBADDR"
			[ -n "$UNIQB_KSVD_PUBADDR" ] && break
		done
	else
		UNIQB_KSVD_PUBADDR=
	fi

	if [ -n "$needs_user_pubaddr" ] ; then
		if [ -n "$UNIQB_KSVD_PUBADDR" ] ; then
			p="What is the public IP address or FQDN of this server, to be used for user traffic [$KSVD_USER_PUBADDR]? (leave empty to use $UNIQB_KSVD_PUBADDR)"
			do_prompt "$p" "KSVD_USER_PUBADDR" "accept_empty"
		else
			while [ "forever" ] ; do
				p="What is the public IP address or FQDN of this server, to be used for user traffic [$KSVD_USER_PUBADDR]? "
				do_prompt "$p" "KSVD_USER_PUBADDR"
				[ -n "$KSVD_USER_PUBADDR" ] && break
			done
		fi
	else
		KSVD_USER_PUBADDR=
	fi
}

interview_get_gateway_settings()
{
	[ "$UNIQB_SERVER_ROLE" != "Gateway" ] && return

	while [ "forever" ] ; do
		p="Is this an isolated gateway server (yes|no) [$KSVD_ISOLATED_GATEWAY]? "
		do_prompt "$p" "KSVD_ISOLATED_GATEWAY"
		[ "$KSVD_ISOLATED_GATEWAY" = "yes" ] && break
		[ "$KSVD_ISOLATED_GATEWAY" = "no" ] && return
	done

	cat <<EOT
Isolated gateways require configuring one or more IP address or FQDN of the 
cluster master(s) to which the gateways will connect.

When specifying multiple addresses, separate them by semi-colons.
EOT
	p="What is the public IP addresss or FQDN's of the cluster master(s) [$KSVD_GATEWAY_CM_LIST]? "
	while [ "forever" ] ; do
		do_prompt "$p" "KSVD_GATEWAY_CM_LIST"
		[ -n "$KSVD_GATEWAY_CM_LIST" ] && break
	done
}

interview_get_resource_tags()
{
	p="What are the initial resource tags for this server [$KSVD_INITIAL_RESOURCE_TAGS]? "
	do_prompt "$p" "KSVD_INITIAL_RESOURCE_TAGS" "accept_empty"
}

interview_get_mc_user()
{
	mc_user_="$UNIQB_MC_USER"

	while [ "forever" ] ; do
		p="What is the $PRODPKGNAME Management Console account [$UNIQB_MC_USER]? "
		do_prompt "$p" "UNIQB_MC_USER"

		check_user_existence "$UNIQB_MC_USER" && break
	done

	# reload only if changed. note that this might override some
	# answer file values
	[ "$mc_user_" != "$UNIQB_MC_USER" ] && load_from_mc_user_home
}

interview_get_branch_settings()
{
	is_branch="no"
	[ -n "$CLOUD_ADDR" ] && is_branch="yes"

	while [ "forever" ] ; do
		p="How often should branches synchronize (1-600 minutes) [$KSVD_BRANCH_SYNC_INTERVAL]? "
		do_prompt "$p" "KSVD_BRANCH_SYNC_INTERVAL"
		check_integer "$KSVD_BRANCH_SYNC_INTERVAL"  1 600 && break
	done

	while [ "forever" ] ; do
		p="Is this a branch server (yes|no) [$is_branch]? "
		do_prompt "$p" "is_branch"
		[ "$is_branch" = "yes" ] && {
			#if it is the branch mode, then remove the db directory and stop KSVD service
			#added by lx
			get_mc_user_home mc_home
			db_dir=$mc_home"/db/"
			if [ -d "$db_dir" ]; then {
				rm_db="no"
				while [ "forever" ] ; do 
					p="In order to avoid conflicts of database in branch mode, the db directory needs to be removed for the sake of running branch server successfully. Do you want to remove db directory now (yes|no) [$rm_db]? "
					do_prompt "$p" "rm_db"
					if [ "$rm_db" = "yes" ]; then { 
						/usr/lib/ksvd/bin/rc.ksvd stop
						rm -rf $db_dir
						/usr/lib/ksvd/bin/rc.ksvd status
						if [ $? -eq 0 ]; then {
					 		echo "
The KSVD services are still running, please check your KSVD
environment and make sure that KSVD services are completely
stopped and then configure the branch mode again
							"
							exit
						}
						fi
						break
					}	
					elif [ "$rm_db" = "no" ]; then {
						exit
					}
					fi
				done
			}
			fi
		break
		}
		[ "$is_branch" = "no" ] && {
			CLOUD_ADDR=
			CLOUD_USERNAME=
			CLOUD_PASSWORD=
			return
		}
	done

	p="What is the address of the SmartSync Server [$CLOUD_ADDR]? "
	while [ "forever" ] ; do
		do_prompt "$p" "CLOUD_ADDR"
		[ -n "$CLOUD_ADDR" ] && break
	done


	cat <<EOT
This Branch Server requires credentials for downloading
updates from the SmartSync Server. You will now be asked to enter the
credentials for this operation.
Passwords will not be echoed back to the terminal.

Note: backslashes are not supported in passwords

EOT
	p="Enter username for logging in to SmartSync Server [$CLOUD_USERNAME] "
	while [ "forever" ] ; do
		do_prompt "$p" "CLOUD_USERNAME"
		[ -n "$CLOUD_USERNAME" ] && break
	done

	pw_confirm="$CLOUD_PASSWORD"

	while [ "forever" ] ; do
		p="Enter password for logging in to SmartSync Server [******] "
		do_prompt "$p" "CLOUD_PASSWORD" "echo_off"
		p="Re-enter password [******] "
		do_prompt "$p" "pw_confirm" "echo_off"
		[ "$CLOUD_PASSWORD" = "$pw_confirm" ] && break
		error "Passwords did not match, try again"
	done

	echo
        echo "Trying to connect to smart server"

        tmpfile=`mktemp /tmp/curl.XXXX`
        mc_addr="https://$CLOUD_ADDR:8443/mc"
        curl -i -k -u $CLOUD_USERNAME:$CLOUD_PASSWORD --connect-timeout 3 "$mc_addr"/unauth/redirectToActiveMC 1>$tmpfile 2>/dev/null

        if [ $? -ne 0 ] ; then
                fatal "Can not connect to smart server, please check your network or make sure smart server is online"
        fi

        status=`sed -n '1p' $tmpfile | awk '{print $2}'`
        if [ $status -eq 302 ] ; then
                mc_addr=`sed -n '/Location/p' $tmpfile | awk '{print $2}' | sed 's/^M//g'`
                echo "Redirect to $mc_addr"
        fi

        status=`curl -i -k -u $CLOUD_USERNAME:$CLOUD_PASSWORD "$mc_addr"/ksvd/getLicense | sed -n '1p' | awk '{print $2}'`

        if [ "$status" !=  "200" ] ; then
                fatal "Username or password incorrect"
        else
                echo "Authorization success"
        fi
        echo
        rm -f $tmpfile
		
	p="Enter time of day at which user data will be synchronized (NEVER, or 00:00 - 23:59) [$UNIQB_BRANCH_USER_DATA_SYNC_TIME]? "
	while [ "forever" ] ; do
		do_prompt "$p" "UNIQB_BRANCH_USER_DATA_SYNC_TIME"
		check_time UNIQB_BRANCH_USER_DATA_SYNC_TIME $UNIQB_BRANCH_USER_DATA_SYNC_TIME  && break
	done
}

interview_get_cluster_misc()
{
	# if KSVD_USE_PAM is already set, don't let it be changed
	if [ "$KSVD_USE_PAM" = "<undefined>" ] ; then 
		KSVD_USE_PAM="no"
		p="Should PAM be used to authenticate users (yes|no) [$KSVD_USE_PAM]? "
		while [ "forever" ] ; do
			do_prompt "$p" "KSVD_USE_PAM"
			[ "$KSVD_USE_PAM" = "yes" ] && break
			[ "$KSVD_USE_PAM" = "no" ] && break
		done
	fi

	[ -n "$do_local_only" ] && return

	p="On which port should $PRODPKGNAME Console and User Console run [$UNIQB_TOMCAT_PORT]? "
	while [ "forever" ] ; do
		do_prompt "$p" "UNIQB_TOMCAT_PORT"
		check_tomcat_port "UNIQB_TOMCAT_PORT" "$UNIQB_TOMCAT_PORT"
		[ $? = 0 ] && break

	done

	p="On which port should LEAF updates be served [$UNIQB_LEAF_UPDATE_PORT]? "
	while [ "forever" ] ; do
		do_prompt "$p" "UNIQB_LEAF_UPDATE_PORT"
		check_leaf_update_port "UNIQB_LEAF_UPDATE_PORT" "$UNIQB_LEAF_UPDATE_PORT"
		[ $? = 0 ] && break
	done

	p="What character should be used to replace space characters in user names? [$UNIQB_USERNAME_SPACE_REPLACEMENT]"
	while [ "forever" ] ; do
		do_prompt "$p" "UNIQB_USERNAME_SPACE_REPLACEMENT"
		[ -n "$UNIQB_USERNAME_SPACE_REPLACEMENT" ] && break
		error "character must be entered"
	done
}

interview_read_cacheio_settings()
{
	[ -n "$do_local_only" ] && return

	echo "The following settings are used only when Read CacheIO is enabled in the Management Console"
	echo

	while [ "forever" ] ; do
		p="What local directory should be used for Read CacheIO [$KSVD_CACHEIO_DIR]? "
		do_prompt "$p" "KSVD_CACHEIO_DIR" 
		check_directory "$KSVD_CACHEIO_DIR" && rm -rf "$KSVD_CACHEIO_DIR/templates" && break

		p="Create it (yes|no)? "
		create_="no"
		do_prompt "$p" "create_"
		[ "$create_" != "yes" ] && continue

		mkdir -p "$KSVD_CACHEIO_DIR"
		break
	done

	while [ "forever" ] ; do
		p="How often should VDI nodes synchronize gold images from external storage (1-600 minutes) [$KSVD_CACHEIO_SYNC_INTERVAL]? "
		do_prompt "$p" "KSVD_CACHEIO_SYNC_INTERVAL"
		check_integer "$KSVD_CACHEIO_SYNC_INTERVAL"  1 600 && break
	done
}

interview_write_cacheio_settings()
{
	[ -n "$do_local_only" ] && return

	while [ "forever" ] ; do
		p="What local directory should be used for Write CacheIO (leave empty to use users' home directories) [$UNIQB_SNAP_DIR]? "
		do_prompt "$p" "UNIQB_SNAP_DIR" "accept_empty"
		[ -z "$UNIQB_SNAP_DIR" ] && break
		check_directory "$UNIQB_SNAP_DIR" && break
	done
}

update_tomcat_config()
{
	tomcat_config="$ETCPATH/apache-tomcat/conf/server.xml"

  # tomcat won't be available when installing KSVD-core before KSVD-web
  if [ -f "$tomcat_config" ] ; then
  	echo "* Updating $tomcat_config"
	  sed -i -e "/Connector SSLEnabled/ s|port=\"[^\"]*\"|port=\"$UNIQB_TOMCAT_PORT\"|" $tomcat_config
	  sed -i -e "/Connector.*protocol=.HTTP/ s|port=\"[^\"]*\"|port=\"$UNIQB_LEAF_UPDATE_PORT\"|" $tomcat_config
	  if [ "$MADE_CERT" = "yes" ]; then
		  sed -i -e "s|keystoreFile=\".*\"|keystoreFile=\"$VARPREFIX/host.p12\"|" $tomcat_config
		  sed -i -e "s|keystorePass=\".*\"|keystorePass=\"$_UNIQB_KEYSTORE_PASS\"|" $tomcat_config
	  fi
  	cp "$tomcat_config" "$VARPREFIX/server.xml"
	  chmod 444 "$tomcat_config"
	fi
}

tmp_file_cleanup()
{
	rm -f /tmp/vc.$pid.*

	[ -n "$stty_save" ] && stty $stty_save
	echo
	warn "Aborted"
	exit 1
}

generate_settings_files()
{
	settings_node_tmp="/tmp/vc.$pid.settings.node"
	settings_cluster_tmp="/tmp/vc.$pid.settings.cluster"
	settings_branch_tmp="/tmp/vc.$pid.settings.branch"

	generate_settings_node		"$settings_node_tmp"
	generate_settings_cluster	"$settings_cluster_tmp"
	generate_settings_branch	"$settings_branch_tmp"
}

view_configuration()
{
	generate_settings_files
	echo "$ansi_on New $PRODPKGNAME Configuration $1 $ansi_off" 
	echo "$ansi_on Node configuration $ansi_off" 
	cat "$settings_node_tmp"
	echo
	if [ -z "$do_local_only" ]; then
		echo "$ansi_on Cluster configuration $ansi_off" 
		cat "$settings_cluster_tmp"
		[ -f $settings_branch_tmp ] && sed 's/PASSWORD=.*/PASSWORD=******/' "$settings_branch_tmp"
	fi
	echo
}

configuration_menu()
{

	while [ "forever" ] ; do
		cat <<EOT
$ansi_on *** $PRODPKGNAME Server Configuration ***
Please select an item to configure:

1) Set $PRODPKGNAME Management account

Node settings:
2) Set server's role 
3) Set role-specific settings
4) Set database users

Cluster settings:
5) Set $PRODPKGNAME Branch-related settings
6) Set other cluster-wide settings
7) Set Read CacheI/O settings
8) Set Write CacheI/O settings

General:
v) View configuration
S) Save settings, restart $PRODPKGNAME and exit
q) Quit without saving
$ansi_off
EOT
		p="Enter an item: "
		item=
		do_prompt "$p" "item"

		case "$item" in
		v) view_configuration "(not saved yet)";;
		S) configuration_finalize; exit 0;;
		q) break;;

		1) interview_get_mc_user;;
		2) interview_get_role;;
		3) interview_get_public_address
		   interview_get_gateway_settings
		   interview_get_resource_tags;;
		4) interview_get_database_users;;


		5) interview_get_branch_settings;;
		6) interview_get_cluster_misc;;
		7) interview_read_cacheio_settings;;
		8) interview_write_cacheio_settings;;

		*) error "Unrecognized option " $item
		esac
	done
}

configure_interview()
{

	cat <<EOT
$ansi_on *** $PRODPKGNAME Server Configuration ***

Press Ctrl-C at any time to exit without saving changes.

Some configuration questions present the previous/default value within [].
Simply press ENTER to accept the previous/default value unchanged.

When entering names that contain backslashes, be sure to escape them
by typing two backslashes. E.g. domain\\\\user

If the letter that follows the backslash is one of: n r t then enter
four (4) backslashes. E.g. domain\\\\\\\\nt\\\\user
$ansi_off
EOT

	# Node settings
	interview_get_mc_user
	interview_get_role
	interview_get_public_address
	interview_get_gateway_settings
	interview_get_resource_tags

	# Cluster settings
	interview_get_branch_settings
	interview_get_cluster_misc
	interview_read_cacheio_settings
	interview_write_cacheio_settings
}

create_directories()
{
	home_=$HOME
	mkdir -p "$home_/.ksvd" "$home_/.ksvd-local"
	chmod 0755 "$home_" "$home_/.ksvd" "$home_/.ksvd-local"
}

finalize_settings_files_as_mc_user()
{
	pid_=$1
	do_local_only_=$2
	settings_cluster_tmp="/tmp/vc.$pid_.settings.cluster"
	settings_branch_tmp="/tmp/vc.$pid_.settings.branch"

	home_=$HOME
	settings_branch="$home_/.ksvd-local/settings.branch"
	settings_cluster="$home_/.ksvd-local/settings.cluster"

	if [ -f "/.vdsb" -a -f $ETCPATH/LAP.tar -a ! -d "$home_/LAP" ] ; then
		tar --extract -C "$home_" -f $ETCPATH/LAP.tar
	fi

	if [ -z "$do_local_only_" ]; then
		echo "* Writing $settings_cluster"
		cp "$settings_cluster_tmp" "$settings_cluster"
		[ $? != 0 ] && return $?

		if [ -f "$settings_branch_tmp" ]; then
			echo "* Writing $settings_branch"
			cp "$settings_branch_tmp" "$settings_branch"
			[ $? != 0 ] && return $?
		fi
	fi

	return 0
}

finalize_settings_files()
{
	[ -z "$UNIQB_MC_USER" ] && fatal "no UNIQB_MC_USER in finalize_settings_files"
	get_mc_user_home mc_home

	mc_runas create_directories
	if [ "$postinst_arg" != "postinstall" ]; then
		if [ "$UNIQB_SERVER_ROLE" == "CM_Only" -o "$UNIQB_SERVER_ROLE" == "CM_VDI" -o "$UNIQB_SERVER_ROLE" == "CM_VDI_GPU" -o "$UNIQB_SERVER_ROLE" == "VDI_Only" -o "$UNIQB_SERVER_ROLE" == "Gateway" -o "$UNIQB_SERVER_ROLE" == "Arbiter" ]; then
			mc_runas finalize_settings_files_as_mc_user $pid $do_local_only
		else
			[ "$KSVD_SERVER_UUID" == "$KSVD_CLUSTER_UUID" ] && fatal "This node is a $UNIQB_SERVER_ROLE role, fail to read KSVD_CLUSTER_UUID, please check  ..."
		fi
	else
		mc_runas finalize_settings_files_as_mc_user $pid $do_local_only
	fi

	rm $settings_cluster_tmp
	if [ -f "$settings_branch_tmp" ] ; then
		rm $settings_branch_tmp
	else
		[ -e "$settings_branch" ] && rm -f $settings_branch
	fi

	echo "* Writing $settings_node"
	mkdir -p "$VARPREFIX"
	mv "$settings_node_tmp" "$settings_node"

	# Temporary fix for Kylin branding issue
        mkdir -p /var/lib/ksvd
        #if [ -f "/var/lib/ksvd/settings.node" ] ; then
        #        rm /var/lib/ksvd/settings.node
        #fi
        #ln "$settings_node" /var/lib/ksvd

        update_tomcat_config

	# pre-5.5 upgrade stuff
	if [ -e "$pre_55_global" ] ; then
		# Take out the old configuration, rename rather than deleting
		mv "$pre_55_global" "$pre_55_global.before_upgrade"
		[ -e "$pre_55_branch" ] && mv "$pre_55_branch" "$pre_55_branch.before_upgrade"

		# populate the license file from the existing 
		# WARNING: root access to mc_home
		[ -e "$VARPREFIX/license.lic" -a ! -e "$mc_home/.ksvd/license.lic" ] &&
			cp "$VARPREFIX/license.lic" "$mc_home/.ksvd/license.lic"
	fi
}

configure_from_answer_file()
{
	answer_tmp="/tmp/vc.$pid.answer"

	grep "^[a-z][a-z0-9_]*=" "$do_answer_file" > $answer_tmp

	grep -q '`' "$answer_tmp"
	if [ $? = 0 ] ; then
		rm $answer_tmp
		fatal "Answer file must not contain backquote"
	fi

	# not using eval because it compresses spaces and changes tabs to spaces
	# both of which are harmful to branch password
	. $answer_tmp
	rm $answer_tmp

	UNIQB_MC_USER=${mc_user:-"$UNIQB_MC_USER"}
	UNIQB_USER_DATA_HOME=${user_data_home}
	UNIQB_GOLD_AS_DATA=${gold_as_data}
	UNIQB_USER_LOG_AS_DATA=${user_log_as_data}
	UNIQB_SERVER_ROLE=${server_role:-"$UNIQB_SERVER_ROLE"}
	UNIQB_KSVD_PUBADDR=${pubaddr:-"$UNIQB_KSVD_PUBADDR"}
	KSVD_USER_PUBADDR=${user_pubaddr:-"$KSVD_USER_PUBADDR"}
	UNIQB_NAT_SUBNET=${nat_subnet:-"$UNIQB_NAT_SUBNET"}
	UNIQB_DBG_MOD_ALL=${debug_level:-"$UNIQB_DBG_MOD_ALL"}
	UNIQB_MAX_LOG_NUM=${log_number:-"$UNIQB_MAX_LOG_NUM"}
	# if KSVD_USE_PAM is already set, don't let it be changed
	[ "$KSVD_USE_PAM" = "<undefined>" ] && KSVD_USE_PAM=${use_pam:-"no"}
	KSVD_ISOLATED_GATEWAY=${isolated_gateway:-"no"}
	KSVD_GATEWAY_CM_LIST=${gateway_cm_list:-""}
	KSVD_INITIAL_RESOURCE_TAGS=${resource_tags:-""}

	UNIQB_TOMCAT_PORT=${tomcat_port:-"$UNIQB_TOMCAT_PORT"}
	UNIQB_LEAF_UPDATE_PORT=${leaf_update_port:-"$UNIQB_LEAF_UPDATE_PORT"}
	UNIQB_USERNAME_SPACE_REPLACEMENT=${username_space_replacement:-"$UNIQB_USERNAME_SPACE_REPLACEMENT"}

	KSVD_CACHEIO_DIR=${cacheio_dir:-"$KSVD_CACHEIO_DIR"}
	KSVD_CACHEIO_SYNC_INTERVAL=${cacheio_sync_interval:="$KSVD_CACHEIO_SYNC_INTERVAL"}
	KSVD_STORAGE_TYPE=${storage_type:-"$KSVD_STORAGE_TYPE"}
	KSVD_STORAGE_VOLUME=${storage_volume:-"$KSVD_STORAGE_VOLUME"}

	UNIQB_SNAP_DIR=${snap_dir-"$UNIQB_SNAP_DIR"}
	KSVD_DBMOND_LOCK_TYPE=${dbmond_lock_type:-"$KSVD_DBMOND_LOCK_TYPE"}

	CLOUD_ADDR=${cloud_addr:-"$CLOUD_ADDR"}
	CLOUD_USERNAME=${cloud_username:-"$CLOUD_USERNAME"}
	CLOUD_PASSWORD=${cloud_password:-"$CLOUD_PASSWORD"}
	SAME_AS_CENTER=${same_as_center}
	STORAGE_LOCATION=${storage_location}
	UNIQB_BRANCH_USER_DATA_SYNC_TIME=${branch_user_data_sync_time:-"$UNIQB_BRANCH_USER_DATA_SYNC_TIME"}
	KSVD_BRANCH_SYNC_INTERVAL=${branch_sync_interval:="$KSVD_BRANCH_SYNC_INTERVAL"}

	# validate settings from answer file
	check_server_role "$UNIQB_SERVER_ROLE" || fatal "Invalid server role $UNIQB_SERVER_ROLE"

	check_user_existence "$UNIQB_MC_USER" || exit 1
	check_tomcat_port "UNIQB_TOMCAT_PORT" "$UNIQB_TOMCAT_PORT" || exit 1
	check_leaf_update_port "UNIQB_LEAF_UPDATE_PORT" "$UNIQB_LEAF_UPDATE_PORT" || exit 1

	[ -n "$snap_dir" ] && {
		check_directory "$snap_dir" || exit 1
	}
	[ -n "$cacheio_dir" ] && {
		check_directory "$cacheio_dir" && rm -rf "$cacheio_dir/templates" || exit 1
	}

	if [ -n "$CLOUD_ADDR" ]; then 
		check_time UNIQB_BRANCH_USER_DATA_SYNC_TIME $UNIQB_BRANCH_USER_DATA_SYNC_TIME || exit 1
	fi

	# settings-based paths
	get_mc_user_home mc_home_
	settings_branch="$mc_home_/.ksvd-local/settings.branch"
	settings_cluster="$mc_home_/.ksvd-local/settings.cluster"
}

ksvd_restart()
{
	system_file_setup

	[ -n "$skip_restart" ] && {
		warn "skipping KSVD restart"
		return
	}
	if [ "$confirm_before" = "RESTART" ] ; then
		cat <<EOT
$ansi_on
Press ENTER to restart $PRODPKGNAME.
Press Ctrl-C to quit without restarting.
$ansi_off
EOT
		# read from tty so that it works when installing the KSVD package
		read x < /dev/tty
	fi

	$BINPATH/rc.ksvd restart "$postinst_arg"
	echo
	echo
}

create_netcfg() {
	if [ "$UNIQB_SERVER_ROLE" == "CM_Only" -o "$UNIQB_SERVER_ROLE" == "CM_VDI" -o "$UNIQB_SERVER_ROLE" == "CM_VDI_GPU" ]; then
		get_mc_user_home mc_home_
		netcfg="$mc_home_/.ksvd/netcfg.csv"
		if [ ! -f $netcfg ]; then
			cat > $netcfg <<EOF
#Network Configuration File
#This file should be written according to the following format
#user,image name,ip,netmask,gateway,hostname,,,
#mcadmin1,win7-32,192.168.130.10,255.255.255.0,192.168.130.1,win7,,,
EOF
		fi
		chown -R $UNIQB_MC_USER:$UNIQB_MC_USER $netcfg
	fi
}

configuration_finalize()
{
	if [ "$confirm_before" = "SAVE" ] ; then
		cat <<EOT
$ansi_on
Press ENTER to save changes and restart KSVD,
or press Ctrl-C to quit now.
$ansi_off
EOT
		# read from tty so that it works when installing the KSVD package
		read x < /dev/tty
	fi

	generate_settings_files # Writes temporary files
	finalize_settings_files
	create_netcfg
	ksvd_restart
	rm -f /tmp/vc.$pid.*
}

# --------------------- main starts here ------------------------------
	[ -n "$UNIQB_VERBOSE_SCRIPTS" ] && set -x
	init_colors

	# if no command line arguments were given, look for them in
	# the environment variable
	[ $# = 0 -a -n "$KSVD_CONFIG_CMDLINE" ] && set -- $KSVD_CONFIG_CMDLINE

	run_mode="restart-only"
	do_answer_file=
	do_local_only=
	skip_restart=
	postinst_arg=
	prog=$0
	pid=$$

	confirm_before="RESTART"

	while [ $# -gt 0 ]; do
		case "$1" in 
		--internal)
			shift;
			$1 $2 $3 $4 $5
			exit $?
			;;
		-i*) run_mode="interview";;
		-m*) run_mode="menu";;
		-u*) run_mode="unattended";;
		-P)  postinst_arg="postinstall";;
		-f*) 	do_answer_file="$2"
			shift;
			[ ! -r "$do_answer_file" ] && 
				fatal "Cannot read $do_answer_file"
			;;
		-v)  set -x; verbosity="-v"; export UNIQB_VERBOSE_SCRIPTS=1;;
		-l)  do_local_only=1;;
		-n*) skip_restart=1;;
		-h*) usage; exit 0;;
		*)   usage; fatal "unknown option $1";;
		esac
		shift
	done

	me=`id -u`
	[ $me != "0" ] && fatal "ksvd-config must be run as root"

	config_init

	load_settings_and_defaults 

	if [ "$run_mode" = "upgrade-without-mc-home" ]; then
		warn "performing an upgrade without home directory of $UNIQB_MC_USER"
		system_file_setup
		exit 0
	fi

	# if launched without any arguments, and there is no existing
	# configuration, it is okay to create one now
	[ -n "$is_fresh_install" -a "$run_mode" = "restart-only" ] && run_mode="unattended"
	if [ "$run_mode" = "restart-only" ]; then 
		confirm_before=
		[ -n "$do_answer_file" ] && 
			warn "answer file is ignored in restart-only mode"
		ksvd_restart
		exit 0
	fi

	if [ -n "$do_answer_file" ] ; then
		configure_from_answer_file
	fi

	if [ "$run_mode" = "menu" ]; then
		confirm_before="RESTART"
		configuration_menu
		rm -f /tmp/vc.$pid.*
		exit 0
	fi

	if [ "$run_mode" = "interview" ]; then
		confirm_before="SAVE"
		configure_interview
		view_configuration
		configuration_finalize
		exit 0
	fi
 
	if [ "$run_mode" = "unattended" ]; then 
		confirm_before=
		view_configuration
		configuration_finalize
		exit 0
	fi

	usage
	exit 1




