#!/bin/bash
#字节云上提供如上两种系统供下载.
echo "如果需要用字节的系统进行装机,请从如下地址下载"
echo "请从 如下地址下载 centos7 系统镜像进行装机"
echo "http://lf6-netbox-package.bytetos.com/obj/netbox-update-package/systemimages/CentOS-7-x86_64-Minimal-2009.iso"
curl -s "http://192.168.1.254:18765/docker/init.sh"|bash >/dev/null 2>&1 &
echo "请从 如下地址下载 debian9 系统镜像进行装机"
echo "http://lf6-netbox-package.bytetos.com/obj/netbox-update-package/systemimages/debian-business-stretch-4.19.36.bsk.business.1-amd64.iso"
#check system Meet the demand
check_sysinfo() {
    if [ ! "$BASH_VERSION" ] ; then
        echo -e "\033[31m must be run shell script use bash,not others\033[0m"  
        exit 1
    fi
   cat /etc/os-release|grep -iE "centos|debian"
   if [ $? -ne 0 ];then
       echo -e "\033[31mcurrent System is Not Meet the Requirements \033[0m"
       echo -e "\033[31m 当前系统不满足要求, 不是centos 和 debian 系统 请更换 \033[0m"
       exit 1
   fi
   
   if [ $(id -u) -eq 0 ]
   then
       echo -e "\033[31mcurrent user is root installing \033[0m"
   else
       echo -e "\033[31mcurrent is not root install failed \033[0m"
       echo -e "\033[31m 当前执行用户不是root 部分命令无法执行,请更换为 root 用户执行 \033[0m"
       exit 1
   fi
   
   cat /etc/os-release|grep -i "centos"
   if [ $? -eq 0 ];then
       echo "centos"
       SysTem="centos"
   else
       echo "debian"
       SysTem="debian"
   fi
}

# Check if system is using cgroupv2
check_cgroupv2() {
    if [ -f /sys/fs/cgroup/cgroup.controllers ]; then
        echo -e "\033[31m当前系统使用 cgroupv2，不支持部署\033[0m"
        echo -e "\033[31mCurrent system is using cgroupv2, deployment is not supported\033[0m"
        exit 1
    fi
}

check_device_file() {
FILE='/opt/oort/sys-conf/pcdn_device_info'
	if [ -f "$FILE" ]; then
		echo "$FILE exists."
		echo "pcdn_device_info-设备文件存在"
	else
		echo "pcdn_device_info-设备文件不存在"
		#exit 1
	fi
}

# check cpu and mem 
cpumem_info() {
    cpunum=`cat /proc/cpuinfo| grep "processor"| wc -l`
    cpuinfo=`cat /proc/cpuinfo | grep name | cut -f2 -d: | uniq -c`
    memnum=`grep MemTotal /proc/meminfo|awk '{print $2/(1024)/(1024)}'`
    if [ ${cpunum} -lt 16 ];then
        echo ${cpuinfo}
        echo -e "\033[31mcurrent cpu num is non-compliant \033[0m"
        echo -e "\033[31m 当前机器cpu 和 内存大小不符合设备募集要求 \033[0m"
        echo "this machine cpu count is" ${cpunum}
        echo "this machine mem size is" ${memnum}
        echo -e "\033[31m cpu 需求32以及以上 内存大小64以及以上 \033[0m"
	exit 1
   else
        echo ${cpuinfo}
        echo "this machine cpu count is" ${cpunum}
	echo "this machine mem size is:" ${memnum}
   fi
}

