#!/bin/bash
local_dir="/opt/packer"
sys_log="/var/log/install.log"
archerosrepo="http://178.104.163.78/cmigrate/"
ver="2.4.0"

INSTALLSUCCEES="0"
INSTALLFAILED="1"
REPOACCESSABLE="2"
REPONOTACCESSABLE="3"
NOSUITABLEPACKAGE="4"

log () {
	date=`date +"%Y-%m-%d %H:%M:%S"`
	para=$1
	echo "[$date] $1" >> $sys_log
}

is_repo_accessable () {
	urlstatus=`curl -s -m 5 -IL "$1" | grep 200`
	if [ "$urlstatus" == "" ];then
		echo "$REPONOTACCESSABLE"
	else
		echo "$REPOACCESSABLE"
	fi
}

get_os_version_full () {
	if [ -f "/etc/redhat-release" ];then
		ret=`cat /etc/redhat-release`
		if [[ "$ret" =~ "Linux" ]];then
			ret=`cat /etc/redhat-release | cut -d " " -f 4`
			echo $ret
		else
			ret=`cat /etc/redhat-release | cut -d " " -f 3`
			echo $ret
		fi
	else
		ret=`cat /etc/issue | cut -d " " -f 2`
		echo $ret
	fi
}

get_os_version_part () {
	if [ -f "/etc/redhat-release" ];then
		ret=`cat /etc/redhat-release`
		if [[ "$ret" =~ "Linux" ]];then
			ret1=`cat /etc/redhat-release | cut -d " " -f 4 | cut -f "." -f 1`
			ret2=`cat /etc/redhat-release | cut -d " " -f 4 | cut -f "." -f 2`
			echo $ret1.$ret2
		else
			ret1=`cat /etc/redhat-release | cut -d " " -f 3 | cut -f "." -f 1`
			ret2=`cat /etc/redhat-release | cut -d " " -f 3 | cut -f "." -f 2`
			echo $ret1.$ret2
		fi
	else
		ret1=`cat /etc/issue | cut -d " " -f 2 | cut -f "." -f 1`
		ret2=`cat /etc/issue | cut -d " " -f 2 | cut -f "." -f 2`
		echo $ret1.$ret2
	fi
}

localinstall_kerneldevel () {
	kernelver=`uname -r`
	kerneldev="kernel-devel-"$kernelver".rpm"
	ret=`yum localinstall -y $local_dir/$kerneldev >> $sys_log 2>&1`
	ret=`rpm -qa | grep "kernel-devel-"$kernelver""`
	if [ -z "$ret" ];then
		log "local install kernel devel $local_dir/$kerneldev failed"
		echo "$INSTALLFAILED"
		return
	fi

	echo "$INSTALLSUCCESS"
}

archerosinstall_kerneldevel () {
	ret=`is_repo_accessable "$archerosrepo"`
	if [ "$ret" = "$REPONOTACCESSABLE" ];then
		log "archerosrepo install kernel devel failed, archerosrepo is not accessable"
		echo "$REPONOTACCESSABLE" 
		return
	fi

	kernelver=`uname -r`
	kerneldev="kernel-devel-"$kernelver".rpm"
	osversion=`get_os_version_full`
	ret=`curl $archerosrepo/kernel-devel/rpms/$kerneldev -f -o $local_dir/$kerneldev >> $sys_log 2>&1`
	sleep 1
	if [ ! -f "$local_dir/$kerneldev" ];then
		log "archeros repo install kernel devel $kerneldev failed, errmsg($ret)"
		echo "$NOSUITABLEPACKAGE"
		return
	fi

	ret=`yum localinstall -y $local_dir/$kerneldev >> $sys_log 2>&1`
	ret=`rpm -qa | grep "kernel-devel-"$kernelver""`
	if [ -z "$ret" ];then
		log "archerosrepo install kernel devel $local_dir/$kerneldev failed"
		echo "$INSTALLFAILED"
		return
	fi

	echo "$INSTALLSUCCESS"
}

