#!/bin/bash

$cloud_uuid
$cloud_name
$cloud_passwd
$listen_port
$os_issue
$overlay
$cloud_host
$proxy_ip

root_path=/usr/local/yunsuo_agent
global_c=60
program_name=$0
options_count=$#

function success()
{
	echo -e "\033[${global_c}G[\033[32m OK \033[0m]"
}

function fail()
{
	echo -e "\033[${global_c}G[\033[31m FAILED \033[0m]"
}

function notfound()
{
	echo -e "\033[${global_c}G[\033[33m NOT FOUND \033[0m]"
}

function warning()
{
	echo -e "\033[${global_c}G[\033[33m WARNING \033[0m]"
}

function welcome_info()
{
	echo "Welcome to install YUNSUO."
	echo "If you encounter any problems during installation, you can use 'ctrl-c' to cancel."
	echo ""
}

# 卸载残留
function clear_residue()
{
	if [ -x ${root_path}/uninstall ];then
		${root_path}/uninstall 2&> /dev/null <<EOF
		y
EOF
	else
		rm -rf ${root_path}
	fi
}

# 信号处理
function register_signal()
{
	trap "clear_residue && echo && echo 'Cancel install successed. Bye' && exit" INT
}

# 帮助
function helper()
{
	echo "Usage: "
	echo "  $program_name -u cloud_name -p cloud_passwd -l listen_port -U cloud_uuid -o os_issue -c cloud_host -f -P proxy_server_ip"
	echo "Options:"
	echo "  -u: Cloud center username"
	echo "  -p: Cloud center password"
	echo "  -U: Cloud center UUID"
	echo "  -l: Agent's listen port. default is 5555"
	echo "  -o: Operation system type. surport centos, redhat, ubuntu, suse, debian"
	echo "  -f: Overlay installation"
	echo "  -c: Cloud Center Host"
	echo "  -P: Set proxy server ip"
}

# 参数解析 
function parse_options()
{
	if [ $options_count -gt 0 ];then
		while getopts "u:p:U:l:o:c:P:fh" opt
		do
			case $opt in
				u)	cloud_name=$OPTARG ;;
				p)	cloud_passwd=$OPTARG ;;
				U)	cloud_uuid=$OPTARG ;;
				l)	listen_port=$OPTARG ;;
				o)	os_issue=$OPTARG ;;
				f)	overlay="y" ;;
				c)	cloud_host=$OPTARG ;;
				P)	proxy_ip=$OPTARG ;;
				h)	helper
					exit ;;
			esac
		done
	fi
}

# 检查安装包是否与系统版本匹配
function check_arch()
{
	if [ `uname -m` != "x86_64" ];then
		return 1
	else
		return 0
	fi
}

# 检查系统版本
function check_os_issue()
{
	if [ -z "$os_issue" ];then
		if [ ! -z `find /usr/bin -name apt-get` ];then
			k_version=`uname -r`
			if [[ $k_version =~ "generic" ]] || [[ $k_version =~ "server" ]];then
				os_issue="ubuntu"
			else
				os_issue="debian"
			fi
		elif [ ! -z `find /usr/bin -name yum` ];then
			os_issue="centos"
		elif [ ! -z `which YaST 2> /dev/null` ] || [ ! -z `which yast 2> /dev/null` ];then
			os_issue="suse"
		else
			return 1
		fi
	else
		if [ "$os_issue" != "centos" ] && [ "$os_issue" != "ubuntu" ] && [ "$os_issue" != "suse" ] && [ "$os_issue" != "redhat" ] && [ "$os_issue" != "debian" ];then
			return 1
		elif [ "$os_issue" = "redhat" ];then
			os_issue="centos"
		fi
	fi
	
	return 0
}