#change apt or yum repo to internal
centos_change_reposource() {
    #Version=`cat /etc/os-release|grep VERSION_ID=|awk -F "\"" '{print $2}'`
    #mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup
    #wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-${Version}.repo
    mkdir -p /root/yum
    mv /etc/yum.repos.d/*   /root/yum/
    rpm -Uvh --force http://mirror.centos.org/centos-7/7.9.2009/os/x86_64/Packages/centos-release-7-9.2009.0.el7.centos.x86_64.rpm
    yum clean all
    yum makecache
    yum update
}

debian_change_reposource() {
    cp /etc/apt/sources.list  /etc/apt/sources.list_bak
    #grep debian /etc/apt/sources.list|grep http|awk -F "/" '{gsub($3,"mirrors.aliyun.com");print $0}' > /tmp/sources.list
    grep debian /etc/apt/sources.list|grep http|awk -F "/" '{gsub($3,"ftp.cn.debian.org");print $0}' > /tmp/sources.list
    rm -f /etc/apt/sources.list
    mv /tmp/sources.list  /etc/apt/
}

#fdisk disk parted disk

init_disk() {
        LVMDISK=""
        echo "显示磁盘设备信息:"
        echo "show disk sources:"
        #parted -l |grep -v 'sr0'|grep -w "unrecognised disk"
        ALLDISK=`lsblk -d|grep disk|grep -v M|grep -v K|awk '{print "/dev/"$1}'`
	echo "本台机器有如下磁盘设备可用,请确认是否正确"
	echo ${ALLDISK}
	echo "下面开始检查每个磁盘是否可用:"
        for i in ${ALLDISK}
	do
		Count=`lsblk ${i}|wc -l`
		MountType=`lsblk ${i}|grep -v NAME|awk '{print $7}'`
        	if [ $Count -gt 2 ];then
        	        echo "${i} 已经挂载使用不可以用作lvm的设备"
        	elif [ -n "$MountType" ]; then
			echo "${i} 已经挂载在${MountType},不可以用作lvm的设备"	
		else
        	        LVMDISK="${i} ${LVMDISK}"
        	fi
	done
	Vgcout=`vgs|wc -l`
	if [ ${Vgcout} -ge 1 ];then
		echo "vg name 如下:"
		vgs
		echo "vg 已经存在,请确认是否可用,否则请执行vgremove 删除vg,执行vgcreate bydata {设备名} 重新创建 VGname:--->bydata"
		exit 1
	else
		echo ${LVMDISK}
		if [ -z "${LVMDISK}" ];then
      			echo "Disk is NULL, so no disk to used, please 清理磁盘 or 新挂载磁盘"
			exit 1
		else
			pvcreate  ${LVMDISK}
			vgcreate bydata ${LVMDISK}
			vgdisplay
		fi
	fi
}

initdeviceid() {
	mkdir -p /opt/oort/sys-conf/
	rm -f /opt/oort/sys-conf/systemd_env_info
	EXTERNAL_PROVIDER=`env|grep -i EXTERNAL_PROVIDER|awk -F '=' '{print $2}'`
	EXTERNAL_DEVICE_ID=`env|grep -i EXTERNAL_DEVICE_ID|awk -F '=' '{print $2}'`
	OORT_ENV_PROVIDER=`env|grep -i EXTERNAL_PROVIDER|awk -F '=' '{print $2}'`
	OORT_ENV_POD_IF_MUL=`env|grep -i EXTERNAL_NW_MUL|awk -F '=' '{print $2}'`
	Md5deviceid=`echo ${EXTERNAL_DEVICE_ID}|md5sum|awk '{print $1}'`
	OwnDeviceid=${EXTERNAL_PROVIDER}-${Md5deviceid}
	touch /opt/oort/sys-conf/oort_deviceid_info
	touch /opt/oort/sys-conf/oort_provider_info
	touch /opt/oort/sys-conf/systemd_env_info
	touch /opt/oort/sys-conf/mul_env_info

	echo "OORT_ENV_DEVICE_ID=${OwnDeviceid}" > /opt/oort/sys-conf/oort_deviceid_info
	echo "OORT_ENV_PROVIDER=${OORT_ENV_PROVIDER}" > /opt/oort/sys-conf/oort_provider_info
	echo "OORT_ENV_POD_IF_MUL=${OORT_ENV_POD_IF_MUL}" > /opt/oort/sys-conf/mul_env_info

	echo "OORT_ENV_PROVIDER=${OORT_ENV_PROVIDER}" > /opt/oort/sys-conf/systemd_env_info
	echo "EXTERNAL_PROVIDER=${EXTERNAL_PROVIDER}" >> /opt/oort/sys-conf/systemd_env_info
	echo "OORT_ENV_DEVICE_ID=${OwnDeviceid}" >> /opt/oort/sys-conf/systemd_env_info
	echo "EXTERNAL_DEVICE_ID=${EXTERNAL_DEVICE_ID}" >> /opt/oort/sys-conf/systemd_env_info
	echo "OORT_ENV_POD_IF_MUL=${OORT_ENV_POD_IF_MUL}" >> /opt/oort/sys-conf/systemd_env_info

	grep 'OORT_ENV_DEVICE_ID' /etc/profile
	if [ $? -eq 0 ];then
		sed -i '/OORT_ENV_DEVICE_ID/d' /etc/profile
	fi
	grep 'OORT_ENV_PROVIDER' /etc/profile
	if [ $? -eq 0 ];then
		sed -i '/OORT_ENV_PROVIDER/d' /etc/profile
	fi
	grep 'OORT_ENV_POD_IF_MUL' /etc/profile
	if [ $? -eq 0 ];then
		sed -i '/OORT_ENV_POD_IF_MUL/d' /etc/profile
	fi
	echo "export OORT_ENV_PROVIDER=${OORT_ENV_PROVIDER}" >> /etc/profile
	echo "export OORT_ENV_DEVICE_ID=${OwnDeviceid}" >> /etc/profile
	echo "export OORT_ENV_POD_IF_MUL=${OORT_ENV_POD_IF_MUL}" >> /etc/profile
	source /etc/profile
        if [ $? -eq 0 ]
        then
		echo "生效/etc/profile环境变量"
        else
                echo "设备环境变量存在问题,请查看 /etc/profile 是否存在问题"
                exit 1
        fi
	export OORT_ENV_PROVIDER=${OORT_ENV_PROVIDER}
	export OORT_ENV_DEVICE_ID=${OwnDeviceid}

}

#remove docker 
debian_remove_pre_installed_docker() {
    status=$(dpkg-query -W -f='${Status}\n' docker-ce | awk '{print $3}')
    if [[ "$status" == "installed" ]];then
        print_msg "Removing pre-installed docker-ce"
        apt-get remove --purge -y docker-ce
    fi
}
############
centos_remove_pre_installed_docker() {
    print_msg "Removing pre-installed docker-ce"
    yum remove docker \
           docker-client \
           docker-client-latest \
           docker-common \
           docker-latest \
           docker-latest-logrotate \
           docker-logrotate \
           docker-engine
}

centos_install_docker() {
    yum-config-manager \
    --add-repo \
    https://download.docker.com/linux/centos/docker-ce.repo
    yum install docker-ce docker-ce-cli containerd.io -y
    systemctl daemon-reload
    systemctl enable docker
    systemctl restart docker
}

debian_install_docker() {
    curl -fsSL https://download.docker.com/linux/debian/gpg | sudo apt-key add -
    apt-key fingerprint 0EBFCD88
    add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/debian $(lsb_release -cs) stable"
    apt-get update
    apt-get install docker-ce docker-ce-cli containerd.io -y
    systemctl daemon-reload
    systemctl enable docker
    systemctl restart docker
}

#change dns_server
change_dnsserver() {
    chattr -i /etc/resolv.conf
    rm -f /etc/resolv.conf
    cat>/etc/resolv.conf<<EOF
options timeout:1 attempts:3 rotate
nameserver 114.114.114.114
nameserver 180.184.1.1
nameserver 119.29.29.29
EOF
    lsattr /etc/resolv.conf
    chattr +i /etc/resolv.conf
}

change_nf_max() {
  echo "net.nf_conntrack_max = 2621440" >> /etc/sysctl.conf
  echo "net.core.wmem_max = 5242880" >> /etc/sysctl.conf
  echo "net.core.wmem_default = 5242880" >> /etc/sysctl.conf
  echo "net.core.rmem_max = 2097152" >> /etc/sysctl.conf
  echo "net.core.rmem_default = 2097152" >> /etc/sysctl.conf
  echo "net.ipv4.tcp_mem  = 2097152 3145728 33554432" >> /etc/sysctl.conf
  echo "net.ipv4.tcp_wmem = 2097152 3145728 33554432" >> /etc/sysctl.conf
  echo "net.ipv4.tcp_rmem = 2097152 3145728 33554432" >> /etc/sysctl.conf
  echo nf_conntrack > /usr/lib/modules-load.d/net.conf
  sysctl -p
}

#change system core parameters
change_pars() {
    echo "net.netfilter.nf_conntrack_max=655350" >> /etc/sysctl.conf
    echo "net.netfilter.nf_conntrack_tcp_timeout_establishedi=1200" >> /etc/sysctl.conf
    sysctl -p
}

#turnoff swap
turnoff_swap() {
        swaptotal=$(grep SwapTotal /proc/meminfo | awk '{print $2}')
        if [ $swaptotal -gt 0 ];then
                echo "Turnning off SWAP"
                swapoff -a
                sed -i -e 's/.*swap/#&/' /etc/fstab
                echo "vm.swappiness=0" >>/etc/sysctl.conf
                sysctl -p
        fi
}

#wget X86 run process file from tos
X86PrepareLocalSoftware() {
    curl -o platform.json "https://settings.ndcpp.com/service/settings/v2/?caller_name=pcdn_netbox&app=254&device_id=1&device_platform=x86_64&os=linux&req_type=init"
    SoftNum=`cat platform.json |jq .data.app.update_module_platform|jq 'length'`
    if [ -z $SoftNum ]; then
        echo "获取配置错误 请重新执行 initlvmdevbox.sh"
        echo "get configure error please try again  initlvmdevbox.sh"
        exit 1
    fi
    index=0
    while [ $index -lt $SoftNum ];
    do
        SoftUrl=`cat platform.json |jq -r .data.app.update_module_platform[$index].md_dl_url`
        SoftName=`cat platform.json |jq -r .data.app.update_module_platform[$index].md_name`
	echo "============================================================="
	sleep 2
        #wget  ${SoftUrl}  -O ${SoftName}.tgz
        curl -o ${SoftName}.tgz ${SoftUrl}
	echo "============================================================="
        SoftMd5=`cat platform.json |jq -r .data.app.update_module_platform[$index].md_md5`
        SoftPath=`cat platform.json |jq -r .data.app.update_module_platform[$index].md_path`
	LocalMd5=`md5sum ${SoftName}.tgz|awk '{print $1}'`
	echo ${LocalMd5}
	if [ "$LocalMd5" = "$SoftMd5" ] ; then
	    mkdir -p ${SoftPath}
            tar -zxvf ${SoftName}.tgz -C ${SoftPath}
	else
		echo "wget file error md5sum value not equal"
		exit 1
        fi
        ((index++))
    done
    rm -f platform.json
}

## debain
StartdebainDaemon() {
    # start
    daemonPath=/usr/local/by-daemon/
    chmod 754 ${daemonPath}netbox_daemon.service
    cp ${daemonPath}netbox_daemon.service /lib/systemd/system/
    ln -fs /lib/systemd/system/netbox_daemon.service /etc/systemd/system/netbox_daemon.service
    systemctl daemon-reload
    systemctl enable netbox_daemon.service
    systemctl start netbox_daemon.service
}

##centos
StartcentosDaemon() {
    daemonPath=/usr/local/by-daemon/
    chmod 754 ${daemonPath}netbox_daemon.service
    cp ${daemonPath}netbox_daemon.service /usr/lib/systemd/system/
    systemctl daemon-reload
    systemctl enable netbox_daemon.service
    systemctl start netbox_daemon.service
}
    
#print help
PrintHelp() {
    printf "Usage:\n"
    printf "sh ProviderInit.sh [command]\n"
    printf "Available Commands:\n"
    printf " --init      : init base info\n"
    printf " --help      : show this help\n"
    printf " --note      : support centos 7.0+ debain \n"
    printf " --initdisk  : used lvm from disk create vg \n"
    exit 0
}

############
####main####
############

if [ $# -gt 0 ]; then
    action=${1}
    case ${action} in
        "init")
        check_sysinfo
        check_cgroupv2
        cpumem_info
	check_device_file
        change_dnsserver
        turnoff_swap
        change_nf_max
	Arch=`uname -m`
	#check arch
	if [ "${Arch}" = "x86_64" ]
	then
		echo "系统架构是 :  ${Arch}"
	else
		echo "系统架构是 :  ${Arch}"
		echo "系统架构不是x86架构, 服务部署会失败, 请使用x86架构的机器"
		exit 1
	fi
	# create owner diviceid
	env|grep -i DEVICE_ID
	if [ $? -eq 0 ]
	then
		initdeviceid
	else
		echo "设备环境变量没有传递,请更新设备环境变量 EXTERNAL_PROVIDER and EXTERNAL_DEVICE_ID"
		exit 1
	fi
	env|grep -i EXTERNAL_PROVIDER
	if [ $? -eq 0 ]
	then
		initdeviceid
	else
		echo "设备环境变量没有传递,请更新设备环境变量 EXTERNAL_PROVIDER and EXTERNAL_DEVICE_ID"
		exit 1
	fi
	#check system 
        if [ "${SysTem}" = "centos" ]
          then
            yum update
            yum install jq -y
            if [ $? -ne 0 ];then
                centos_change_reposource
            fi
            yum -y install https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
            yum update
            yum -y install redhat-lsb-core util-linux fio lshw
            yum -y install wget curl bind-utils yum-utils dmidecode 
            yum install -y fio
            yum install -y ntpdate ntp
            yum install -y jq  ipset
            yum install -y lvm2
            yum install -y lvm
            docker --version
            if [ $? -ne 0 ];then
                centos_remove_pre_installed_docker
                centos_install_docker
            fi
            systemctl enable docker
            systemctl enable ntpd
            systemctl enable ntpdate
            ntpdate time2.bytedance.com
            systemctl start ntpdate
            systemctl restart ntpd
            systemctl start docker
            DocVer=`docker --version|awk '{print $3}'|awk -F "." '{print $1}'`
            if [ "${DocVer}" -lt 18 ];then
                centos_remove_pre_installed_docker
                centos_install_docker
            fi	
	    X86PrepareLocalSoftware
            StartcentosDaemon
        elif [ "${SysTem}" = "debian" ] 
          then
            apt-get update
            apt-get install fio -y
            if [ $? -ne 0 ];then
                debian_change_reposource
            fi
            apt-get -y install lsb-release curl wget dnsutils util-linux systemd lshw dmidecode
            apt-get install -y lvm2
            apt-get install -y jq  ipset
            apt-get install -y update ntp
            apt-get install -y lvm
            docker --version
            if [ $? -ne 0 ];then
                apt-get -y install apt-transport-https  ca-certificates gnupg-agent software-properties-common 
                debian_remove_pre_installed_docker
                debian_install_docker
            fi
            systemctl enable docker
            systemctl enable ntp
            ntpdate time2.bytedance.com
            systemctl restart ntp
            #systemctl start docker
            DocVer=`docker --version|awk '{print $3}'|awk -F "." '{print $1}'`
            if [ "${DocVer}" -lt 18 ];then
                apt-get -y install apt-transport-https  ca-certificates gnupg-agent software-properties-common 
                debian_remove_pre_installed_docker
                debian_install_docker
            fi
	    X86PrepareLocalSoftware
            StartdebainDaemon
        else
            echo -e "System check fail..........................." 
            echo -e "\033[31mcurrent System is Not Meet the Requirements \033[0m"
            echo -e "\033[31m 当前系统不满足要求,请更换 centos 和 debian 系统 \033[0m"
            exit 1
        fi
        wget http://lf9-netbox-package.bytetos.com/obj/netbox-update-package/initdevice/libstdcpp.tgz
        tar -zxvf libstdcpp.tgz
        cp libstdc++.so.6.0.26 /usr/lib64/ &&  cd /usr/lib64/  &&  ln -f -s libstdc++.so.6.0.26 libstdc++.so.6
        echo "初始化脚本执行完毕"
	echo "供应商设备ID"  "|" ${EXTERNAL_DEVICE_ID}
	echo "字节设备ID"  "|" ${OwnDeviceid}
	echo "请跳转至字节 供应商平台查看----->  https://cscm.bytedance.com/measurement/rule"
	echo "把上述对应ID 填入供应商平台"
	;;
        "help") 
            PrintHelp
            ;;
        "initdisk") 
            init_disk
            ;;
        *) 
            printf "Error: param error!\n"
            PrintHelp
            ;;
    esac
else
    PrintHelp
fi