install_kerneldevel () {
	ret=`localinstall_kerneldevel`
	if [ "$ret" = "$INSTALLSUCESS" ];then
		log "local install kernel devel succeeded"
		echo "$ret"
		return
	fi

	log "local install kernel devel failed, keep trying from archeros repo"
	ret=`archerosinstall_kerneldevel`
	if [ "$ret" = "$INSTALLSUCCESS" ];then
		log "archeros repo install kernel devel succeeded"
		echo "$ret"
		return
	fi

	log "archeros repo install kernel devel failed"
	echo "$ret"
}

localinstall_datto () {
	uname=`uname -a`
	if [[ "$uname" =~ "x86_64" ]];then
		if [ -f "/usr/bin/yum" ];then
			osVersion=`get_os_version_full`
			if [[ $osVersion == "6."* ]]; then
				ret=`yum -y install https://archives.fedoraproject.org/pub/archive/epel/6/x86_64/epel-release-6-8.noarch.rpm >> $sys_log 2>&1`
			fi
			ret=`yum install dkms-dattobd dattobd-utils -y >> $sys_log 2>&1 && modprobe dattobd >> $sys_log 2>&1`
			ret=`lsmod | grep dattobd`
			if [ -z "$ret" ];then
				log "local install datto failed, errmsg(dattobd not loaded!)"
				echo "$INSTALLFAILED"
				return
			fi
			echo "$INSTALLSUCCESS"
			return
		fi

		if [ -f "/usr/bin/apt" ];then
			ret=`apt-get install dattobd-dkms dattobd-utils -y --allow-unauthenticated >> $sys_log 2>&1 && modprobe dattobd >> $sys_log 2>&1`
			ret=`lsmod | grep dattobd`
			if [ -z "$ret" ];then
				log "local install datto failed, errmsg(dattobd not loaded!)"
				echo "$INSTALLFAILED"
				return
			fi
			echo "$INSTALLSUCCESS"
			return
		fi

		log "internet install datto failed, neither yum nor apt-get found"
		echo "$INSTALLFAILED"
		return
	else
		kernelver=`uname -r`
		if [ -f "$local_dir/dattobd-for-$kernelver.tgz" ];then
			tar -pzxvf $local_dir/dattobd-for-$kernelver.tgz -C / > /dev/null
			depmod -a
			modprobe dattobd
			ret=`lsmod | grep dattobd`
			if [ -z "$ret" ];then
				log "local install datto failed, errmsg(dattobd not loaded!)"
				echo "$INSTALLFAILED"
				return
			fi
			echo "INSTALLSUCCESS"
			return
		else
			log "local install dattobd-for-$kernelver failed, errmsg(package not exits!)"
			echo "$INSTALLFAILED"
			return
		fi
	fi
}

#only for aarch64
archerosinstall_datto () {
	uname=`uname -a`
	if [[ "$uname" =~ "x86_64" ]];then
		log "archeros repo install dattobd failed, errmsg(archeros repo install datto only for aarch64!)"
		echo "$INSTALLFAILED"
		return
	fi
	ret=`is_repo_accessable "$archerosrepo"`
	if [ "$ret" = "$REPONOTACCESSABLE" ];then
		log "archerosrepo install datto failed, archerosrepo is not accessable"
		echo "$REPONOTACCESSABLE"
		return
	fi

	kernelver=`uname -r`
	ret=`curl $archerosrepo/datto/aarch64/dattobd-for-$kernelver.tgz -f -o $local_dir/dattobd-for-$kernelver.tgz >> $sys_log 2>&1`
	sleep 1
	if [ ! -f "$local_dir/dattobd-for-$kernelver.tgz" ];then
		log "archeros repo install packer dattobd-for-$kernelver.tgz failed, errmsg($ret)"
		echo "$NOSUITABLEPACKAGE"
		return
	fi
	tar -pzxvf $local_dir/dattobd-for-$kernelver.tgz -C / > /dev/null
	depmod -a
	modprobe dattobd
	ret=`lsmod | grep dattobd`
	if [ -z "$ret" ];then
		log "archeros repo install datto failed, errmsg(dattobd not loaded!)"
		echo "$INSTALLFAILED"
		return
	fi

	echo "$INSTALLSUCCESS"
}