# 检查是否已经安装了产品
function check_installed()
{
	if [ -d $root_path ];then
		if [ -z $overlay ];then
			# 安装时未指定覆盖安装, 这里做提示, 是否覆盖安装
			echo
			echo -n "Overlay installation?(Y/N): "
			read overlay
		fi
		
		if [ "$overlay" != "y" ] && [ "$overlay" != "Y" ];then
			# 不覆盖安装
			return 1
		else
			# 覆盖安装(这里做卸载操作)
			clear_residue
		fi
	fi
	
	return 0
}

# 检查驱动是否已经安装
function check_dirvers()
{
	which lsmod 2&> /dev/null
	if [ $? -ne 0 ];then
		# 系统可能不存在lsmod命令，因此不做驱动检查，直接安装
		return 0
	fi

	driver_not_uninstall=`lsmod | grep resguard_linux | grep -v grep | head -1 | awk '{print $1}'`
	if [ ! -z "$driver_not_uninstall" ];then
		return 1
	fi
	
	return 0
}

# 检查当前系统环境是否允许安装
function check_installation_environment()
{
	echo -n "checking installation environment:"
	
	while true
	do
		# 检查包是否匹配
		check_arch
		if [ $? -ne 0 ];then
			error_info="Installation package and system version mismatch, please confirm package"
			break
		fi

		# 检查system issue
		check_os_issue
		if [ $? -ne 0 ];then
			error_info="Installer could not detect system issue, please specify system issue to install."
			break
		fi
		
		# 检查是否已经安装过
		check_installed
		if [ $? -ne 0 ];then
			error_info="Has been installed."
			break
		fi
		
		# 检查驱动
		check_dirvers
		if [ $? -ne 0 ];then
			error_info="Drivers not uninstall, Please Reboot Your System and Install."
			break
		fi

		success
		return 
	done
	
	fail
	echo ""
	echo "Error: $error_info"
	exit
}

function prepare_before_install()
{
	execute_path=$0
	execute_path=`echo ${execute_path%%install}`
	if [ -z $execute_path ];then
		execute_path=.
	fi

	# 解压
	echo -n "decompression package:"
	mkdir ${root_path} 2> /dev/null
	tar zxf ${execute_path}/src_lib.tar.gz -C ${root_path} 2> /dev/null

	# 创建及修改必要文件
	test ! -d /var/log && mkdir /var/log
	
	# 创建软链
	test ! -d /usr/local/lib && mkdir /usr/local/lib
	test -d /usr/local/lib/jlib64 && rm -rf /usr/local/lib/jlib64
	ln -s ${root_path}/libs /usr/local/lib/jlib64
	# 旧的jlibs软链还需要存在, 为了兼容旧的nginx, 以防找不到库
	# 等nginx更新后, 再把这个删掉
	ln -s ${root_path}/libs /usr/local/lib/jlibs
	
	# 生成路径控制文件
	echo "${root_path}" > /var/log/version_control
	echo "server_name: yunsuo_agent_service" > ${root_path}/command_control
	echo "guard_name: yunsuo_agent_guard" >> ${root_path}/command_control
	echo "script_server: yunsuo" >> ${root_path}/command_control
	echo "script_guard: yunsuo_guard" >> ${root_path}/command_control

	# 需要用到的可执行文件+x
	chmod +x ${root_path}/change_port
	chmod +x ${root_path}/agent_smart_tool.sh
	chmod +x ${root_path}/register_cloud_center
	chmod +x ${root_path}/uninstall_driver
	chmod +x ${root_path}/setup_configure
	chmod +x ${root_path}/Update
	
	test -f ${execute_path}/custom_ac && cp ${execute_path}/custom_ac ${root_path}/config/other

	# 修改cloud center host
	if [ ! -z ${cloud_host} ];then
		sed -i "s/update.yunsuo.com.cn/${cloud_host}/g" ${root_path}/config.xml
		sed -i "s/apiv3.yunsuo.com.cn/${cloud_host}/g" ${root_path}/config.xml
		sed -i "s/scan.yunsuo.com.cn/${cloud_host}:7901/g" ${root_path}/config.xml
		sed -i "s/monitor.yunsuo.com.cn/${cloud_host}/g" ${root_path}/config.xml
		sed -i "s/1:tcp:127.0.0.1:443/1:tcp:127.0.0.1:555/g" ${root_path}/config.xml
	fi
	
	success
}