internetinstall_datto () {
	if [ -f "/usr/bin/yum" ];then
		osVersion=`get_os_version_full`
		if [[ $osVersion == "6."* ]]; then
			ret=`yum -y install https://archives.fedoraproject.org/pub/archive/epel/6/x86_64/epel-release-6-8.noarch.rpm >> $sys_log 2>&1`
		fi
		ret=`yum install https://cpkg.datto.com/datto-rpm/repoconfig/datto-el-rpm-release-$(rpm -E %rhel)-latest.noarch.rpm -y >> $sys_log 2>&1`
		ret=`rpm -qa | grep datto-el-rpm-release`
		if [ -z "$ret" ];then
			log "internet install datto failed, datto-el-rpm-release"
			echo "$INSTALLFAILED"
			return
		fi
		sed -i "s/=https/=http/" /etc/yum.repos.d/epel.repo 2>&1 > /dev/null
		ret=`yum install dkms-dattobd dattobd-utils -y >> $sys_log 2>&1 && modprobe dattobd >> $sys_log 2>&1`
		ret=`lsmod | grep dattobd`
		if [ -z "$ret" ];then
			log "internet install datto failed, errmsg(dattobd not loaded!)"
			echo "$INSTALLFAILED"
			return
		fi
		echo "$INSTALLSUCCESS"
		return
	fi
	
	if [ -f "/usr/bin/apt" ];then
		#maybe for ubuntu16
		ret=`apt-get update >> $sys_log 2>&1 && apt-get install gnupg-curl -y >> $sys_log 2>&1`
		ret=`dpkg -l 2>&1 | grep gnupg-curl 2>&1`
		if [[ ! "$ret" =~ "gnupg-curl" ]];then
			log "internet install gnupg-curl failed, maybe due to install datto failed"
			#echo "$INSTALLFAILED"
			#return
		fi

		ret=`apt-key adv --fetch-keys https://cpkg.datto.com/DATTO-PKGS-GPG-KEY >> $sys_log 2>&1`
		ret=`apt-key list | grep datto`
		if [ -z "$ret" ];then
			log "internet install datto failed, fetch key"
			echo "$INSTALLFAILED"
			return
		fi

		ret=`echo "deb [arch=amd64] https://cpkg.datto.com/datto-deb/public/$(lsb_release -sc) $(lsb_release -sc) main" | sudo tee /etc/apt/sources.list.d/datto-linux-agent.list >> $sys_log 2>&1`

		ret=`apt-get update >> $sys_log 2>&1`
		
		ret=`apt-get install dattobd-dkms dattobd-utils -y --allow-unauthenticated >> $sys_log 2>&1 && modprobe dattobd >> $sys_log 2>&`
		ret=`lsmod | grep dattobd`
		if [ -z "$ret" ];then
			log "internet install datto failed, errmsg(dattobd not loaded!)"
			echo "$INSTALLFAILED"
			return
		fi
		echo "$INSTALLSUCCESS"
		return
	fi

	log "internet install datto failed, neither yum nor apt-get found"
	echo "$INSTALLFAILED"
}

install_datto () {
	ret=`localinstall_datto`
	if [ "$ret" = "$INSTALLSUCCESS" ];then
		log "local install datto succeeded"
		echo "$ret"
		return
	fi

	log "local install datto failed, keep trying from archeros repo"
	ret=`archerosinstall_datto`
	if [ "$ret" = "$INSTALLSUCCESS" ];then
		log " archeros repo install datto succeeded"
		echo "$ret"
		return
	fi

	log "archeros repo install datto failed, keep trying from internet"
	ret=`internetinstall_datto`
	if [ "$ret" = "$INSTALLSUCCESS" ];then
		log "internet install datto succeeded"
		echo "$ret"
		return
	fi

	echo "$ret"
}

update_datto () {
	uname=`uname -a`
	if [[ "$uname" =~ "x86_64" ]];then
		log "update datto for x86_64"
	else
		log "update datto only works for x86_64"
		echo "$INSTALLSUCCESS"
		return
	fi

	cd /usr/src
	dattobd_dir=""
	for f in `ls`
	do
		if [[ "$f" =~ "dattobd" ]]; then
			dattobd_dir="$f"
			break
		fi
	done
	if [ -z "$dattobd_dir" ]; then
		log "can not find dattobd dir in /usr/src"
		echo "$INSTALLFAILED"
		return
	fi

	version=`echo $dattobd_dir | cut -d "-" -f 2`
	log "dattobd version is $version dir:$dattobd_dir"
	cd "$dattobd_dir"

	if [ ! -f "./dattobd.c" ]; then
		log "dattobd.c is not exist!"
	else
		ret=`cat dattobd.c | grep "This Version Fixed Kernel Panic in cow_read_mapping"`
		if [ ! -z "$ret" ]; then
			log "patch already installed!"
		else
			url="$archerosrepo/datto/patch/$version/0001-fix-kernel-panic-in-cow_read_mapping.patch"
			if [ -f "0001-fix-kernel-panic-in-cow_read_mapping.patch" ]; then
				rm -rf 0001-fix-kernel-panic-in-cow_read_mapping.patch
			fi
			if [ -f "$local_dir/$version/0001-fix-kernel-panic-in-cow_read_mapping.patch" ];then
				cp $local_dir/$version/0001-fix-kernel-panic-in-cow_read_mapping.patch ./
			else
				wget $url -O ./0001-fix-kernel-panic-in-cow_read_mapping.patch >> $sys_log 2>&1
				if [ ! -f "0001-fix-kernel-panic-in-cow_read_mapping.patch" ]; then
					log "download patch failed"
					echo "$INSTALLFAILED"
					return
				fi
			fi

			patch < 0001-fix-kernel-panic-in-cow_read_mapping.patch >> $sys_log 2>&1
			if [ $? -ne 0 ]; then
				log "patch failed"
				echo "$INSTALLFAILED"
				return
			fi
		fi
	fi

	modprobe -r dattobd >> $sys_log 2>&1
	ret=`lsmod | grep dattobd`
	if [ ! -z "$ret" ]; then
		log "modprobe -r failed"
		echo "$INSTALLFAILED"
		return
	fi

	dkms remove -m dattobd -v $version --all >> $sys_log 2>&1
	ret=`dkms status | grep "dattobd"`
	if [ ! -z "$ret" ]; then
		log "remove dattobd from dkms failed($ret)"
	        echo "$INSTALLFAILED"
		return
	fi

	/usr/lib/dkms/common.postinst dattobd $version >> $sys_log 2>&1
	if [ $? -ne 0 ]; then
		log "dkms install failed"
		echo "$INSTALLFAILED"
		return
	fi

	modprobe dattobd >> $sys_log 2>&1
	if [ $? -ne 0 ]; then
		log "modprobe failed"
		echo "$INSTALLFAILED"
		return
	fi

	echo "$INSTALLSUCCESS"
}

install_dmidecode() {
	if [ -f "/usr/bin/yum" ];then
		ret=`yum install dmidecode -y >> $sys_log 2>&1`
		if [ ! -f "/usr/sbin/dmidecode" ]; then
			log "install dmidecode failed"
			echo "$INSTALLFAILED"
		fi
		echo "$INSTALLSUCCESS"
		return
	fi
	
	if [ -f "/usr/bin/apt-get" ];then
		ret=`apt-get install dmidecode -y >> $sys_log 2>&1`
		if [ ! -f "/usr/sbin/dmidecode" ]; then
			log "install dmidecode failed"
			echo "$INSTALLFAILED"
		fi
		echo "$INSTALLSUCCESS"
		return
	fi
}

install_partprobe() {
	if [ -f "/usr/bin/yum" ];then
		ret=`yum install parted -y >> $sys_log 2>&1`
	fi
	
	if [ -f "/usr/bin/apt-get" ];then
		ret=`apt-get install parted -y >> $sys_log 2>&1`
	fi

	if [ ! -f "/usr/sbin/partprobe" -a ! -f "/sbin/partprobe" ]; then
			log "install partprobe failed"
			echo "$INSTALLFAILED"
		fi
		echo "$INSTALLSUCCESS"
		return

}

install_patch() {
	if [ -f "/usr/bin/yum" ];then
		ret=`yum install patch -y >> $sys_log 2>&1`
		if [ ! -f "/usr/bin/patch" ]; then
			log "install patch failed"
			echo "$INSTALLFAILED"
		fi
		echo "$INSTALLSUCCESS"
		return
	fi

	if [ -f "/usr/bin/apt-get" ];then
		ret=`apt-get install patch -y >> $sys_log 2>&1`
		if [ ! -f "/usr/bin/patch" ]; then
			log "install patch failed"
			echo "$INSTALLFAILED"
		fi
		echo "$INSTALLSUCCESS"
		return
	fi
}