# 配置代理服务器IP
function configure_proxy()
{
	if [ ! -z "$proxy_ip" ];then
		${root_path}/change_port -p $proxy_ip
	fi
}

# 绑定云中心
function bind_cloud_account()
{
	if [ ! -z $cloud_uuid ];then
		${root_path}/register_cloud_center bind $cloud_uuid
	elif [ ! -z $cloud_name ] && [ ! -z $cloud_passwd ];then
		${root_path}/register_cloud_center bind $cloud_name $cloud_passwd
	else
		${root_path}/register_cloud_center bind
	fi
}

# 修改监听端口
function update_listen_port()
{
	if [ ! -z "$listen_port" ];then
		${root_path}/agent_smart_tool.sh -l $listen_port
	fi
}

# 配置云锁运行环境
function execute_configure_script()
{
	cd ${root_path}
	
	# 生成configure_file文件, 该文件内容为具体的配置信息
	test -f configure_file && rm -rf configure_file ; echo "1:normal:x64:$root_path:$os_issue" > configure_file
	
	export JHSE_SAFE_PATH=$root_path
	export LANG="C"

	# 下载驱动
	./Update kernel $os_issue
	
	# 配置云锁
	./setup_configure -c setup.xml -l runlog/setup.log -e "ALL" -t "ALL" -s safe -m cmdline 2>/dev/null

	echo ""
	echo "Install Yunsuo Success."
}

# 设置当前bash的umask值为022, 且保存原始的umask值
function reset_umask()
{
	old_umask=`umask`
	
	umask 022
}

# 还原原始umask
function restore_umask()
{
	umask $old_umask
}

# 安装selinux规则模块
function install_selinux_policy()
{
	echo -n "Install Selinux Policy Module:"

	cur_path=`pwd`
	cd ${root_path}
	
	install_res=0
	
	while true
	do
		if [ ! -f /usr/sbin/semodule ];then 
			break 
		fi
		
		if [ `getenforce` != "Enforcing" ];then
			break
		fi
		
		# 判断policy版本
		policy_version=`sestatus | grep version | awk -F':' '{print $2}' | xargs echo`
		if [ $policy_version -ge 21 ] && [ $policy_version -lt 24 ];then
			cp agent_selinux_policy.21 agent_selinux_policy.te
		elif [ $policy_version -ge 24 ];then
			cp agent_selinux_policy.24 agent_selinux_policy.te
		else
			break
		fi
		
		# 编译selinux规则模块
		checkmodule -M -m -o agent_selinux_policy.mod agent_selinux_policy.te > /dev/null
		if [ $? -ne 0 ];then
			install_res=1
			break
		fi
		
		# 生成selinux规则模块
		semodule_package -o agent_selinux_policy.pp -m agent_selinux_policy.mod
		if [ $? -ne 0 ];then
			install_res=1
			break
		fi
		
		# 安装selinux规则模块
		semodule -i agent_selinux_policy.pp
		if [ $? -ne 0 ];then
			install_res=1
			break
		fi
		
		# 设置lib库的标签
		chcon -R -u system_u -t lib_t libs pam
		
		# 清理临时文件
		rm -rf agent_selinux_policy.te agent_selinux_policy.mod agent_selinux_policy.pp
		
		break
	done 
	
	# 恢复工作目录
	cd ${cur_path}
	
	if [ $install_res -eq 0 ];then
		success
	else
		fail
	fi
}

######################################################
parse_options $*
welcome_info
register_signal
reset_umask
check_installation_environment
prepare_before_install $0
install_selinux_policy
configure_proxy
bind_cloud_account
update_listen_port
execute_configure_script
restore_umask