localinstall_packer () {
	uname=`uname -a`
	if [[ "$uname" =~ "x86_64" ]];then
		if [[ "$uname" =~ "el6" ]]; then
			if [ -f "$local_dir/packer-linux-centos6-$1.tgz" ];then
				tar -pzxvf $local_dir/packer-linux-centos6-$1.tgz -C / > /dev/null
				echo "$INSTALLSUCCESS"
			else
				log "local install packer packer-linux-centos6-$1.tgz failed, errmsg(package not exits!)"
				echo "$INSTALLFAILED"
			fi
		else
			if [ -f "$local_dir/packer-linux-generic-$1.tgz" ];then
				tar -pzxvf $local_dir/packer-linux-generic-$1.tgz -C / > /dev/null
				echo "$INSTALLSUCCESS"
			else
				log "local install packer packer-linux-generic-$1.tgz failed, errmsg(package not exits!)"
				echo "$INSTALLFAILED"
			fi
		fi
	else
		if [ -f "$local_dir/packer-linux-aarch64-$1.tgz" ];then
			tar -pzxvf $local_dir/packer-linux-aarch64-$1.tgz -C / > /dev/null
			echo "INSTALLSUCCESS"
		else
			log "local install packer packer-linux-aarch64-$1.tgz failed, errmsg(package not exits!)"
			echo "$INSTALLFAILED"
		fi
	fi
}

archerosinstall_packer () {
	ret=`is_repo_accessable "$archerosrepo"`
	if [ "$ret" = "$REPONOTACCESSABLE" ];then
		log "archerosrepo install packer failed, archerosrepo is not accessable"
		echo "$REPONOTACCESSABLE" 
		return
	fi

	uname=`uname -a`
	if [[ "$uname" =~ "x86_64" ]];then
		if [[ "$uname" =~ "el6" ]]; then
			ret=`curl $archerosrepo/v$1/packer-linux-centos6-$1.tgz -f -o $local_dir/packer-linux-centos6-$1.tgz >> $sys_log 2>&1`
			sleep 1
			if [ ! -f "$local_dir/packer-linux-centos6-$1.tgz" ];then
				log "archeros repo install packer packer-linux-centos6-$1.tgz failed, errmsg($ret)"
				echo "$NOSUITABLEPACKAGE"
				return
			fi
			tar -pzxvf $local_dir/packer-linux-centos6-$1.tgz -C / > /dev/null
		else
			ret=`curl $archerosrepo/v$1/packer-linux-generic-$1.tgz -f -o $local_dir/packer-linux-generic-$1.tgz >> $sys_log 2>&1`
			sleep 1
			if [ ! -f "$local_dir/packer-linux-generic-$1.tgz" ];then
				log "archeros repo install packer packer-linux-generic-$1.tgz failed, errmsg($ret)"
				echo "$NOSUITABLEPACKAGE"
				return
			fi
			tar -pzxvf $local_dir/packer-linux-generic-$1.tgz -C / > /dev/null
		fi
	else
		ret=`curl $archerosrepo/v$1/packer-linux-aarch64-$1.tgz -f -o $local_dir/packer-linux-aarch64-$1.tgz >> $sys_log 2>&1`
		sleep 1
		if [ ! -f "$local_dir/packer-linux-aarch64-$1.tgz" ];then
			log "archeros repo install packer packer-linux-aarch64-$1.tgz failed, errmsg($ret)"
			echo "$NOSUITABLEPACKAGE"
			return
		fi
		tar -pzxvf $local_dir/packer-linux-aarch64-$1.tgz -C / > /dev/null
	fi

	echo "$INSTALLSUCCESS"
}

install_packer () {
	ret=`localinstall_packer $1`
	if [ "$ret" = "$INSTALLSUCCESS" ];then
		log "local install packer succeeded"
		packer_service restart > /dev/null
		echo "$ret"
		return
	fi

	log "local install packer failed, keep trying from archeros repo"
	ret=`archerosinstall_packer $1`
	if [ "$ret" = "$INSTALLSUCCESS" ];then
		log "archeros repo install packer succeeded"
		packer_service restart > /dev/null
		echo "$ret"
		return
	fi

	log "archeros repo install packer failed"
	echo "$ret"
}

install() {
	echo "Install patch"
	ret=`install_patch`
	if [ "$ret" = "$INSTALLFAILED" ];then
		echo "Install terminated, install patch failed, please check log for more details"
		exit
	elif [ "$ret" = "$INSTALLSUCCESS" ];then
		echo "Install patch success"
	else
		echo "Install patch failed due to unknown reasons, please check log for more details"
		exit
	fi

	if [ -f "/usr/bin/yum" ];then
		echo "Install kernel devel"
		ret=`install_kerneldevel`
		if [ "$ret" = "$INSTALLFAILED" ];then
			echo "Install terminated, install kernel devel failed, please check log for more details"
			exit
		elif [ "$ret" = "$REPONOTACCESSABLE" ];then
			echo "Unable to connect to "$archerosrepo". please check your internet connection and try again."
			exit
		elif [ "$ret" = "$NOSUITABLEPACKAGE" ];then
			echo "Unable to get the kernel-devel installation package for the kernel version, please contact the technician for processing."
			exit
		elif [ "$ret" = "$INSTALLSUCCESS" ];then
			echo "Install kernel devel success"
		else
			echo "Install kernel devel failed due to unknown reasons, please check log for more details"
			exit
		fi
	fi

	echo "Install datto"
	ret=`install_datto`
	if [ "$ret" = "$INSTALLFAILED" ];then
		echo "Install terminated, install datto failed, please check log for more details"
		exit
	elif [ "$ret" = "$REPONOTACCESSABLE" ];then
		echo "Unable to connect to "$archerosrepo". please check your internet connection and try again."
		exit
	elif [ "$ret" = "$NOSUITABLEPACKAGE" ];then
		echo "Unable to get the datto installation package, please contact the technician for processing."
		exit
	elif [ "$ret" = "$INSTALLSUCCESS" ];then
		echo "Install datto success"
	else
		echo "Install datto failed due to unknown reasons, please check log for more details"
		exit
	fi

	echo "Install dmidecode"
	ret=`install_dmidecode`
	if [ "$ret" = "$INSTALLFAILED" ];then
		echo "Install terminated, install dmidecode failed, please check log for more details"
		exit
	elif [ "$ret" = "$INSTALLSUCCESS" ];then
		echo "Install dmidecode success"
	else
		echo "Install dmidecode failed due to unknown reasons, please check log for more details"
		exit
	fi
	
	#echo "Install partprobe"
	#ret=`install_partprobe`
	#if [ "$ret" = "$INSTALLFAILED" ];then
	#	echo "Install terminated, install partprobe failed, please check log for more details"
	#	exit
	#else
	#	echo "Install partprobe success"
	#fi

	echo "Install packer"
	ret=`install_packer $1`
	if [ "$ret" = "$INSTALLFAILED" ];then
		echo "Install terminated, install packer failed, please check log for more details"
		exit
	elif [ "$ret" = "$REPONOTACCESSABLE" ];then
		echo "Unable to connect to "$archerosrepo". please check your internet connection and try again."
		exit
	elif [ "$ret" = "$NOSUITABLEPACKAGE" ];then
		echo "Unable to get the packer installation package, please contact the technician for processing."
		exit
	elif [ "$ret" = "$INSTALLSUCCESS" ];then
		echo "Install packer success"
	else
		echo "Install packer failed due to unknown reasons, please check log for more details"
	fi

	echo "update datto"
	ret=`update_datto`
	if [ "$ret" = "$INSTALLFAILED" ];then
		echo "Install terminated, update datto failed, please check log for more details"
		exit
	elif [ "$ret" = "$INSTALLSUCCESS" ];then
		echo "Update datto success"
	else
		echo "Update datto failed due to unknown reasons, please check log for more details"
		exit
	fi
}

main () {
	echo "Install start, ver:$ver, more details can be found in $sys_log"
	install $ver
	echo "Successful installation!"
}

if [ ! -d "$local_dir" ];then
	mkdir -p $local_dir
fi

main
