diff --git a/build.sh b/build.sh index cde96f48d72f6f04832c38c02847e39c760c1b09..c7f02dc6fa56d956255c0a39a6f8859d5c9bda34 100755 --- a/build.sh +++ b/build.sh @@ -23,7 +23,6 @@ SCRIPTS_DIR="${SRC}/scripts" TOOLS_DIR="${SRC}/tools" APPS_DIR="${SRC}/apps" DOWNLOAD_DIR="${OUTPUT}/download" -LOG_DIR="${OUTPUT}/log" YUM_CONF="${OVERLAY_DIR}/etc/yum.repos.d/openEuler.repo" CONFIG_RPM_LIST="${CONFIG_DIR}/rpm.list" @@ -33,14 +32,14 @@ SCRIPTS_CHROOT="${SCRIPTS_DIR}/make_cfg.sh" ############################################ [[ -d ${ROOTFS} ]] && rm -rf ${ROOTFS} -[[ -d ${LOG_DIR} ]] && rm -rf ${LOG_DIR} -mkdir -p ${OUTPUT} ${LOG_DIR} ${ROOTFS} +mkdir -p ${OUTPUT} ${ROOTFS} if [[ ! -d ${DOWNLOAD_DIR} ]]; then mkdir -p ${DOWNLOAD_DIR} fi source ${SRC}/scripts/install_host_tools.sh source ${SRC}/scripts/install_bisheng.sh +source ${SRC}/scripts/install_devkit.sh source ${SRC}/scripts/make_image.sh source ${SRC}/scripts/install_driver_package.sh source ${SRC}/scripts/install_rpms.sh diff --git a/scripts/devkit/argv.json b/scripts/devkit/argv.json new file mode 100644 index 0000000000000000000000000000000000000000..77acab5db1d84a356757c715763a088b373677aa --- /dev/null +++ b/scripts/devkit/argv.json @@ -0,0 +1,20 @@ +// This configuration file allows you to pass permanent command line arguments to VS Code. +// Only a subset of arguments is currently supported to reduce the likelihood of breaking +// the installation. +// +// PLEASE DO NOT CHANGE WITHOUT UNDERSTANDING THE IMPACT +// +// NOTE: Changing this file requires a restart of VS Code. +{ + // Use software rendering instead of hardware accelerated rendering. + // This can help in cases where you see rendering issues in VS Code. + // "disable-hardware-acceleration": true, + + // Allows to disable crash reporting. + // Should restart the app if the value is changed. + "enable-crash-reporter": true, + + // Unique id used for correlating crash reports sent from this instance. + // Do not edit this value. + "password-store": "basic", "locale": "zh-cn" +} \ No newline at end of file diff --git a/scripts/devkit/common.sh b/scripts/devkit/common.sh new file mode 100755 index 0000000000000000000000000000000000000000..2c3c8efc204c2a5aabca677d9190cf1d92be6209 --- /dev/null +++ b/scripts/devkit/common.sh @@ -0,0 +1,2308 @@ +#!/bin/bash +#Description: DevKit common function +#Copyright: Copyright © Huawei Technologies Co., Ltd. 2023. All rights reserved. +#History: 2023-2-9 created +CURRENT_DIR=$(cd $(dirname $0); pwd) +source ${CURRENT_DIR}/const.sh +source ${CURRENT_DIR}/log.sh +os_type="" +package_tool="" + +function copy_install_log(){ + # 存放安装相关日志 + devkit_install_logs="${install_path}/DevKitInstallLogs" + mkdir -p ${devkit_install_logs} + INSTALL_LOG_PATH="${install_path}/DevKit/logs/install_plugins.log" + if [ -f ${INSTALL_LOG} ]; then + cp ${INSTALL_LOG} ${devkit_install_logs} + fi + if [ -f ${INSTALL_DEP_LOG} ]; then + cp ${INSTALL_DEP_LOG} ${devkit_install_logs} + fi + if [ -f ${TOOL_LOG} ]; then + cp ${TOOL_LOG} ${devkit_install_logs} + fi + if [ -f ${INSTALL_LOG_PATH} ]; then + cp ${INSTALL_LOG_PATH} ${devkit_install_logs} + fi + +} + +# 文件中写入参数:sed_ini [file] [param] [param=set_value] +function sed_ini() +{ + local source_file=$1 + local comp_str=$2 + local sed_str=$3 + local mode=$4 + if [[ -z "${mode}" ]]; then + mode="0" + fi + if [[ ! -f "${source_file}" ]]; then + echo_and_log "sed_ini:${source_file} is not exist" "${ERROR}" + exit "${ERROR}" + fi + is_exist=$(grep "${comp_str}" "${source_file}") + # 设值 + if [[ "${mode}" == "0" ]]; then + if [[ -z "${is_exist}" ]]; then + echo -e "\n${sed_str}" >> "${source_file}" + else + sed -i "s%${comp_str}.*%${sed_str}%g" "${source_file}" + fi + # 替换 + else + if [[ -n "${is_exist}" ]]; then + sed -i "s%${comp_str}%${sed_str}%g" "${source_file}" + fi + fi + if [[ "$?" -ne "${SUCCESS}" ]]; then + echo_and_log "sed_ini: failed to write ${sed_str} to ${source_file}." "${ERROR}" + exit "${ERROR}" + fi +} + +function check_architecture(){ + architecture=$(uname -m) +} + +function recommended_os() { + local log_file_path=$1 + if [[ "${os_support_status}" == 1 ]]; then + # 为空时不在兼容性系统中 + echo_and_log "The current OS may fail to be installed or run because the OS version is not in the compatibility list supported by the Kunpeng DevKit." "${DOING}" "${log_file_path}" + echo_and_log "\nSelect the OS series to which the current OS belongs:" "${DOING}" "${log_file_path}" + printf "%-16s %-29s %-20s\n" " SequenceNumber" "OS Series" "Description" + for ((i=0;i<${#not_support_os[@]};i++)); do + printf "%-16s %-29s %-20s\n" " [$((i+1))]" "${not_support_os[i]}" "${not_support_os_description[i]}" + done + echo "" + echo -n -e "\e[1;37mIf you continue the installation, enter the supported OS serial sequence number. If you want to exit the installation, enter no:\e[0m" + echo "If you continue the installation, enter the supported OS serial sequence number. If you want to exit the installation, enter no:" >> "${log_file_path}" + read -t "${TIMEOUT}" -r number + if [[ "$?" -gt 128 ]]; then + echo_and_log "Input timeout." "${ERROR}" + exit ${SUCCESS} + fi + if [[ "$number" == "1" ]]; then + echo_and_log "You have selected the CentOS series. We will continue installation tool with CentOS 7.6." "${SUCCESS}" "${log_file_path}" + echo_and_log "\nContinue the environment check..." "${DOING}" "${log_file_path}" + os_name="$default_centos_name" + os_version="7.6" + os_type="CentOS" + elif [[ "$number" == "2" ]]; then + echo_and_log "You have selected the Debian series. We will continue installation tool with Ubuntu 18.04." "${DOING}" "${log_file_path}" + echo_and_log "\nContinue the environment check..." "${DOING}" "${log_file_path}" + os_name="$default_debian_name" + os_version="18.04" + os_type="DeepinOS" + elif [[ "$number" == "3" ]]; then + echo_and_log "You have selected the OpenEuler series. We will continue installation tool with OpenEuler 20.03." "${DOING}" "${log_file_path}" + echo_and_log "\nContinue the environment check..." "${DOING}" "${log_file_path}" + os_name="$default_openeuler_name" + os_version="20.03" + os_type="OpenEulerOS" + elif [[ "$(input_value_check ${number})" == "no" ]]; then + echo_and_log "\nOperation aborted." "${DOING}" "${log_file_path}" + echo_and_log "\nEnvironment check canceled." "${DOING}" "${log_file_path}" + exit ${SUCCESS} + else + echo_and_log "\nInvalid input. Environment check canceled." "${DOING}" "${log_file_path}" + exit ${SUCCESS} + fi + elif [[ "${os_support_status}" == 2 ]]; then + + if [[ -z "$os_version" ]]; then + # 为空时在兼容性系列中但系统不支持 + os_info="$os_type" + else + # 此时os在兼容性系列中但版本不支持 + if [[ -z "$os_version_number" ]]; then + os_info="$os_version" + else + os_info="$os_version $os_version_number" + fi + fi + echo_and_log "\nYour OS version $os_info is not included in the compatibility list supported by the Kunpeng DevKit. The installation and running may fail" "${DOING}" "${log_file_path}" + if [[ "$openeuler_series" =~ "$os_version" ]] || [[ "$openeuler_series" =~ "$os_type" ]]; then + os_name="$default_openeuler_name" + elif [[ "$debian_series" =~ "$os_version" ]] || [[ "$debian_series" =~ "$os_type" ]]; then + os_name="$default_debian_name" + elif [[ $centos_series =~ $os_version ]] || [[ $centos_series =~ $os_type ]]; then + os_name="$default_centos_name" + fi + echo -n -e "The default OS version(default os:$os_name) will be used to install the Kunpeng DevKit. Do you want to continue?[y/N]: " + echo "The default OS version(default os:$os_name) will be used to install the Kunpeng DevKit. Do you want to continue?[y/N]: " >> ${log_file_path} + read -t "${TIMEOUT}" -r input + if [[ "$?" -gt 128 ]]; then + echo_and_log "Input timeout." "${ERROR}" + exit ${SUCCESS} + fi + local input=$(input_value_check ${input}) + if [[ "${input}" == "yes" ]]; then + echo " your selected is ${input}" >> ${log_file_path} + echo_and_log "\nContinue the environment check..." "${DOING}" "${log_file_path}" + elif [[ "${input}" == "no" ]]; then + echo " your selected is ${input}" >> ${log_file_path} + echo_and_log "Environment check canceled." "${DOING}" "${log_file_path}" + exit ${SUCCESS} + else + echo_and_log "Invalid input. Environment check canceled." "${ERROR}" "${log_file_path}" + fi + fi +} + +# 获取OS版本号 +function get_os_version() { + local install_log_path=$2 # 检查或者安装记录日志 + if [[ ${os_type} == "OpenEulerOS" ]]; then + os_version=$(cat /etc/os-release |grep VERSION= |awk -F '"' '{print$2}' |awk -F ' ' '{print$1$2}') + elif [[ ${os_type} == "uosEulerOS" ]]; then + os_version=$(cat /etc/os-release |grep VERSION_ID= |awk -F '"' '{print$2}') + elif [[ ${os_type} == "EulerOS" ]]; then + os_version=$(cat /etc/euleros-release | awk '{print$3$4}') + elif [[ ${os_type} == "CentOS" ]]; then + os_version=$(cat /etc/redhat-release | grep -Po "\d+\.\d+") + elif [[ ${os_type} == "NeoKylinOS" ]]; then + os_version=$(cat /etc/system-release | awk '{print$6}') + elif [[ ${os_type} == "SLESOS" ]]; then + os_version=$(cat /etc/os-release |grep VERSION_ID | awk -F '"' '{print$2}') + elif [[ ${os_type} == "UbuntuOS" ]]; then + os_version=$(cat /etc/os-release | grep -Po "\d+\.\d+" | awk 'NR==1') + elif [[ ${os_type} == "DebianOS" ]]; then + os_version=$(cat /etc/os-release |grep VERSION_ID= |awk -F '"' '{print$2}') + elif [[ ${os_type} == "LinxOS" ]]; then + os_version=$(cat /etc/os-release |grep PRETTY_NAME= | grep -Po "\d+\.\d+\.\d+") + elif [[ ${os_type} == "KylinOS" ]]; then + os_version=$(cat /etc/kylin-release | grep -Po "V\d+") + elif [[ ${os_type} == "UOS" ]]; then + os_version=$(cat /etc/os-release |grep VERSION_ID= |awk -F '"' '{print$2}'|sed 's/[[:space:]]//g') + elif [[ ${os_type} == "iSoftOS" ]]; then + os_version=$(cat /etc/isoft-release | grep -Po "\d+\.\d+") + elif [[ ${os_type} == "BCLinuxOS" ]]; then + os_version=$(cat /etc/redhat-release | grep -Po "\d+\.\d+") + elif [[ ${os_type} == "DeepinOS" ]]; then + os_version=$(cat /etc/os-release |grep VERSION_ID | awk -F '"' '{print$2}') + elif [[ ${os_type} == "UnionTechOS" ]]; then + os_version=$(cat /etc/os-version |grep MajorVersion= |awk -F '=' '{print$2}')-$(cat /etc/os-version |grep MinorVersion= |awk -F '=' '{print$2}') + elif [[ ${os_type} == "KylinSecOS" ]]; then + os_version=$(cat /etc/os-release | grep VERSION_ID= |awk -F '"' '{print$2}') + elif [[ ${os_type} == "RedHatOS" ]]; then + os_version=$(cat /etc/redhat-release | grep -Po "\d+\.\d+") + else + os_support_status=1 # OS 类型不支持 + recommended_os ${install_log_path} + return 0 + fi + platform=$(uname -m) + if [[ ${platform} == "aarch64" ]]; then + support_os_version=${OS_LIST_VERSION_ARM[$os_type]} + else + support_os_version=${OS_LIST_VERSION_X86[$os_type]} + fi + if [[ ! ${support_os_version} =~ "${os_version}" ]]; then + os_support_status=2 # OS 版本不支持 + recommended_os ${install_log_path} + fi +} + +# 获取OS类型 +function get_os_type() +{ + local install_ini=$1 + local str_os_name="" + local install_log_path=$2 + if [[ -z ${install_log_path} ]]; then + install_log_path="${INSTALL_DEP_LOG}" + fi + os_type="" + for ((i=0;i<${#OS_LIST[@]};i++)) + do + str_os_name=$(grep "^NAME" "${OS_RELEASE}" | grep -o "${OS_LIST[$i]}" | head -n 1) + if [[ -n "${str_os_name}" ]]; then #判断是否为空 + if [ "${str_os_name}" == "${OS_LIST[$i]}" ]; then + os_type=${OS_TYPE_LIST[$i]} + break + fi + else + # 统信服务器操作系统,名称各版本名称不一样 + if [ -f /etc/UnionTech-release ]; then + os_type="UnionTechOS" + break + fi + fi + done + get_os_version "${os_type}" "${install_log_path}" + if [[ -n "${install_ini}" ]]; then + sed_ini "${install_ini}" "OS_TYPE" "OS_TYPE=${os_type}" + sed_ini "${install_ini}" "OS_VERSION" "OS_VERSION=${os_version}" + fi + OS_TYPE="${os_type}" +} + +# 获取包管理工具名称 yum|apt|zypper +function get_package_tool() { + local log_file_path=$1 + if [[ "$2" ]]; then + local os_type=$2 + fi + package_tool=${PACKAGE_TOOL_LIST["${os_type}"]} + if [[ -n "${install_ini}" ]]; then + sed_ini "${install_ini}" "PACKAGE_TOOL" "PACKAGE_TOOL=${package_tool}" + fi + if [[ -z "${os_type}" ]]; then + echo_and_log "Unsupported OS type!" "${ERROR}" "${log_file_path}" + exit "${SUCCESS}" + fi + echo_and_log "The system uses ${package_tool} to manage packages." "${ECHO}" "${log_file_path}" +} + +# 判断安装系统类型 是否为docker 或者其他类型容器 +function check_system_type() { + system_is_container=1 +} + +# 关闭端口 +function close_port(){ + local port=$1 + local log_file="$2" + if [[ "${package_tool}" == "yum" ]] || [[ "${package_tool}" == "zypper" ]];then + firewall-cmd --permanent --remove-port=${port}/tcp >/dev/null 2>&1 + firewall-cmd --reload >/dev/null 2>&1 + remove_flag=$? + else + command -v firewalld > /dev/null 2>&1 + if [[ "$?" == "0" ]]; then + firewalld_status=$(systemctl status firewalld | grep -E "Active" | awk -F":" '{print $2}'| awk -F" " '{print $1}') + if [[ "$firewalld_status" == "active" ]]; then + firewall-cmd --permanent --remove-port=${port}/tcp >/dev/null 2>&1 + firewall-cmd --reload >/dev/null 2>&1 + remove_flag=$? + fi + else + ufw delete allow ${port}/tcp >/dev/null 2>&1 + remove_flag=$? + fi + fi + if [[ "$remove_flag" == "0" ]]; then + echo_and_log "Port ${port} removed successfully." "${DOING}" "${log_file}" + fi +} + +# 关闭由工具开启的端口 +function close_opened_ports() { + local config_path=$1 + local log_file=$2 + local port_string=$(grep -w OPEN_PORT "${config_path}" | awk -F= '{if($2 !="") print $2}') + opened_ports=(${port_string// / }) + for port in "${opened_ports[@]}" + do + close_port "${port}" "${log_file}" + done +} + +# 环境检查展示项 +function displaying_check_items(){ + + echo_and_log "\nInstallation environment check result:" "${ECHO}" "${INSTALL_LOG}" + printf "%-20s %-35s %-14s %-20s\n" " SequenceNumber" "CheckItem" "CheckResult" "Suggestion" + printf "%-2s %-2s %-20s %-35s %-14s %-20s\n" "[$(date "+%Y-%m-%d %H:%M:%S")]" "[INFO]" "SequenceNumber" "CheckItem" "CheckResult" "Suggestion" >> ${INSTALL_LOG} + for ((i=0;i<${#CHECK_ITEM[@]};i++)); do + if [ "${CheckResult[i]}" == "fail" ]; then + local color=31 + else + local color=32 + fi + if [[ "$i" == "${#CHECK_ITEM[@]}" ]]; then + return 0 + fi + printf "%-20s %-35s \033[1;${color}m%-14s\033[0m \033[1;${color}m%-20s\033[0m\n" " [$((i+1))]" "${CHECK_ITEM[i]}" "${CheckResult[i]}" "${Suggestion[i]}" + printf "%-2s %-2s %-20s %-35s \033[1;${color}m%-14s\033[0m \033[1;${color}m%-20s\033[0m\n" "[$(date "+%Y-%m-%d %H:%M:%S")]" "[INFO]" "[$((i+1))]" "${CHECK_ITEM[i]}" "${CheckResult[i]}" "${Suggestion[i]}" >> ${INSTALL_LOG} + done + echo "" +} + +# 环境检查失败时,分情况获取用户下步操作 +function get_user_choice(){ + for ((i=0;i<${#CheckResult[@]};i++)); do + if [[ "${CheckResult[i]}" == "fail" ]]; then + if [[ "$i" -le "3" ]]; then + echo_and_log "The check items 1 to 3 fails, proceed according to the handling suggestions." "${DOING}" "${INSTALL_LOG}" + echo_and_log "Failed to check the environment. Perform related operations based on the suggestions and reinstall the tool." "${DOING}" "${INSTALL_LOG}" + echo_and_log "Installation canceled." "${DOING}" "${INSTALL_LOG}" + exit 1 + else + while true; do + echo "Installation Start Phase:Clearable=False" >> ${INSTALL_LOG} + read -t "${TIMEOUT}" -p "Do you want to authorize the tool to handle the items failed in the installation environment check?[y/N]: " input + if [[ "$?" -gt 128 ]]; then + echo_and_log "Input timeout." "${ERROR}" + exit ${ERROR} + fi + echo "The installation environment is checked. View the handling suggestions for the items that fail to pass the check" >> "${INSTALL_LOG}" + echo "Do you want to authorize the tool to handle the items failed in the installation environment check? You input is:$y_n" >> "${INSTALL_LOG}" + echo "Installation Start Phase:Clearable=True" >> ${INSTALL_LOG} + local input=$(input_value_check ${input}) + if [[ "${input}" == "yes" ]]; then + user_choice=yes + return 0 + elif [[ "${input}" == "no" ]]; then + echo "Installation Start Phase:Clearable=False" >> ${INSTALL_LOG} + echo_and_log "You have refused to authorize the tool to process failed items in the environment check. Tool installation canceled." "${DOING}" "${INSTALL_LOG}" + echo_and_log "Installation failed." "${DOING}" "${INSTALL_LOG}" + exit ${ERROR} + else + echo_and_log "Incorrect entered information." "${DOING}" "${INSTALL_LOG}" + fi + done + fi + fi + done +} + +# 终止服务防止僵尸进程存在 +function stop_services() { + #web模式,关闭服务,移除开机启动 + aim_dir=${SYSTEM_DIR_LIST["${os_type}"]} + gunicorn_framework_file="${aim_dir}/gunicorn_framework.service" + gunicorn_plugin_file="${aim_dir}/gunicorn_plugin.service" + devkit_nginx_file="${aim_dir}/devkit_nginx.service" + if [[ ${system_is_container} == 1 ]]; then + ppid=$(ps -ef |grep "DevKit/tools/nginx/conf/devkit_nginx.conf"| grep -v grep | awk '{print $2}') + if [[ ${ppid} ]]; then + for pid in ${ppid};do + kill -9 $(ps -ef | grep ${pid}|grep -v grep | awk '{print $2}') + done + fi + gunicorn_pid=$(pidof ${install_path}/DevKit/tools/python_venv/bin/python3) + if [[ ${gunicorn_pid} ]]; then + kill -9 ${gunicorn_pid} > /dev/null 2>&1 + else + gunicorn_framework_pid=$(ps -ef |grep "devkitframework/gunicorn_framework.py"| grep -v grep | awk '{print $2}') + [[ ${gunicorn_framework_pid} ]] && kill -9 ${gunicorn_framework_pid} + gunicorn_plugin_pid=$(ps -ef | grep "devkitplugins/gunicorn_plugin.py" | grep -v grep | awk '{print $2}') + [[ ${gunicorn_plugin_pid} ]] && kill -9 ${gunicorn_plugin_pid} + fi + id "devkit" > /dev/null 2>&1 + if [[ $? == 0 ]]; then + devkit_pid=$(ps -u devkit -f | awk 'NR> 1 {print $2}') + [[ ${devkit_pid} ]] && echo "$devkit_pid" | xargs kill -9 + fi + else + gunicorn_plugin_process=$(ps -ef | grep gunicorn_plugin |grep -v grep | awk '{print $2}') + gunicorn_framework_process=$(ps -ef | grep gunicorn_framework |grep -v grep | awk '{print $2}') + [[ "${gunicorn_plugin_process}" ]] && kill -9 ${gunicorn_plugin_process} + [[ "${gunicorn_framework_process}" ]] && kill -9 ${gunicorn_framework_process} + # 杀掉服务停止1s防止下面stop冲突导致卸载卡顿 + sleep 1s + # 停止定时任务 + which crontab >/dev/null 2>&1 + if [ "$?" == "0" ]; then + crontab -r -u devkit >/dev/null 2>&1 + fi + # 清除nginx服务 + systemctl disable devkit_nginx.service >/dev/null 2>&1 + if [ $? -eq 0 ];then + systemctl stop devkit_nginx.service + fi + # 清除框架服务 + systemctl disable gunicorn_framework.service >/dev/null 2>&1 + if [ $? -eq 0 ];then + systemctl stop gunicorn_framework.service + fi + # 清除plugin服务 + systemctl disable gunicorn_plugin.service >/dev/null 2>&1 + if [ $? -eq 0 ];then + systemctl stop gunicorn_plugin.service + fi + + [[ -f ${gunicorn_framework_file} ]] && rm -rf ${gunicorn_framework_file} + [[ -f ${gunicorn_plugin_file} ]] && rm -rf ${gunicorn_plugin_file} + [[ -f ${devkit_nginx_file} ]] && rm -rf ${devkit_nginx_file} + systemctl daemon-reload + fi +} + + +function init_need_install_lib() { + local plugin_essential_lost="$1" + essential_need_install_lib_print=() + all_need_install_lib=() + for i in $(echo "${plugin_essential_lost}"| tr "" "");do + essential_need_install_lib_print[${#essential_need_install_lib_print[@]}]=${i} + done + all_need_install_lib=(${essential_need_install_lib_print[@]}) + install_missing_dependence 'install' +} + +function plugin_lost_dependency_install() { + # 插件的安装 区分必要和非必要安装 + if [[ "${sys_perf_essential_lost}" ]]; then + init_need_install_lib "${sys_perf_essential_lost}" + sys_perf_essential_lost="$(echo ${install_fail_array[@]})" + fi + if [ "${java_perf_essential_lost}" ]; then + init_need_install_lib "${java_perf_essential_lost}" + java_perf_essential_lost="$(echo ${install_fail_array[@]})" + fi + + if [ "${sys_diagnosis_essential_lost}" ]; then + init_need_install_lib "${sys_diagnosis_essential_lost}" + sys_diagnosis_essential_lost="$(echo ${install_fail_array[@]})" + fi +} + +function show_dependencies_to_install() { + # 展示需要安装的依赖 + local need_install_lib="" + if [ ${framework_dependencies_status} = 1 ];then + # all_need_install_lib 由env_check->dependence_check检查获取 + need_install_lib="$(echo ${all_need_install_lib[@]})" + fi + if [[ "${sys_perf_essential_lost}" ]]; then + need_install_lib="${need_install_lib} ${sys_perf_essential_lost}" + fi + if [ "${java_perf_essential_lost}" ]; then + need_install_lib="${need_install_lib} ${java_perf_essential_lost[@]}" + fi + + if [ "${sys_diagnosis_essential_lost}" ]; then + need_install_lib="${need_install_lib} ${sys_diagnosis_essential_lost[@]}" + fi + if [[ -n "${need_install_lib}" ]];then + need_install_lib=$(echo ${need_install_lib} | tr ' ' '\n' | sort -u | tr '\n' ' ') + echo_and_log "The following necessary components have not been installed: ${need_install_lib}" "${DOING}" "${install_dep_check_path}" + fi +} + +# 处理环境检查中的失败项 +function resolve_fail_checklist(){ + if [[ "$user_choice" != "yes" ]]; then + return + fi + show_dependencies_to_install + if [ ${framework_dependencies_status} = 1 ]; then + # 执行安装时 + install_missing_dependence 'install' + if [ $? -ne 0 ]; then + exit ${SUCCESS} + fi + fi + plugin_lost_dependency_install + if [[ "${CheckResult[4]}" = "fail" ]]; then + deal_devkit_sudoers_config + logger "The /etc/sudoers.d/devkit_sudoers is configured successfully." + fi + + if [[ "${CheckResult[5]}" = "fail" ]]; then + # 删除devkit的定时任务 + which crontab >/dev/null 2>&1 + if [ "$?" == "0" ]; then + crontab -r -u devkit + fi + delete_devkit_user + delete_multi_user + logger "The ${USER_HOME}/devkit folder is deleted successfully." + fi + + if [[ "${CheckResult[6]}" = "fail" ]]; then + # 关停服务并删除配置文件 + stop_services + fi + if [[ "${CheckResult[8]}" = "fail" ]];then + # 清理/home/devkit + [[ -d "/home/devkit" ]] && rm_rf "/home/devkit" + fi + if [[ "${CheckResult[7]}" = "fail" || ${status_of_install_folders} == 2 ]]; then + # 可以判定为用户已经安装了工具,删除安装路径 执行清理动作,删除目录,删除各种配置文件 + close_opened_ports "${install_ini}" "${INSTALL_LOG}" + init_env_common + fi + +} + +function enable_firewall_ports(){ + local port=$1 + if [[ "${package_tool}" == "yum" ]] || [[ "${package_tool}" == "zypper" ]];then + firewall-cmd --add-port=${port}/tcp --permanent >/dev/null 2>&1 + firewall-cmd --reload >/dev/null 2>&1 + enable_flag=$? + else + if [[ "$status_by_firewalld" == "active" ]] && [[ "$status_by_ufw" == "active" ]]; then + # 此时不做开启,给出相应提示,放在安装成功前提示 + failed_enable_port=yes + elif [[ "$status_by_firewalld" == "active" ]]; then + firewall-cmd --add-port=${port}/tcp --permanent >/dev/null 2>&1 + firewall-cmd --reload >/dev/null 2>&1 + enable_flag=$? + else + ufw allow ${port}/tcp >/dev/null 2>&1 + enable_flag=$? + fi + fi + if [[ "$enable_flag" == "0" ]]; then + # 异常终止的时候清理端口判断用 + nginx_port_owner=${USER_NAME} + local install_ini="${CURRENT_DIR}/${INSTALL_INI}" + sed_ini "${install_ini}" "NGINX_PORT_OWNER=" "NGINX_PORT_OWNER=${USER_NAME}" + open_port+=" ${port}" + echo_and_log "Port ${port} is enabled successfully." "${DOING}" + fi +} + +# 开启多个端口 +function enable_multi_firewall_ports(){ + local ports=$1 + for port in ${ports[@]} + do + enable_firewall_ports "${port}" + done + sed_ini "${install_ini}" "OPEN_PORT" "OPEN_PORT=${open_port}" +} + +# 检查端口是否开始防火墙 +function check_firewalld_status(){ + # 防火墙状态判断并提示相关信息 $3端口号 + local port=$1 + if [[ "${package_tool}" == "yum" ]] || [[ "${package_tool}" == "zypper" ]]; then + firewall_status_of_redhat_or_suse "$1" + else + firewall_status_of_debian "$1" + fi +} + +function firewall_status_of_redhat_or_suse(){ + local port=$1 + command -v firewalld > /dev/null 2>&1 + if [[ "$?" != "0" ]]; then + return 0 + fi + get_port_status_by_firewall "$port" +} + +# 通过firewall检查端口状态status_of_firewall=1 代表未开启 +function get_port_status_by_firewall(){ + local port=$1 + status_by_firewalld=$(systemctl status firewalld | grep -E "Active" | awk -F":" '{print $2}'| awk -F" " '{print $1}') + if [[ $status_by_firewalld == "active" ]]; then + local port_status=$(firewall-cmd --query-port=${port}/tcp) + if [[ $port_status == "no" ]]; then + status_of_firewall=1 + disabled_ports="${disabled_ports} ${port}" + fi + fi +} + +function firewall_status_of_debian(){ + local port=$1 + command -v firewalld > /dev/null 2>&1 + firewalld_flag=$? + command -v ufw > /dev/null 2>&1 + ufw_flag=$? + if [[ "$firewalld_flag" != "0" ]] && [[ "$ufw_flag" != "0" ]]; then + while true; do + logger "The ufw doesn't exist in the system. However, we need to use the ufw to check the firewall status." ${TIP_COLOR_WARNING} + logger 'Now, we need to run the "apt-get -y install ufw" to install the ufw.' ${TIP_COLOR_WARNING} + read -t "${TIMEOUT}" -p "Are you agree to install the ufw command?[y/N],(default:y): " input + if [[ "$?" -gt 128 ]]; then + echo_and_log "Input timeout." "${ERROR}" + return 0 + fi + # 默认为yes + input=${input:='y'} + logger "Are you agree to install the ufw command? You input is:${input}" + local answer=$(input_value_check ${input}) + if [[ "${answer}" == "yes" ]];then + apt-get -y install ufw + if [[ "$?" != "0" ]]; then + # 安装失败,提示退出 + logger "Failed to install the ufw command. Manually install the ufw command." "WARNING" + echo -e "\e[1;33mFailed to install the ufw command. Run the following command to install the ufw:\e[0m" + prompt_msg_debian "$port" + return 0 + fi + firewall_status_of_debian "$port" + return 0 + elif [[ "${answer}" == "no" ]]; then + logger "You refused to install the ufw command. Manually install the ufw command." "WARNING" + echo -e "\e[1;33mYou refused to install the ufw command. Run the following command to install the ufw:\e[0m" + prompt_msg_debian "$port" + return 0 + else + logger "Incorrect entered information." ${TIP_COLOR_WARNING} + fi + done + elif [[ "$firewalld_flag" != "0" ]] && [[ "$ufw_flag" == "0" ]]; then + check_debian_port "$port" + elif [[ "$firewalld_flag" == "0" ]] && [[ "$ufw_flag" != "0" ]]; then + get_port_status_by_firewall "$port" + else + status_by_ufw=$(ufw status | grep -E Status | awk -F": " '{print $2}') + status_by_firewalld=$(systemctl status firewalld | grep -E "Active" | awk -F":" '{print $2}'| awk -F" " '{print $1}') + if [[ "$status_by_firewalld" == "active" ]]; then + local port_status=$(firewall-cmd --query-port=${port}/tcp) + if [[ $port_status == "no" ]]; then + status_of_firewall=1 + disabled_ports="${disabled_ports} ${port}" + fi + return 0 + elif [[ "$status_by_ufw" == "active" ]]; then + local port_status=$(ufw status | grep -E ${port}/tcp | awk -F" " '{print $2}' | head -n 1) + if [[ $port_status != "ALLOW" ]]; then + status_of_firewall=1 + disabled_ports="${disabled_ports} ${port}" + fi + return 0 + fi + fi +} + +# 检查debian系列防火墙端口 +function check_debian_port(){ + local port=$1 + status_by_ufw=$(ufw status | grep -E Status | awk -F": " '{print $2}') + local port_status=$(ufw status | grep -E ${port}/tcp | awk -F" " '{print $2}' | head -n 1) + if [[ $status_by_ufw == "active" ]] && [[ $port_status != "ALLOW" ]]; then + status_of_firewall=1 + disabled_ports="${disabled_ports} ${port}" + fi +} + +# debian系统不存在ufw时的提示语 +function prompt_msg_debian(){ + local port=$1 + echo -e "\e[1;33m apt-get -y install ufw\e[0m" + echo -e "\e[1;33mTo ensure successful running of the tool, enable the web service port as follows:\e[0m" + echo -e "\e[1;33m 1.Check whether the port is enabled: ufw status\e[0m" + echo -e "\e[1;33m 2.If the firewall status is inactive, the tool can be accessed. Otherwise, run the following command:\e[0m" + echo -e "\e[1;33m 3.Enable the web service port: ufw allow ${port}/tcp\e[0m" +} + +# 执行删除devkit用户操作 +function delete_devkit_user(){ + del_sudoers_name="devkit" + if grep -E "^${del_sudoers_name}:" /etc/passwd; then + if [[ "${package_tool}" == "yum" ]];then + userdel -rf ${del_sudoers_name} + elif [[ "${package_tool}" == "zypper" ]]; then + userdel -rf ${del_sudoers_name} + groupdel ${del_sudoers_name} + elif [[ "${package_tool}" == "apt" ]] ; then + rmuser -h >/dev/null 2>&1 + if [ 0 == $? ]; then + rmuser ${del_sudoers_name} -rf + else + userdel -rf ${del_sudoers_name} + fi + else + deluser -q ${del_sudoers_name} + fi + fi +} + +# 准备检查结果和建议数组 +function prepare_check_result(){ + source $CURRENT_DIR/const.sh + if [[ ${install_user_is_root} == 1 ]];then + CheckResult[0]="fail" + Suggestion[0]=${install_user_not_root[1]} + else + CheckResult[0]='ok' + Suggestion[0]=${install_user_is_root[1]} + fi + if [[ ${sudo_has_s_permission} == 1 ]];then + CheckResult[1]="fail" + Suggestion[1]=${sudo_s_fail_info[1]} + else + CheckResult[1]='ok' + Suggestion[1]=${sudo_s_success_info[1]} + fi + if [[ ${su_has_s_permission} == 1 ]];then + CheckResult[2]="fail" + Suggestion[2]=${su_s_fail_info[1]} + else + CheckResult[2]='ok' + Suggestion[2]=${su_s_success_info[1]} + fi + if [[ ${pam_rootok_config_status} == 1 ]];then + CheckResult[3]="fail" + Suggestion[3]=${pam_rootok_fail_info[1]} + else + CheckResult[3]='ok' + Suggestion[3]=${pam_rootok_success_info[1]} + fi + if [[ ${sudoers_devkit_file_exists} == "1" ]]; then + if [[ ${sudoers_devkit_config_exists} == "0" ]]; then + CheckResult[4]="fail" + Suggestion[4]=${sudoers_status_fail_sudoers_dir_config[1]} + else + CheckResult[4]="fail" + Suggestion[4]=${sudoers_status_fail_devkit_sudoers[1]} + fi + elif [[ ${sudoers_devkit_file_exists} == "2" ]]; then + if [[ ${sudoers_devkit_config_exists} == "0" ]]; then + CheckResult[4]="fail" + Suggestion[4]=${sudoers_status_fail_devkit_sudoers_config[1]} + else + CheckResult[4]="fail" + Suggestion[4]=${sudoers_status_fail_sudoers_dir[1]} + fi + else + if [[ ${sudoers_devkit_config_exists} == "0" ]]; then + CheckResult[4]="fail" + Suggestion[4]=${sudoers_status_fail_sudoers_config[1]} + else + CheckResult[4]="ok" + Suggestion[4]=${sudoers_status_success_info[1]} + fi + fi + if [[ "${status_of_user_status}" == "1" ]]; then + CheckResult[5]="fail" + Suggestion[5]=${user_fail_info[1]} + else + CheckResult[5]="ok" + Suggestion[5]=${user_success_info[1]} + fi + + if [[ "$status_of_service_config" == "1" ]]; then + CheckResult[6]="fail" + Suggestion[6]=${service_file_fail_info[1]} + else + CheckResult[6]="ok" + Suggestion[6]=${service_file_success_info[1]} + fi + + if [[ "$status_of_install_folders" == "1" ]]; then + CheckResult[7]="fail" + Suggestion[7]=${install_path_fail_info[1]} + else + CheckResult[7]="ok" + Suggestion[7]=${install_path_success_info[1]} + fi + + if [[ "$status_of_user_home" == "1" ]]; then + CheckResult[8]="fail" + Suggestion[8]=${user_home_fail_info[1]} + else + CheckResult[8]="ok" + Suggestion[8]=${user_home_success_info[1]} + fi + + if [[ ${#all_need_install_lib[@]} -eq 0 ]];then + framework_dependencies_status=0 + CheckResult[9]="ok" + Suggestion[9]="N/A" + else + framework_dependencies_status=1 + CheckResult[9]="fail" + Suggestion[9]="The following mandatory component is not installed:${essential_need_install_lib_print[*]}" + fi + CheckResult[10]="ok" + Suggestion[10]=${user_devkitworker_info[1]} + +} + +# 检查devkit是否已安装 +function check_already_installed() { + # 检查安装配置文件是否存在 + # 判断用户家目录是否为/home + status_of_install_folders=0 + if [[ -f "${DEVKIT_CONF}"/"${INSTALL_INI}" ]];then + old_install_path=$(grep -w INSTALL_PATH "${DEVKIT_CONF}/${INSTALL_INI}" | awk -F= '{if($2 !="") print $2}') + if [[ -n "${old_install_path}" ]] && [[ -f "${old_install_path}/DevKit/config/${INSTALL_INI}" ]]; then + status_of_install_folders=1 + echo_and_log "DevKit has been installed in the ${old_install_path}/DevKit directory." "${ECHO}" "${INSTALL_LOG}" + fi + else + echo_and_log "DevKit is not installed, continue" "${ECHO}" "${INSTALL_LOG}" + fi +} + +# 检查是否有安装残留并清理 +function clean_residue() { + echo_and_log "Clean residue" "${ECHO}" "${INSTALL_LOG}" + # 清理用户仍存在、安装目录有残留、服务有残留的情况 + rm_rf "${CURRENT_DIR}/devkitFramework" + rm_rf "${CURRENT_DIR}/portal" + rm_rf "${CURRENT_DIR}/toolkit" + # 服务终止 删除服务文件 + stop_services + del_file_chattr "del" "${install_path}" + # 清理端口 + close_opened_ports "${install_ini}" "${INSTALL_LOG}" + # 删除安装目录 + init_env_common 'install' + # 删除devkitworker用户 + delete_multi_user + # 删除用户 + delete_devkit_user + # sudo提权的文件 + clean_sudoers_config "${install_ini}" + if [[ ${vscode_devkit_tag} == 1 ]]; then + sleep 2 + rm_rf ${record_file_path} + fi + echo_and_log "Clean residue success" "${SUCCESS}" "${INSTALL_LOG}" +} + +function clean_sudoers_config() { + # 删除配置文件 + local config_path="$1" + [[ -f "/etc/sudoers.d/devkit_sudoers" ]] && rm -rf "/etc/sudoers.d/devkit_sudoers" + # 删除/存放到系统目录下的脚本或者文件 + [[ -d "/usr/bin/devkit_tools" ]] && rm -rf "/usr/bin/devkit_tools" + [[ -d "/usr/bin/devkit" ]] && rm -rf "/usr/bin/devkit" + # 循环检查已经安装插件是否有sudoers文件 + install_plugins_record=$(grep -w INSTALL_TOOL ${config_path} | awk -F "=" '{print $2}') + for plugin_name in $(echo ${install_plugins_record} | tr "," " ") + do + plugin_name=${plugin_name##devkit.} + if [ -f "/etc/sudoers.d/devkit_${plugin_name}_sudoers" ]; then + rm -rf "/etc/sudoers.d/devkit_${plugin_name}_sudoers" + fi + done +} + +function add_installed_record() { + # 修改配置文件插件记录状态 + local config_path="$1" + local plugin_name="$2" + # 获取已有记录 + local install_plugins_record=$(grep -w INSTALL_TOOL ${config_path} | awk -F "=" '{print $2}') + # 在最后追加 + if [[ ${install_plugins_record} == "framework" ]]; then + sed_ini "${config_path}" "INSTALL_TOOL=" "INSTALL_TOOL=devkit.${plugin_name}" + sed_ini "${config_path}" "OLD_INSTALL_TOOL=" "OLD_INSTALL_TOOL=devkit.${plugin_name}" + else + if [[ ! ${install_plugins_record} =~ ${plugin_name} ]]; then + sed_ini "${config_path}" "INSTALL_TOOL=" "INSTALL_TOOL=${install_plugins_record},devkit.${plugin_name}" + sed_ini "${config_path}" "OLD_INSTALL_TOOL=" "OLD_INSTALL_TOOL=${install_plugins_record},devkit.${plugin_name}" + fi + fi +} + +function delete_uninstalled_record() { + local config_path="$1" + local plugin_name="$2" + # 删除记录中的插件信息 + plugins_end=$(cat ${config_path} | grep "\, \"devkit.${plugin_name}\"") # 软件在最后 + plugins_start=$(cat ${config_path} | grep "\"devkit.${plugin_name}\"\, ") # 软件在中间或者开头 + plugins_only=$(cat ${config_path} | grep "\"devkit.${plugin_name}\"") # 只有一个软件 + if [[ ${plugins_end} ]]; then + sed -i "s/, \"devkit.${plugin_name}\"//g" ${log_level_update_flag} + elif [[ ${plugins_start} ]]; then + sed -i "s/\"devkit.${plugin_name}\", //g" ${log_level_update_flag} + elif [[ ${plugins_only} ]]; then + sed -i "s/\"devkit.${plugin_name}\"//g" ${log_level_update_flag} + fi +} + +function add_devkit_sudo_log(){ + sudo_file="/etc/sudoers.d/devkit_sudoers" + if grep "Defaults logfile=/var/log/sudo.log" "$sudo_file" + then + echo_and_log "sudo.log conf is already in the ${USER_NAME} sudoers." "${DOING}" ${INSTALL_LOG} + else + sed -i '$a'" Defaults logfile=/var/log/sudo.log #${USER_NAME}" "$sudo_file" + fi +} + +function add_devkit_sudo() +{ + local command="$1" + local command_path="$2" + local install_log="$3" + sudo_file="/etc/sudoers.d/devkit_sudoers" + if [ ! -f "${sudo_file}" ]; then + touch $sudo_file + fi + chmod 440 ${sudo_file} + # 跳过空提权命令 + if [ -z "${command}" ]; then + echo_and_log "Empty command, skip" "${DOING}" "${install_log}" + return + fi + # 跳过不存在的提权命令 + if [ ! -e "${command}" ]; then + echo_and_log "Not exits command, skip: ${command}" "${DOING}" "${install_log}" + return + fi + if grep "${USER_NAME} ALL=(root) NOPASSWD:${command_path}" "$sudo_file" + then + echo_and_log "${command} is already in the ${USER_NAME} sudoer list." "${DOING}" ${install_log} + else + # 空文件sed 追加不进去 sed 根据行号追加内容 + echo "${USER_NAME} ALL=(root) NOPASSWD:""${command_path}" >> "$sudo_file" + fi +} + +function add_devkit_sudo_list(){ + + parameter_list=( + "${install_path}/DevKit/tools/install_devkit_plugin.sh" + "${install_path}/DevKit/tools/uninstall_devkit_plugin.sh" + "${install_path}/DevKit/tools/upgrade_devkit_plugin.sh" + "${install_path}/DevKit/tools/docker_service.sh" + "${install_path}/DevKit/tools/build_agent_plugins.sh" + "$(which systemctl 2>/dev/null) restart gunicorn_plugin.service" + "$(which systemctl 2>/dev/null) restart gunicorn_framework.service" + "$(which systemctl 2>/dev/null) restart devkit_nginx.service" + ) + if [[ "${architecture}" == "aarch64" ]]; then + # 提权脚本 + local perf_path=$(which perf 2>/dev/null) + local lspci_path=$(which lspci 2>/dev/null) + local numastat_path=$(which numastat 2>/dev/null) + parameter_list+=( + "${DEVKIT_TOOL_PATH}/check_app_auth_diagnose.sh *" + "${DEVKIT_TOOL_PATH}/kill_process.sh *" + "${DEVKIT_TOOL_PATH}/launch_app_diagnose.sh *" + "${DEVKIT_TOOL_PATH}/set_env.sh *" + "${DEVKIT_TOOL_PATH}/pidstat.sh *" + "${DEVKIT_TOOL_PATH}/perf record *" + "${DEVKIT_TOOL_PATH}/perf_archive" + "${DEVKIT_TOOL_PATH}/directory_retrieval" + "${DEVKIT_TOOL_PATH}/perf buildid-cache *" + "${perf_path} script *" + "${lspci_path}" + "${numastat_path}" + ) + fi + parameter_list_len=${#parameter_list[@]} + for ((i=0;i<${parameter_list_len};i++)); do + local parameter=${parameter_list[i]} + local cmd_name=$(echo ${parameter} | cut -d " " -f 1) + add_devkit_sudo "${cmd_name}" "${parameter}" "${INSTALL_LOG}" + done +} + +function create_multi_user(){ + # 创建多用户之前先删除残留devkitworker + local worker_json_path=${CURRENT_DIR}/portal/devkitframework/user/worker.json + local install_ini="${CURRENT_DIR}/${INSTALL_INI}" + delete_multi_user + # 添加多用户 + while true; do + j=1 + echo_and_log '\nStart to create multiple users.' ${ECHO} + for (( i = 1; i < 11; i++ )); do + useradd -MN -g devkit devkitworker${j} -c "devkit_advisor_user" -s /sbin/nologin >/dev/null 2>&1 + local status_code=$? + if [[ "$status_code" == "0" ]]; then + # 创建的用户信息写入worker.json + uid=$(id -u devkitworker${j}) + sed -i "s/\"uid${i}\"/${uid}/g" ${worker_json_path} + sed -i "s/\"worker_name${i}\"/\"devkitworker${j}\"/g" ${worker_json_path} + echo_and_log "devkitworker${j} is created successfully." ${SUCCESS} ${INSTALL_LOG} + if [ ${i} == 1 ]; then + sed_ini "${install_ini}" "HYPER_WORKER=" "HYPER_WORKER=devkitworker${j}" + # 创建家目录 + mkdir -p ${USER_HOME}/devkitworker${j} + chown devkit:devkit ${USER_HOME}/devkitworker${j} + chmod 700 ${USER_HOME}/devkitworker${j} + sed_ini "${install_ini}" "HYPER_WORKER_HOME=" "HYPER_WORKER_HOME=${USER_HOME}/devkitworker${j}" + fi + ((j++)) + elif [[ "$status_code" == "9" ]]; then + # 已经存在了该用户 + ((j++)) + ((i--)) + continue + else + delete_multi_user + exit 1 + fi + done + break + done +} + +function delete_multi_user(){ + # 卸载的时候删除创建的用户 + user_list=$(cat /etc/passwd | grep -E "^devkitworker" |grep "devkit_advisor_user" | awk -F ":" '{print $1}') + # 用户非正常操作剩余的portwork用户 + if [[ "${user_list}" ]]; then + for user in ${user_list[@]}; do + if [[ "${user}" == "devkit" ]]; then + continue + else + if [[ "${package_tool}" == "yum" ]];then + userdel -rf ${user} >/dev/null 2>&1 + elif [[ "${package_tool}" == "zypper" ]]; then + userdel -rf ${user} >/dev/null 2>&1 + elif [[ "${package_tool}" == "apt" ]] ; then + rmuser -h >/dev/null 2>&1 + if [ 0 == $? ]; then + rmuser ${user} -rf >/dev/null 2>&1 + else + userdel -rf ${user} >/dev/null 2>&1 + fi + else + deluser -q ${user} >/dev/null 2>&1 + fi + # userdel 删除用户删除mail下的内容导致创建同名用户报异常 + rm_rf "/var/spool/mail/${user}" + fi + done + fi +} + +# 复写文件函数 +function erasing_file() +{ + local eras_path=$1 + local counts=1 + shift 1 + eras_file=($(echo "$@")) + if [ -d "${eras_path}" ]; then + for file in ${eras_file[@]} + do + # 文件校验 + if [ ! -f "${eras_path}/${file}" ]; then + echo_and_log "${eras_path}/${file} does not exist!" "${ERROR}" + continue + fi + # 获取文件占用空间大小并校验 + counts=$((10#$(du -k "${eras_path}/${file}" | awk '{if($1 !="") print $1}')*2)) + if [ -z "${counts}" ]; then + echo_and_log "Get ${eras_path}/${file} space failed!" "${ERROR}" + continue + fi + if [ "${counts}" -gt 1000 ] || [ "${counts}" -lt 1 ]; then + echo_and_log "Get ${eras_path}/${file} space ${counts}K out of range(1-1000K)!" "${ERROR}" + continue + fi + # 0擦除 + dd if=/dev/zero of="${eras_path}/${file}" bs=512 count=${counts} >> /dev/null 2>&1 + if [ "$?" -ne "${SUCCESS}" ]; then + echo_and_log "replicate 0 failed" "${ERROR}" + exit ${ERROR} + fi + # 1擦除 + cat /dev/zero | tr '\0' '\377' | dd of="${eras_path}/${file}" bs=512 count=${counts} >> /dev/null 2>&1 + if [ "$?" -ne "${SUCCESS}" ]; then + echo_and_log "replicate 1 failed" "${ERROR}" + exit ${ERROR} + fi + # 安全随机数擦除 + openssl rand 512 | dd of="${eras_path}/${file}" bs=512 count=${counts} >> /dev/null 2>&1 + if [ "$?" -ne "${SUCCESS}" ]; then + echo_and_log "replicate random number failed" "${ERROR}" + exit ${ERROR} + fi + # 删除文件 + if [ -f "${eras_path}/${file}" -o -d "${eras_path}/${file}" ];then + rm_rf "${eras_path}/${file}" + fi + if [ "$?" -ne "${SUCCESS}" ]; then + echo_and_log "delete ${eras_path} file failed" "${ERROR}" + exit ${ERROR} + fi + done + else + echo_and_log "${eras_path} does not exist!" "${ERROR}" + fi +} + +function delete_rsa_file() +{ + local install_path="$1" + # 删除nginx使用的rsa,并重写0、1和随机值 + local rsa_file=(server.crt server.csr pontus dhparam.pem ca.crt) + erasing_file "${install_path}/DevKit/rsa" ${rsa_file[@]} + echo_and_log "delete web ssl service certificates success" "${SUCCESS}" +} + +# 安装失败清理环境 或者初始化环境 +function init_env_common(){ + # 清理有修改过用户 + local deal_type="$1" + if [[ "${deal_type}" != "install" ]]; then + local install_path=${old_install_path:=${install_path}} + fi + # recover_mount + # 清理证书内容 + delete_rsa_file ${install_path} + + # 工具安装时添加的配置,卸载时删掉 + if [[ "${sudoers_devkit_config_exists}" == "1" ]]; then + sed -i "/^#includedir \/etc\/sudoers.d$/d" /etc/sudoers + fi + # 清除工具添加的devkit_sudoers文件 + if [ -f "/etc/sudoers.d/devkit_sudoers" ];then + rm -f /etc/sudoers.d/devkit_sudoers + fi + # 安装了老版本重复安装新版本要把老版本的清理掉 + tool_user="devkit" + sed -i "/^[[:space:]]*${tool_user} /d" /etc/sudoers + sed -i "/Defaults logfile=\/var\/log\/sudo.log #${tool_user}/d" /etc/sudoers + del_file_chattr "del" "${install_path}" + rm_rf ${install_path}/DevKit + # 删除升级多出的备份文件 + rm_rf ${install_path}/devkitadvisor + if [[ "${deal_type}" == "install" ]]; then + echo "Environment cleanup completion phase:Clearable=False" >> ${INSTALL_LOG} + fi +} + +# 打印安装脚本的使用方式 +function print_install_usage() +{ + choose_all_plugin + echo "Usage: DevKit install [OPTION]..." + echo "Set installation configuration information." + + echo -e "\nInstall path:" + printf "%-40s%-15s\n" " -d=Directory, --dir=Directory" "Set the installation path, which defaults to /opt." + + echo -e "\nInstall type:" + printf "%-40s%-15s\n" " -l" "Check dependencies before installation." + printf "%-40s%-15s\n" " --framework" "Install the framework, default" + printf "%-40s%-15s\n" " --plugin=Plugin Name" "Install the framework with assigned plugins, eg. (--plugin=porting [,devtools])" + printf "%-40s%-15s\n" " " "The plug-ins that can be installed are as follows:${install_tool}" + printf "%-40s%-15s\n" " -a, --all" "Install the framework with all plugins." + printf "%-40s%-15s\n" " --normal-install" "Install the tool in normal mode instead of using SSO." + + echo -e "\nServer IP:" + printf "%-40s%-15s\n" " --ip=Server IP" "Set the server IP to which the client needs to connect." + + echo -e "\nServer Port:" + printf "%-40s%-15s\n" " -p=Port, --port=Port" "Set the server port to which the client needs to connect. The default port is 8086." + + echo -e "\nServer Http Port:" + printf "%-40s%-15s\n" " --http_port=HTTP Port" "Set the server HTTP port to which the client needs to connect. The default port is 8002." + + if [[ "${architecture}" == "aarch64" ]]; then + echo -e "\nRpc Server Port:" + printf "%-40s%-15s\n" " --rpc_port=RPC cluster server port" "Set the RPC cluster server port. The default port is 50051." + fi +} + +# 展示最终安装完成信息 +function displaying_installed_msg() { + # 展示信息 + for ((i=0;i<${#record_install_plugin_status[@]};i++)); do + local plugin_name=$(echo ${record_install_plugin_status[$i]} | awk -F "-&-" '{print $1}') + local install_status=$(echo ${record_install_plugin_status[$i]} | awk -F "-&-" '{print $2}') + if [[ "${install_status}" == "success" ]]; then + echo_and_log "The ${plugin_name} plugin is successfully installed in the $install_path/DevKit/devkitplugins/${plugin_name} directory." "${SUCCESS}" "${INSTALL_LOG}" + else + echo_and_log "Failed to install the ${plugin_name} plugin. The $install_path/DevKit/devkitplugins/${plugin_name} directory has been cleared." "${ERROR}" "${INSTALL_LOG}" + fi + done + echo_and_log "The Kunpeng Devkit Advisor is successfully installed in the ${install_path}/DevKit directory." "${SUCCESS}" "${INSTALL_LOG}" + echo_and_log "The Devkit Web console is running. Visit https://${nginx_ip}:${nginx_port}" "${SUCCESS}" "${INSTALL_LOG}" + echo_and_log "If ${nginx_ip}:${nginx_port} has mapping IP, please use the mapping IP." "${SUCCESS}" "${INSTALL_LOG}" +} + +# 展示安装信息 +function show_install_msg() { + local platform=$(uname -m) + # 展示信息 + local tool_version=$1 # 安装的版本 + local instlal_type=$2 # 安装调用为install 升级为upgrade + if [[ "$instlal_type" == 'upgrade' ]]; then + local old_install_tool=$3 # 老的工具 (升级时显示) + fi + echo_and_log "\nThe following parameters will be used for deployment:" ${ECHO} "${INSTALL_LOG}" + echo_and_log "++++++++++++++++++++++++++++++++++++++++++++++++ " ${ECHO} "${INSTALL_LOG}" + echo_and_log "OS_TYPE : ${os_type}" ${ECHO} "${INSTALL_LOG}" + echo_and_log "TOOL_VERSION : $tool_version" ${ECHO} "${INSTALL_LOG}" + echo_and_log "INSTALL_TOOL : ${install_tool}" ${ECHO} "${INSTALL_LOG}" + if [[ "$instlal_type" == 'upgrade' ]]; then + echo_and_log "OLD_TOOL_VERSION : $old_install_tool" ${ECHO} "${INSTALL_LOG}" + fi + echo_and_log "INSTALL_PATH : ${install_path}" ${ECHO} "${INSTALL_LOG}" + echo_and_log "NGINX_IP : ${nginx_ip}" ${ECHO} "${INSTALL_LOG}" + echo_and_log "NGINX_PORT : ${nginx_port} " ${ECHO} "${INSTALL_LOG}" + echo_and_log "PLUGIN_GUNICORN_PORT : ${plugin_gunicorn_port} " ${ECHO} "${INSTALL_LOG}" + if [[ ${platform} == "aarch64" ]]; then + echo_and_log "GRPC_SERVER_IP : ${grpc_server_ip} " ${ECHO} "${INSTALL_LOG}" + echo_and_log "GRPC_LISTEN_PORT : ${grpc_listen_port} " ${ECHO} "${INSTALL_LOG}" + fi + echo_and_log "HTTP_LISTEN_PORT : ${http_listen_port} " ${ECHO} "${INSTALL_LOG}" + echo_and_log "++++++++++++++++++++++++++++++++++++++++++++++++ " ${ECHO} "${INSTALL_LOG}" +} + +# 本函数用于检查参数是否被多次赋值:is_empty [value] [value_type] +function is_empty() +{ + local value=$1 + local value_type=$2 + if [ -n "${value}" ]; then + echo_and_log "Parameter error: ${value_type} is assigned multiple times." "${ERROR}" + print_install_usage + exit "${SUCCESS}" + fi +} + +# 检查SSO登录参数 +function check_sso_legitimate() { + if [ -z "${sso_flag}" ]; then + echo_and_log "DevKit_params:normal-install parameter value is empty" "${ERROR}" + exit "${SUCCESS}" + fi + + if [[ "${sso_flag}" == "1" ]] || [[ "${sso_flag}" == "2" ]]; then + return + else + echo_and_log "DevKit_params:normal-install parameter error." "${ERROR}" + echo_and_log "The value of normal-install can only be 1 or 2. 1: indicates the access mode based on the user name and password. 2: OAuth 2.0 SSO mode" "${ERROR}" + exit "${SUCCESS}" + fi + +} + +# 用户选择了所有的插件 +function choose_all_plugin() { + install_tool=$(echo ${plugins_support_list[@]} | tr ' ' ',') + if [[ ${architecture} != "aarch64" ]]; then + install_tool=${install_tool%,debugger,sys_perf,java_perf*} + install_tool=$(echo $install_tool | awk -F ",affinity" '{print $1$2}') + else + if [[ ${env_type} == 0 ]]; then + install_tool=$(echo $install_tool | awk -F ",affinity" '{print $1$2}') + fi + fi +} + +# 检查用户选择插件是否重复 +function check_plugin_same() { + local install_plugins="$1" + # 切割去重,判断数量 如果数量变小提示有重复 + no_sort_unique=$(echo ${install_plugins} | tr "," " " | xargs -n 1 | wc -l) + sort_unique=$(echo ${install_plugins} | tr "," " " | xargs -n 1 | sort -u| wc -l) + if [ ${sort_unique} -lt ${no_sort_unique} ]; then + echo_and_log "DevKit_params:Repeatedly select the plug-in for installation." "${ERROR}" + exit "${SUCCESS}" + fi +} + +function choose_plugin_invalid_tip() { + # 参数方式安装插件选择不合法提示 + echo_and_log "DevKit_params: The ${plugin_name} plug-in cannot be installed, Check whether the ${plugin_name} plug-in name is incorrectly spelled or the service platform is incompatible. " "${ERROR}" + check_architecture + choose_all_plugin + echo_and_log "Plug-ins that can be installed:${install_tool}" "${SUCCESS}" + exit "${SUCCESS}" +} + +# 检查用户输入的脚本 +function check_plugin_legitimate() { + if [ -z "${install_tool}" ]; then + echo_and_log "DevKit_params:plugin parameter value is empty" "${ERROR}" + exit "${SUCCESS}" + fi + check_plugin_same ${install_tool} + for plugin_name in $(echo ${install_tool} | tr "," " ") + do + plugin_name=${plugin_name##devkit.} + + if [[ ! ${plugins_support_list[@]} =~ ${plugin_name} ]]; then + choose_plugin_invalid_tip + else + flag=0 + for support_name in ${plugins_support_list[@]} + do + if [[ ${support_name} == ${plugin_name} ]]; then + flag=1 + fi + done + if [[ ${flag} != 1 ]] || [[ ${env_type} == 0 && ${plugin_name} == "affinity" ]]; then + choose_plugin_invalid_tip + fi + fi + done +} + +# 版本比较:version_lt [result_version] [standard_version] +function version_lt() +{ + test "$(echo "$@" | tr " " "\n" | sort -rV | head -n 1)" != "$1"; +} + +# 展示环境IP +function show_ip_address() +{ + host_name=$(hostname -I) + num=1 + temp_string="" + ip_array=() + + echo "IP address list:" + printf " %-20s %-20s %-20s\n" sequence_number ip_address device + for ip in ${host_name} + do + nic_name=$(ip addr show to ${ip} |awk -F ":" '{print$2}' |awk '{print$1}' |awk 'NR==1') + sequence_number="[${num}]" + printf " %-20s %-20s %-20s\n" "${sequence_number}" "${ip}" "${nic_name}" + ip_array[${num}-1]=${ip} + let num++ + done + len_num=${#ip_array[@]} +} + +# 获取环境网口数量(可用ip数量) +function get_legality_ip_quantity () { + local ip_list=($(hostname -I)) + local ip_num=${#ip_list[@]} + if [ ${ip_num} -eq 1 ]; then + GLOBAL_IP="${ip_list[0]}" + fi +} + +# 创建用户 +function create_user() +{ + local common_install_user=$1 + local user_path="${USER_HOME}/${common_install_user}" + local user_exist=$(grep -w "${common_install_user}" "${OS_PASSWD}") + local ssh_dir="${user_path}/.ssh" + if [[ "${package_tool}" == "apt" ]] || [[ "${package_tool}" == "zypper" ]]; then + groupadd "${common_install_user}" + useradd "${common_install_user}" -d "${user_path}" -g "${common_install_user}" -m + elif [[ "${package_tool}" == "yum" ]]; then + useradd "${common_install_user}" + else + echo_and_log "Not supported OS type:${os_type}!" "${ERROR}" + exit "${ERROR}" + fi + if [ "${SUCCESS}" == "$?" ]; then + force_mk_dir "${DEVKIT_CONF}" + force_mk_dir "${ssh_dir}" + chown ${USER_NAME}:${USER_NAME} "${ssh_dir}" + chmod 700 "${user_path}" "${ssh_dir}" + chmod 700 "${user_path}/devkit_conf" + else + if [ "${os_type}" == "SLESOS" ]; then + userdel -f "${common_install_user}" + groupdel "${common_install_user}" + elif [[ "${package_tool}" == "yum" ]]; then + userdel -f "${common_install_user}" + else + userdel "${common_install_user}" + fi + if [ -d "${user_path}" ]; then + rm_rf "${user_path}" + fi + echo_and_log "Add user failed!" "${ERROR}" + exit "${ERROR}" + fi + #锁定创建用户的账号,禁止登陆 + set_user_passwd "${PASSWD_NOLOGIN}" "${common_install_user}" + passwd -l "${common_install_user}" + # 节点安装无该步骤 + if [[ -f "${current_dir}/sso_register.sh" ]]; then + sed -i "s#sso_user_path#${USER_HOME}\/devkit#" "${current_dir}/sso_register.sh" + fi +} + +# get & set user passwd info +function set_user_passwd() { + local passwd_type=$1 + local user=$2 + local user_passwd_info=$(grep -w "${user}" "${OS_PASSWD}") + # user不存在时直接返回 + if [[ -z "${user_passwd_info}" ]]; then + return "${SUCCESS}" + fi + if [[ -n "${os_type}" ]]; then + if [[ "${package_tool}" == "apt" ]]; then + if [[ "${passwd_type}" == "/sbin/nologin" ]]; then + passwd_type="/usr/sbin/nologin" + fi + fi + fi + + usermod -s ${passwd_type} "${user}" >> /dev/null 2>&1 + if [[ "$?" != "${SUCCESS}" ]]; then + echo_and_log "usermod -s ${passwd_type} ${user} failed!" "${ERROR}" + exit "${ERROR}" + fi +} + +function su_user_cert() +{ + local cmd=$1 + local passwd=$2 + local os_type=$3 + local user=$4 + user=${user:="devkit"} + su - "${user}" -s /bin/bash -c "${cmd} <<<${passwd}" + if [ "$?" != "${SUCCESS}" ]; then + echo_and_log "su_user:execute ${cmd} failed!" "${ERROR}" + exit "${ERROR}" + fi +} + +function su_user() +{ + local cmd=$1 + local os_type=$2 + local user=$3 + user=${user:="devkit"} + su - "${user}" -s /bin/bash -c "${cmd}" + if [ "$?" != "${SUCCESS}" ]; then + echo_and_log "su_user:execute ${cmd} failed!" "${ERROR}" + exit "${ERROR}" + fi +} + +function has_root(){ + # 判断用户是否 + install_user_not_root=0 + if [[ $UID -ne 0 ]]; then + install_user_not_root=1 + return_install_info "$1" "Error" "End" "devkit" + return_install_info "$1" "Deployment_End" "failed" "Deployment_End" + fi +} + +# 设置用户环境变量 +function configure_user_env() +{ + local user=$1 + local user_path="${USER_HOME}/${user}" + local env_file="" + echo_and_log "\nDeal ${user} user env" "${ECHO}" + if [[ -f "${USER_HOME}/${user}/.bash_profile" ]]; then + env_file="${user_path}/.bash_profile" + elif [[ -f "${user_path}/.profile" ]]; then + env_file="${user_path}/.profile" + else + echo_and_log "deal_env:env_file is not exist" "${ERROR}" + exit "${ERROR}" + fi + su_user "sed -i -e '/umask/d' '${env_file}'" "${os_type}" "${user}" + su_user "echo 'umask 077' >> '${env_file}'" "${os_type}" "${user}" + su_user "sed -i -e '/export/d' '${env_file}'" "${os_type}" "${user}" + # 设置用户umask值 + local path="${install_path}/DevKit/tools/python_venv/bin:${install_path}/DevKit/tools/nginx/sbin" + local ld_lib_path="${user_path}/libssl:${user_path}/libsqlite3:${user_path}/lib" + local rpc_server_lib_path="${install_path}/DevKit/tools/rpc_cluster/server/lib" + su_user "echo 'export PATH=${path}:\$PATH:\$HOME/.local/bin:\$HOME/bin' >> '${env_file}'" "${os_type}" "${user}" + su_user "echo 'export LD_LIBRARY_PATH=${ld_lib_path}:${rpc_server_lib_path}:\$LD_LIBRARY_PATH' >> '${env_file}'" "${os_type}" "${user}" + echo_and_log "The environment of the devkit user is configured successfully." "${SUCCESS}" +} + +# 判断是否危险路径,防止误删除 +function danger_path() { + local path=$1 + path=$(realpath "${path}") + if [[ "${path}" == "/" ]] || [[ "${path}" == "/bin" ]] || [[ "${path}" == "/boot" ]] || [[ "${path}" == "/dev" ]] || [[ "${path}" == "/home" ]] || [[ "${path}" == "/lib" ]] || [[ "${path}" == "/lib64" ]] || [[ "${path}" == "/root" ]] || [[ "${path}" == "/proc" ]]; then + echo_and_log "Danger operation: Deleting the ${path} path is forbidden." "${ERROR}" + return "${ERROR}" + fi + return "${SUCCESS}" +} + +function rm_rf() +{ + local source=$1 + source=$(realpath "${source}") + if [[ -f "${source}" || -d "${source}" ]];then + danger_path "${source}" + if [[ "$?" == "${ERROR}" ]]; then + echo_and_log "Danger operation: Deleting the ${source} path is forbidden." "${ERROR}" + exit "${ERROR}" + fi + rm -rf "${source}" + if [[ "$?" -ne "${SUCCESS}" ]];then + echo_and_log "rm_rf: remove ${source} failed." "${ERROR}" + exit "${ERROR}" + fi + fi +} + +# 强制创建目录,若存在则先删除 +function force_mk_dir() +{ + local dir=$1 + if [ -d "${dir}" ]; then + rm_rf "${dir}" + fi + mkdir -p "${dir}" +} + +function cp_rf() +{ + local source=$1 + local aims=$2 + cp -rf ${source} ${aims} + if [ "$?" -ne "${SUCCESS}" ]; then + echo_and_log "cp_rf: copy ${source} to ${aims} failed." "${ERROR}" + exit ${ERROR} + fi +} + +function check_service_status() { + local mode=$1 + local is_exist=1 + local raw_ps_info=$(ps -fu devkit | grep nginx | grep worker) + local pid_list=$(echo "${raw_ps_info}" | awk '{print $2}') + local ppid_list=$(echo "${raw_ps_info}" | awk '{print $3}') + local nginx_master_exist="" + local nginx_master_pid="" + for ppid in $ppid_list + do + nginx_master_exist=$(ps -ef -q ${ppid} | grep tools/nginx/sbin/nginx) + if [ -n "${nginx_master_exist}" ]; then + nginx_master_pid=${ppid} + break + fi + done + if [ "${mode}" == "check_mode" ]; then + if [ -z "${nginx_master_pid}" ]; then + is_exist=0 + fi + echo ${is_exist} + elif [ "${mode}" == "kill_mode" ]; then + if [ -z "${nginx_master_pid}" ]; then + return + fi + kill -SIGKILL ${nginx_master_pid} ${pid_list} + fi +} + +function change_nginx_pid_permission(){ + local install_ini="${CURRENT_DIR}/${INSTALL_INI}" + local install_path="" + local time=0 + if [ ! -f "${install_ini}" ];then + echo_and_log "${install_ini} is not exist,get config failed" "${ERROR}" + exit ${ERROR} + fi + install_path=$(grep -w INSTALL_PATH ${install_ini} | awk -F= '{if($2 !="") print $2}') + local nginx_pid_path="${install_path}/tools/nginx/nginx.pid" + + while (( ${time}<10 )) + do + if [ -f "${nginx_pid_path}" ]; then + chmod 600 ${nginx_pid_path} + chown devkit:devkit ${nginx_pid_path} + break + fi + sleep 1s + let "time++" + done +} + +function call_service_start() { + local name=$1 + local is_active="" + local time=0 + local max_time=60 + if [ "${name}" == "devkit_nginx" ]; then + local is_exist=$(check_service_status "check_mode") + if [ "${is_exist}" == "1" ]; then + return + fi + fi + systemctl enable ${name}.service + if [ "$?" != "${SUCCESS}" ]; then + echo_and_log "enable ${name}.service failed" "${ERROR}" + exit ${ERROR} + fi + systemctl daemon-reload + if [ "$?" != "${SUCCESS}" ]; then + echo_and_log "daemon-reload failed" "${ERROR}" + exit ${ERROR} + fi + systemctl start ${name}.service + if [ "$?" != "${SUCCESS}" ]; then + echo_and_log "start ${name}.service failed" "${ERROR}" + exit ${ERROR} + else + while (( ${time}<${max_time} )) + do + if [ "${name}" == "devkit_nginx" ]; then + is_active=$(check_service_status "check_mode") + if [ "${is_active}" == "1" ]; then + change_nginx_pid_permission + break + fi + else + is_active=$(systemctl status ${name}.service | grep "Active" | awk '{print $2}') + if [ "${is_active}" == "active" ]; then + break + fi + fi + sleep 1s + let "time++" + done + fi +} + +# 检查是否为系统路径 +function check_path_is_system() { + # 判断输入的路径是否为系统路径 + local input_path="$1" + for bad_path in ${NOT_ALLOW_PATH[@]} + do + if [ "/" == "${input_path}" ]; then + echo_and_log "The following directories are not allowed: ${NOT_ALLOW_PATH_SORT}." ${ERROR} ${INSTALL_LOG} + return 1 + fi + + if [[ "/${bad_path}" == "${input_path}" ]];then + echo_and_log "The following directories are not allowed: ${NOT_ALLOW_PATH_SORT}." ${ERROR} ${INSTALL_LOG} + return 1 + else + local split_path=($(echo "${input_path}" | tr '/' ' ')) + first_path=${split_path[0]} + if [[ "${bad_path}" == "${first_path}" ]];then + echo_and_log "The following directories are not allowed: ${NOT_ALLOW_PATH_SORT}." ${ERROR} ${INSTALL_LOG} + return 1 + fi + fi + done +} + +function check_path_include_special() { + local input_path="$1" + del_space_path=$(echo "${input_path}" | awk '{gsub(/^\s+|\s+$/, "");print}') + echo ${del_space_path} | grep " " >/dev/null 2>&1 + if [ "$?" == "0" ];then + echo_and_log "The entered installation path cannot contain spaces. Please enter a correct path and try again." ${ERROR} ${INSTALL_LOG} + return 1 + fi + local split_path=($(echo ${del_space_path} | tr '/' ' ')) + for value in ${split_path[*]} + do + str_status=$(echo "${value}" | tr -d '[A-Za-z0-9-_.]') + if [ -n "${str_status}" ];then + echo_and_log "The entered installation path can contain digital alphabets and special characters such as $ALLOW_STRING Please enter a correct path and try again." ${ERROR} ${INSTALL_LOG} + return 1 + fi + done + # 安装会检查用户家目录是否存在,存在了会提示用户创建devkit时把USER_PATH删除导致创建的安装目录被删 + if [[ "${input_path}" == ${USER_PATH} || "${input_path}" == "${USER_PATH}/" ]] ;then + local NOT_ALLOW_PATH_SORT=${NOT_ALLOW_PATH_SORT}" '${USER_PATH}'" + echo_and_log "The following directories are not allowed: ${NOT_ALLOW_PATH_SORT}." ${ERROR} ${INSTALL_LOG} + return 1 + fi + # 判断用户输入的路径是否为当前路径 + if [[ "${input_path}" == "${current_dir}" ]]; then + echo_and_log "The current directory cannot be used as the installation path." ${ERROR} ${INSTALL_LOG} + return 1 + fi +} + +function check_is_absolute_path() { + # 判断是否为绝对路径 "/" 开头的为绝对路径,否则为相对路径 + local input_path="$1" + first_str=${input_path: 0:1} + if [[ "$first_str" != "/" ]]; then + return 1 + fi + # 匹配/.. ../ /../ /. /./ 路径中的内容 + if (echo "${input_path}" | grep -qE "^\.{1,2}/|/\.{1,2}/|/\.{1,2}$" );then + return 1 + fi +} + +#检查用户输入的目录是否合法 +function check_user_input_path() { + local input_path="$1" + check_path_include_special "${input_path}" + if [ $? -ne 0 ]; then + return 1 + fi + check_path_is_system "${input_path}" + if [ $? -ne 0 ]; then + return 1 + fi + check_is_absolute_path "${input_path}" + if [ $? -ne 0 ]; then + echo_and_log "The relative path cannot be used as the installation directory. Enter an absolute path." ${ERROR} ${INSTALL_LOG} + return 1 + fi +} + +function verifying_signature_cmd(){ + local cms_bin_path="$1" + local package_name_tar="$2" + ${cms_bin_path} "${package_name_tar}" "${package_name_tar}.crl" "${package_name_tar}.cms" "${package_name_tar}.txt" + if [ $? -ne 0 ]; then + echo "The ${package_name}.tar.gz is incomplete,please check it" + exit ${ERROR} + fi +} + +# 验证签名 +function verifying_signature() { + local package_name="$1" + local INSTALL_PATH=${INSTALL_PATH:=$2} + local inner_package_name="$3" + if [[ -z ${inner_package_name} ]]; then + local inner_package_name=${package_name} + fi + local cms_bin_path="${INSTALL_PATH}/tools/cms" + local package_name_tar="${inner_package_name}.tar.gz" + if [[ -f "${package_name_tar}.crl" && -f "${package_name_tar}.txt" && -f "${package_name_tar}.cms" ]]; then + verifying_signature_cmd ${cms_bin_path} ${package_name_tar} + else + echo "The signature file is missing in ${package_name}.tar.gz,please check it" + exit ${ERROR} + fi +} + +# 自定义安装目录不存在创建目录 +function create_install_path(){ + status=$(mkdir -p "$1" 2>&1) + if [ "0" != "$?" ]; then + if [[ "$status" =~ "Permission denied" ]] || [[ "$status" =~ "权限不够" ]]; then + echo_and_log "Permission_denied" ${ERROR} ${INSTALL_LOG} + return 1 + fi + fi +} + +# 获取系统磁盘空间,检查磁盘空间是否满足安装 +function check_disk_space() +{ + local install_path=$1 + local disk_space_need=$2 + local check_type=$3 + available_space=$(df -kP "${install_path}" | awk 'NR==2' | awk '{print $4}') + if [[ ${available_space} -lt ${disk_space_need} ]]; then + local print_disk_space_need=$((disk_space_need / 1000)) + if [[ ${check_type} == "package" ]]; then + local tip="insufficient available disk space, ${print_disk_space_need} MB of free space was needed to decompress the installation package!" + else + local tip="insufficient available disk space, ${print_disk_space_need} MB of free space was needed to install DevKit!" + fi + echo_and_log "${tip}" "${ERROR}" "${INSTALL_LOG}" + exit "${ERROR}" + fi +} + +# 检测安装目录权限 +function path_permission_check() +{ + local install_path="$1" + local path="" + local owner="" + local permission="" + local dir="" + + if [[ -z "${install_path}" ]];then + echo_and_log "install path permission check Failed" "${ERROR}" + exit "${ERROR}" + fi + + for dir in ${install_path//// } + do + path="${path}/${dir}" + owner=$(ls -ld ${path} | awk '{print$3}') + permission=$(ls -ld ${path} | awk '{print$1}') + # 非devkit用户检测其他用户是否有可执行权限 + if [[ "${permission:9:1}" == x ]];then + continue + else + echo_and_log "${path} directory does not have sufficient permissions" "${ERROR}" + exit "${ERROR}" + fi + done +} + +function get_framework_version() { + local install_ini="${CURRENT_DIR}/${INSTALL_INI}" + framework_version=$(grep -w FRAMEWORK_VERSION ${install_ini} | awk -F= '{if($2 !="") print $2}') +} + +function add_crontab() +{ + local install_path=$1 + if [[ $os_type == "RedHatOS" ]]; then + cron_service=$(ps -ef | grep crond | grep -v grep) + if [ -z "${cron_service}" ]; then + echo_and_log "Nginx and Gunicorn logs cannot be deleted because the cron service is not started." ${DOING} ${INSTALL_LOG} + fi + else + cron_service=$(ps -ef | grep cron | grep -v grep) + if [ -z "${cron_service}" ]; then + echo_and_log "Nginx and Gunicorn logs cannot be deleted because the cron service is not started." ${DOING} ${INSTALL_LOG} + fi + fi + which crontab >/dev/null 2>&1 + if [ "$?" == "0" ]; then + echo 'MAILTO=""' > ${USER_PATH}/devkit_cron + crontab -l -u devkit >> ${USER_PATH}/devkit_cron + echo "0 2 * * * /bin/bash $install_path/DevKit/tools/script_port/log_rotate.sh >/dev/null 2>&1" >> ${USER_PATH}/devkit_cron + chown devkit:devkit ${USER_PATH}/devkit_cron + chmod 600 ${USER_PATH}/devkit_cron + crontab ${USER_PATH}/devkit_cron -u devkit + fi +} + +# 安装|升级|卸载过程写入到临时文件中前端获取阶段展示 +function return_install_info(){ + if [[ ${vscode_devkit_tag} != 1 ]]; then + return + fi + local type=$1 # 类型 安装、升级或者卸载 + local status=$2 # 成功 失败 + local info="$3" # 具体的信息 + local plugin_name="$4" # 插件名 + record_file_path="/root/tmp/.${type}_devkit.step" + plugin_name=$(echo "${plugin_name}" |sed 's/\b[a-z]/\U&/g') # 首字母大写 + + echo "${plugin_name}--$2--$3" >> ${record_file_path} + chmod 600 ${record_file_path} +} + +function check_vscode_install_tag() { + # 检查是否为vscode安装的 + local type="$1" + if [[ ${type} == "install" ]]; then + if [ -f "${CURRENT_DIR}/../.vscode_devkit.tag" ]; then + vscode_devkit_tag=1 + fi + fi + + if [[ ${type} == "uninstall" ]]; then + if [ -f "${CURRENT_DIR}/.vscode_devkit.tag" ]; then + vscode_devkit_tag=1 + fi + fi + + if [[ ${type} == "upgrade" ]]; then + if [ -f "/root/tmp/.vscode_devkit.tag" ]; then + vscode_devkit_tag=1 + fi + fi +} + +function add_devkit_plugin_sudo() +{ + command="$1" + command_path="$2" + local install_log="$3" + local sudo_file="$4" + if [ ! -f "${sudo_file}" ]; then + touch $sudo_file + fi + chmod 440 ${sudo_file} + + if grep "${USER_NAME} ALL=(root) NOPASSWD:${command_path}" "$sudo_file" + then + echo_and_log "${command} is already in the ${USER_NAME} sudoer list." "${DOING}" ${install_log} + else + # 空文件sed 追加不进去 sed 根据行号追加内容 + echo "${USER_NAME} ALL=(root) NOPASSWD:""${command_path}" >> "$sudo_file" + fi +} + +function change_asm_dep_permission() { + local file="$1" + if [ -f "${file}" ]; then + chmod 500 "${file}" + fi +} + +function install_asm_dep() { + # 安装汇编相关依赖 + local install_path=$1 + bash ${install_path}/DevKit/devkitplugins/check_asm_env.sh "install" + aarch64_all_asm_lib="${install_path}/DevKit/devkitplugins/all_asm/lib/ld-linux-aarch64.so.1" + x86_64_all_asm_lib="${install_path}/DevKit/devkitplugins/all_asm/lib/ld-linux-x86-64.so.2" + if [[ ${platform} == "aarch64" ]]; then + if [[ -f "${aarch64_all_asm_lib}" ]]; then + chmod 500 ${aarch64_all_asm_lib} + fi + else + if [[ -f "${x86_64_all_asm_lib}" ]]; then + chmod 500 ${x86_64_all_asm_lib} + fi + fi + if [ -d "${install_path}/DevKit/devkitplugins/all_asm/lib" ]; then + chown ${USER_NAME}:${USER_NAME} "${install_path}"/DevKit/devkitplugins/all_asm/lib/* + chmod 400 $(find "${install_path}/DevKit/devkitplugins/all_asm/lib" -type f) + change_asm_dep_permission ${install_path}/DevKit/devkitplugins/all_asm/lib/libc.so.6 + change_asm_dep_permission ${install_path}/DevKit/devkitplugins/all_asm/lib/libpthread.so.0 + change_asm_dep_permission ${install_path}/DevKit/devkitplugins/all_asm/lib/libdl.so.2 + change_asm_dep_permission ${install_path}/DevKit/devkitplugins/all_asm/lib/ld-linux-aarch64.so.1 + fi + if [ -d "${install_path}/DevKit/devkitplugins/inline_asm/remill/lib" ]; then + chown ${USER_NAME}:${USER_NAME} "${install_path}"/DevKit/devkitplugins/inline_asm/remill/lib/* + chmod 400 $(find "${install_path}/DevKit/devkitplugins/inline_asm/remill/lib" -type f) + change_asm_dep_permission ${install_path}/DevKit/devkitplugins/inline_asm/remill/lib/libc.so.6 + change_asm_dep_permission ${install_path}/DevKit/devkitplugins/inline_asm/remill/lib/libpthread.so.0 + change_asm_dep_permission ${install_path}/DevKit/devkitplugins/inline_asm/remill/lib/libdl.so.2 + change_asm_dep_permission ${install_path}/DevKit/devkitplugins/inline_asm/remill/lib/ld-linux-aarch64.so.1 + fi + if [[ -n ${install_path} && -d "${install_path}/DevKit/devkitplugins/all_asm/tmp/rpm" ]]; then + rm -rf "${install_path}"/DevKit/devkitplugins/all_asm/tmp/rpm/* + fi +} + +function restart_server() { + check_system_type + if [[ ${plugin_flag} == "web" ]]; then + local tmp_nginx_ini="${INSTALL_PATH}/config/.tmp_${plugin_name}_nginx.ini" + echo "[STATUS]" >${tmp_nginx_ini} + echo "server_status=1" >>${tmp_nginx_ini} # 开始重启 + chmod 644 ${tmp_nginx_ini} + sleep 1 + + fi + executing_user=$(whoami) + gunicorn_plugin_pid="${INSTALL_PATH}/devkitplugins/pid/pid" + gunicorn_plugin_ids=$(ps -ef | grep "devkitplugins/gunicorn_plugin.py" | grep -v 'grep' | awk '{print $2}' | xargs) + if [[ "${gunicorn_plugin_ids}" ]]; then + kill -9 ${gunicorn_plugin_ids} + fi + sleep 3 # 给服务重启预留时间 + # 删除历史报告记录 300 停止 100运行 400 等待 + $(${sqlite3_bin_path} "${sqlite3_file_path}" "delete from task_manage_task where status='100' or status='200';") + $(${sqlite3_bin_path} "${sqlite3_file_path}" ".quit") + if [[ ${system_is_container} == 1 ]]; then + local install_path=${INSTALL_PATH%/DevKit} + bash ${install_path}/DevKit/tools/docker_service.sh "restart" "gunicorn_plugin" + gunicorn_plugin_status="$?" + bash ${install_path}/DevKit/tools/docker_service.sh "restart" "devkit_nginx" + devkit_nginx_status="$?" + else + systemctl restart gunicorn_plugin.service + gunicorn_plugin_status="$?" + systemctl restart devkit_nginx.service + devkit_nginx_status="$?" + fi + sleep 1 + chmod 600 "${gunicorn_plugin_pid}" + if [[ "${devkit_nginx_status}${gunicorn_plugin_status}" != "00" ]]; then + exit ${ERROR} + fi + + if [[ ${plugin_flag} == "web" ]]; then + # 防止nginx重启过程中接口请求失败 + echo "[STATUS]" >${tmp_nginx_ini} + echo "server_status=0" >>${tmp_nginx_ini} # 重启成功 + sleep 5 + if [[ -n ${INSTALL_PATH} && -f "${tmp_nginx_ini}" ]]; then + rm -rf ${tmp_nginx_ini} + fi + fi +} + +function config_std_lib() { + if [ -f ${install_path}/DevKit/tools/libstdc++.so.6.0.24 ];then + cp_rf ${install_path}/DevKit/tools/libstdc++.so.6.0.24 ${USER_PATH}/lib/ + chmod 600 ${USER_PATH}/lib/libstdc++.so.6.0.24 + chown ${USER_NAME}:${USER_NAME} ${USER_PATH}/lib/libstdc++.so.6.0.24 + if [ -n "${USER_PATH}" ] && [ -h "${USER_PATH}/lib/libstdc++.so.6" ]; then + rm -rf ${USER_PATH}/lib/libstdc++.so.6 + fi + ln -s ${USER_PATH}/lib/libstdc++.so.6.0.24 ${USER_PATH}/lib/libstdc++.so.6 + chown -h ${USER_NAME}:${USER_NAME} ${USER_PATH}/lib/libstdc++.so.6 + fi +} + +function config_libprof_lib() { + if [ -f ${install_path}/DevKit/tools/libsym.so ];then + cp_rf ${install_path}/DevKit/tools/libsym.so ${USER_PATH}/lib/ + chmod 600 ${USER_PATH}/lib/libsym.so + chown ${USER_NAME}:${USER_NAME} ${USER_PATH}/lib/libsym.so + fi +} + +# 配置libffi软链接路径 +function config_libffi() +{ + local lib_dir=$1 + local log_file=$2 + local libffi_ldd_path="" + local libffi_ldconfig_path="" + local libffi_name="libffi.so.6" + echo_and_log "\nConfig libffi path" "${ECHO}" "${log_file}" + if [[ "${os_type}" == "OpenEulerOS" ]] && [[ "${os_version}" == "22.03" ]]; then + LIBFFI_PATH_LIST["${os_type}"]="/usr/lib64/libffi.so.8.1.0" + elif [[ "${os_type}" == "KylinOS" ]] && [[ "$(uname -m)" == "x86_64" ]] && [[ ! "$(cat /etc/kylin-release)" =~ "Sword" ]]; then + LIBFFI_PATH_LIST["${os_type}"]="/usr/lib64/libffi.so.6.0.1" + elif [[ "${os_type}" == "UbuntuOS" ]] && [[ "${os_version}" == "20.04" ]]; then + LIBFFI_PATH_LIST["${os_type}"]="/usr/lib/aarch64-linux-gnu/libffi.so.7.1.0" + elif [[ "${os_type}" == "CentOS" ]] && [[ ${os_version} =~ "8" ]]; then + LIBFFI_PATH_LIST["${os_type}"]="/usr/lib64/libffi.so.6.0.2" + fi + if [[ -f "${LIBFFI_PATH_LIST["${os_type}"]}" ]];then + libffi_source_path=${LIBFFI_PATH_LIST["${os_type}"]} + cp_rf ${libffi_source_path} ${lib_dir} + libffi_real_name=${libffi_source_path##*/} + if [[ "$?" -ne "${SUCCESS}" ]]; then + echo_and_log "Config libffi path failed" "${ERROR}" "${log_file}" + exit "${ERROR}" + fi + else + if [ -f "/usr/bin/pkttyagent" ]; then + libffi_ldconfig_path=$(ldd /usr/bin/pkttyagent | grep libffi |awk -F">" '{print$2}' | awk '{print$1}') + fi + if [[ -z "${libffi_ldconfig_path}" ]]; then + libffi_ldconfig_path=$(ldconfig -p | grep libffi.so | head -n1 | awk '{print$4}') + if [[ -z "${libffi_ldconfig_path}" ]]; then + echo_and_log "Get libffi from /usr/bin/pkttyagent and ldconfig failed" "${ERROR}" "${log_file}" + exit "${ERROR}" + fi + fi + libffi_real_name=$(ls -l ${libffi_ldconfig_path} | awk -F'->' '{print $2}' | tr -d ' ') + # 把libffi源文件拷贝到/home/devkit/lib 并改名为源文件 + cp -rL ${libffi_ldconfig_path} ${lib_dir}/${libffi_real_name} + if [[ "$?" -ne "${SUCCESS}" ]]; then + echo_and_log "Config libffi path failed" "${ERROR}" "${log_file}" + exit "${ERROR}" + fi + fi + # -h 判断如果后面内容未空也会执行 + if [ -n "${lib_dir}" ] && [ -n "${libffi_name}" ] && [ -h "${lib_dir}/${libffi_name}" ]; then + rm -rf "${lib_dir}/${libffi_name}" + fi + ln -sf ${lib_dir}/${libffi_real_name} "${lib_dir}/${libffi_name}" + chown -R ${USER_NAME}:${USER_NAME} ${USER_PATH} + echo_and_log "The libffi path is configured successfully." "${SUCCESS}" "${log_file}" +} + +check_cpu_type(){ + # 获取操作系统 + if [[ -f "${CURRENT_DIR}/check_env" ]] ; then + return_type=$(${CURRENT_DIR}/check_env && echo $?) + if [[ "${return_type}" == 0 ]] ; then + env_type=1 + else + env_type=0 + fi + else + env_type=0 + fi +} + +function get_cpu_id() { + open_file_num=8192 +} +# vscode安装记录已安装插件 +function record_installed_plugins() { + local record_flag="$1" + local plugin_name="$2" + local record_installed_file_path="/root/tmp/.install_record" + if [[ ${record_flag} ]]; then + # 插件的安装记录 + local record_plugin=$(grep -w install_plugin "${record_installed_file_path}" | awk -F= '{if($2 !="") print $2}') + if [[ ${record_plugin} ]]; then + if [[ "${record_plugin}" == "framework" ]]; then + sed_ini "${record_installed_file_path}" "install_plugin=" "install_plugin=${plugin_name}" + return + fi + local record_plugin="${record_plugin},${plugin_name}" + sed_ini "${record_installed_file_path}" "install_plugin=" "install_plugin=${record_plugin}" + else + sed_ini "${record_installed_file_path}" "install_plugin=" "install_plugin=${plugin_name}" + fi + else + local record_plugin=$(grep -w install_plugin "${record_installed_file_path}" | awk -F= '{if($2 !="") print $2}') + if [[ -z ${record_plugin} ]]; then + sed_ini "${record_installed_file_path}" "install_plugin=" "install_plugin=framework" + fi + local framework_version="$(grep -w FRAMEWORK_VERSION "${install_ini}" | awk -F= '{if($2 !="") print $2}')" + echo "install_framework_version=${framework_version}" >>${record_installed_file_path} + fi +} + +# 额外创建安全执行app的普通用户devkitworker1 +function create_launcher() +{ + local os_type=$1 + local user_name="devkitworker1" + local user_home="${USER_HOME}/${user_name}" + local user_group="devkit" + local package_tool=${PACKAGE_TOOL_LIST["${os_type}"]} + local user_exist=$(cat ${OS_PASSWD} | grep -w "${user_name}") + if [ -n "${user_exist}" ]; then + # 先删除 + echo_and_log "User:${user_name} is exist!" "${SUCCESS}" + delete_user "${user_name}" "${package_tool}" + fi + # 再创建 + if [[ "${package_tool}" == "apt" ]] || [[ "${package_tool}" == "zypper" ]]; then + groupadd "${user_name}" + useradd "${user_name}" -d "${user_home}" -g "${user_group}" -m -c "devkit_advisor_user" + elif [[ "${package_tool}" == "yum" ]]; then + useradd "${user_name}" -g "${user_group}" -c "devkit_advisor_user" + else + echo_and_log "Not supported OS type:${os_type}!" "${ERROR}" + exit "${ERROR}" + fi + if [ "${SUCCESS}" == "$?" ]; then + chmod 700 "${user_home}" + else + if [ "${os_type}" == "SLESOS" ]; then + userdel -f "${user_name}" + groupdel "${user_name}" + elif [[ "${package_tool}" == "yum" ]]; then + userdel -f "${user_name}" + else + userdel "${user_name}" + fi + echo_and_log "create_launcher:add user failed!" "${ERROR}" + exit "${ERROR}" + fi + + usermod -G wheel "${user_name}" -s /sbin/nologin + passwd -l "${user_name}" + # 设置launch用户umask值 + if [[ -f "${user_home}/.bash_profile" ]]; then + env_file="${user_home}/.bash_profile" + elif [[ -f "${user_home}/.profile" ]]; then + env_file="${user_home}/.profile" + else + echo_and_log "deal_env:env_file is not exist" "${ERROR}" + exit "${ERROR}" + fi + sed -i -e "/umask/d" "${env_file}" + sed -i "s%HYPER_WORKER_HOME=.*%HYPER_WORKER_HOME=${user_home}%g" "${CONFIG_FILE}" + echo "umask 077" >> "${env_file}" +} + + +# 删除应用运行用户 +function delete_launcher() { + local os_type=$1 + local user_name="devkitworker1" + local package_tool=${PACKAGE_TOOL_LIST["${os_type}"]} + delete_user "${user_name}" "${package_tool}" +} + +# 删除用户 +function delete_user() { + local user_name="$1" + local package_tool="$2" + local user_home="${USER_HOME}/${user_name}" + if [[ "${package_tool}" == "yum" ]];then + userdel -rf ${user_name} >/dev/null 2>&1 + elif [[ "${package_tool}" == "zypper" ]]; then + userdel -rf ${user_name} >/dev/null 2>&1 + elif [[ "${package_tool}" == "apt" ]] ; then + rmuser -h >/dev/null 2>&1 + if [ 0 == $? ]; then + rmuser ${user_name} -rf >/dev/null 2>&1 + else + userdel -rf ${user_name} >/dev/null 2>&1 + fi + else + deluser -q ${user_name} >/dev/null 2>&1 + fi + # userdel 删除用户删除mail下的内容导致创建同名用户报异常 + rm -rf "/var/spool/mail/${user_name}" + if [ -n "${USER_HOME}" ] && [ -d "${user_home}" ]; then + rm -rf "${user_home}" + fi +} + + +function copy_system_sudo_files() +{ + # 复制系统命令 + for ((i=0;i<${#RISKY_SUDOERS_LIST[@]};i++)) { + local cmd_path="$(which ${RISKY_SUDOERS_LIST[$i]} 2>/dev/null)" + if [[ -n "${cmd_path}" ]]; then + cp "${cmd_path}" "${DEVKIT_TOOL_PATH}/${RISKY_SUDOERS_LIST[$i]}_binary" + chmod 500 "${DEVKIT_TOOL_PATH}/${RISKY_SUDOERS_LIST[$i]}_binary" + chown root:root "${DEVKIT_TOOL_PATH}/${RISKY_SUDOERS_LIST[$i]}_binary" + fi + } + echo_and_log "Copy risky command success" "${SUCCESS}" +} + +function devkit_tools_config_init() +{ + # 复制install.ini到提权目录下 + local install_ini="${USER_HOME}/devkit/devkit_conf/install.ini" + if [ -e "${install_ini}" ]; then + local sudo_install_ini="/usr/bin/devkit_tools/install.ini" + if [ ! -e "${sudo_install_ini}" ]; then + cp "${install_ini}" "${sudo_install_ini}" + chown root:root "${sudo_install_ini}" + chmod 400 "${sudo_install_ini}" + fi + fi +} + +function del_file_chattr() { + # 处理文件添加/去除chattr + local type="$1" + local install_path="$2" + local service_path="${install_path}/DevKit/tools/script_port" + local file="${service_path}/service_gunicorn.sh ${service_path}/service_nginx.sh" + if [ "$1" == "add" ]; then + chattr +i ${file} >/dev/null 2>&1 + fi + if [ "$1" == "del" ]; then + chattr -i ${file} >/dev/null 2>&1 + fi +} + +# 同步配置文件 +function sync_install_ini() { + local base_ini="$1" + local install_ini_for_devkit="${install_path}/DevKit/config/install_devkit.ini" + local install_ini_for_root="${install_path}/DevKit/config/install.ini" + local install_ini_for_home="${USER_HOME}/devkit/devkit_conf/install.ini" + local install_ini_for_sudo="/usr/bin/devkit_tools/install.ini" + local ini_items=("${install_ini_for_devkit}" "${install_ini_for_root}" "${install_ini_for_home}" "${install_ini_for_sudo}") + for item in ${ini_items[@]}; do + if [[ -e "${item}" ]]; then + diff "${base_ini}" "${item}" >/dev/null + if [[ "$?" != 0 ]]; then + cp -f "${base_ini}" "${item}" + fi + fi + done +} + +# 检查SELinux强制状态1是否开启 +function check_selinux_status() { + status=$(getenforce 2>&1) + if [[ "Enforcing" == "$status" ]]; then + echo -e "\e[1;31m Failed to install Kunpeng DevKit. \e[0m" + echo -e "\e[1;31m The SELinux enforcing mode is enabled on the server, which will cause a tool installation failure.\e[0m" + exit 1 + fi +} + +function input_value_check(){ + # 把输入的内容换成小写 + local input_value=$1 + local agree=(yes y) + local disagree=(no n) + for (( i = 0; i < 2; i++ )); do + if [[ ${agree[$i]} == ${input_value,,} ]]; then + echo "yes" + return + fi + if [[ ${disagree[$i]} == ${input_value,,} ]]; then + echo "no" + return + fi + done +} + + +function is_orange_pi() { + if [ -e "/sys/devices/system/cpu/cpu0/regs/identification/midr_el1" ]; then + orange_pi_id=$(cat /sys/devices/system/cpu/cpu0/regs/identification/midr_el1) + if [ ${orange_pi_id} = "0x00000000001fd022" ]; then + echo "yes" + return + fi + fi +} + +function is_supported_arm() { + current_cpu_id="unknown" + if [ -f "${CPU_ID_FILE}" ]; then + current_cpu_id=$(cat "${CPU_ID_FILE}") + fi + if [[ "${SUPPORTED_ARM[@]}" =~ "${current_cpu_id}" ]]; then + return "${SUCCESS}" + else + return "${ERROR}" + fi +} diff --git a/scripts/devkit/deploy_devkit.sh b/scripts/devkit/deploy_devkit.sh new file mode 100644 index 0000000000000000000000000000000000000000..723c46f95a88d3c149dc378a141711deeacd705a --- /dev/null +++ b/scripts/devkit/deploy_devkit.sh @@ -0,0 +1,20 @@ +#!/usr/bin/expect + +set timeout 1500 +set devkit_dir_path [lindex $argv 0] + +cd $devkit_dir_path +spawn $devkit_dir_path/install_devkit.sh + +expect { + "The preceding dependencies will be automatically installed with DevKit. If source installation packages are available, add the installation paths to the LD_LIBRARY_PATH or PATH environment variable. Do you allow automatic installation of these dependencies?" { send "y\r"; exp_continue } + "Enter the sequence number of the tool access mode for your installation (default: 1)" { send "\r"; exp_continue } + "Enter the sequence number of the tool to be installed (default: 1)" { send "2\r"; exp_continue } + "Enter the serial number of the plug-in that can be installed. Format: a single digit or 'digits+commas', for example, (1 or 1,2 or 1,2,3). To exit the plug-in installation, enter no" { send "1,2,3,4,5\r"; exp_continue } + "Do you want to authorize the tool to handle the items failed in the installation environment check?" { send "Y\r"; exp_continue } + "Enter the installation path. (The default path is /opt)" { send "\r"; exp_continue } + "Please enter the installation port (default: 8086)" { send "\r"; exp_continue } + "please use the mapping IP" { exit 0 } + eof {} +} + diff --git a/scripts/devkit/install_devkit.sh b/scripts/devkit/install_devkit.sh new file mode 100755 index 0000000000000000000000000000000000000000..1927333774dc27dafb62a838825aa7adf95b8085 --- /dev/null +++ b/scripts/devkit/install_devkit.sh @@ -0,0 +1,2142 @@ +#!/bin/bash +#Description: DevKit install tool +#Copyright: Copyright © Huawei Technologies Co., Ltd. 2023. All rights reserved. +#History: 2023-2-9 created +set -x +current_dir=$(cd $(dirname $0);pwd) +source const.sh +source common.sh +source log.sh +source process_install_except.sh +source ${current_dir}/dependence_operate.sh + +# 默认非sso模式安装 +devkit_install_type="1" +install_tool="" +install_path="" +nginx_ip="" +server_ip="" +sso_flag="" +nginx_port="" +plugin_gunicorn_port="7996" +install_ini="${current_dir}/install.ini" +EXIT_FLAG="TRUE" # 记录exit_clean状态防止进入死循环 +trap 'onCtrlC' INT +trap 'onDisconnect' HUP +trap "exit_clean" EXIT + +function check_os_support() { + os_support_status=0 + if [ ${OS_TYPE_LIST} ~= ${os_type} ]; then + os_support_status=1 + fi +} + +check_sudoers() { + devkit_sudoers_status=$(grep -E "^#includedir /etc/sudoers.d\s*$" /etc/sudoers) + if [ -z "${devkit_sudoers_status}" ]; then + sudoers_devkit_config_exists=0 + else + # 用户已经添加了includedir + sudoers_devkit_config_exists=1 + fi + check_sudoers_status=1 + if [[ -f "/etc/sudoers.d/devkit_sudoers" ]] || [[ -d "/etc/sudoers.d/devkit_sudoers" ]]; then + # 用户已经有同名的devkit_sudoers文件 + sudoers_devkit_file_exists=1 + else + sudoers_devkit_file_exists=0 + # /etc/sudoers.d 目录不存在 + if [[ ! -d /etc/sudoers.d ]]; then + mkdir -p /etc/sudoers.d + chmod 750 /etc/sudoers.d + sudoers_devkit_file_exists=2 + fi + fi +} + +# sudo权限检查,必须有s权限 +function sudo_check_failed() { + local command="$1" + local sudo_path=$(which ${command}) + if [[ "${sudo_path}" == "" ]]; then + return "${SUCCESS}" + fi + local permission=$(stat -c %A "${sudo_path}") + if [[ ${permission:3:1} != "s" ]]; then + return "${SUCCESS}" + fi + return "${ERROR}" +} + +# su配置pam_rootok.so状态,必须有开启 +function pam_rootok_failed() { + local pam_rootok="/etc/pam.d/su" + if [ -e "${pam_rootok}" ]; then + for pamd in $(grep -w 'pam_rootok.so' ${pam_rootok} | awk '{print $1}'); do + if [[ ${pamd} == "auth" ]]; then + return "${ERROR}" + fi + done + fi + return "${SUCCESS}" +} + +check_devkit_user() { + user_exist=$(grep -w "${USER_NAME}" "${OS_PASSWD}") + if [[ "${user_exist}" ]]; then + status_of_user_status=1 + else + status_of_user_status=0 + fi + if [[ -d "/${USER_PATH}/" ]]; then + status_of_user_home=1 + else + status_of_user_home=0 + fi +} + +check_server_config() { + aim_dir=${SYSTEM_DIR_LIST["${os_type}"]} + gunicorn_framework_file="${aim_dir}/gunicorn_framework.service" + gunicorn_plugin_file="${aim_dir}/gunicorn_plugin.service" + devkit_nginx_file="${aim_dir}/devkit_nginx.service" + if [[ -f ${gunicorn_framework_file} ]] || [[ -f ${gunicorn_plugin_file} ]] || [[ -f ${devkit_nginx_file} ]]; then + status_of_service_config=1 + else + status_of_service_config=0 + fi +} + +function check_nOk_exit() { + # 检查不符合环境要求的内容退出安装 + sudo_has_s_permission=0 + su_has_s_permission=0 + pam_rootok_config_status=0 + if (sudo_check_failed "sudo"); then + sudo_has_s_permission=1 + fi + if (sudo_check_failed "su"); then + su_has_s_permission=1 + fi + if (pam_rootok_failed); then + pam_rootok_config_status=1 + fi + +} + +function record_plugin_lost_dependency() { + # 记录各插件缺失依赖 + local plugin_name=$1 + case $plugin_name in + sys_perf) + sys_perf_essential_lost="${essential_lost}" + sys_perf_noessential_lost="${noessential_lost}" + ;; + java_perf) + java_perf_essential_lost="${essential_lost}" + java_perf_noessential_lost="" + ;; + sys_diagnosis) + sys_diagnosis_essential_lost="${essential_lost}" + sys_diagnosis_noessential_lost="${noessential_lost}" + ;; + esac +} + +function parse_plugin_env_result(){ + # 解析 + local plugin_name="$1" + local plugin_package_name="$2" + local plugin_check_ini="${current_dir}/${plugin_package_name}/${plugin_package_name}/deploy/${plugin_name}_env_res.ini" + noessential_lost=$(grep -w noessential_lost "${plugin_check_ini}" | awk -F= '{if($2 !="") print $2}') + essential_lost=$(grep -w essential_lost "${plugin_check_ini}" | awk -F= '{if($2 !="") print $2}') + if [[ "${essential_lost}" ]]; then + CHECK_ITEM[${#CHECK_ITEM[@]}]="${plugin} mandatory dependencies" + CheckResult[${#CheckResult[@]}]="fail" + Suggestion[${#Suggestion[@]}]="The following mandatory components have not been installed:${essential_lost}" + fi + if [[ "${noessential_lost}" ]]; then + CHECK_ITEM[${#CHECK_ITEM[@]}]="${plugin} optional dependencies" + CheckResult[${#CheckResult[@]}]="fail" + Suggestion[${#Suggestion[@]}]="The following optional components have not been installed:${noessential_lost}" + fi + record_plugin_lost_dependency ${plugin_name} +} + +function check_plugins_env(){ + # 遍历选择安装的插件的环境检查脚本具体结果存放到临时目录,有框架读取 + # 未安装的失败的插件 + record_plugins_signature_failed="" + local plugins=$1 + if [[ ${plugins} == "framework" ]]; then + return + fi + tar zxfm ${current_dir}/toolkit.tar.gz + local cms_bin_path="${current_dir}/toolkit/cms" + for plugin in $(echo ${plugins} | tr "," " ");do + local plugin_package_name=${PLUGIN_NAME_MAPPING["${plugin}"]} + tar zxfm "${plugin_package_name}.tar.gz" + cd ${current_dir}/${plugin_package_name} + # 验证签名 + (verifying_signature_cmd ${cms_bin_path} "${plugin_package_name}.tar.gz") + if [ $? -ne 0 ];then + # 验签失败不进行后操作 + record_plugins_signature_failed=${record_plugins_signature_failed},${plugin} + cd ${current_dir} + continue + else + # 解压内层包执行环境检查 + tar zxfm ${plugin_package_name}.tar.gz + if [ -f ${plugin_package_name}/deploy/env_check.sh ]; then + echo " " + bash ${plugin_package_name}/deploy/env_check.sh + if [ $? -ne 0 ]; then + plugin_env_check_failed=1 + else + # 1、失败提示检查失败,安装过程不安装此插件 + # 2、检查成功读配置文件plugin_env_res.ini + parse_plugin_env_result "${plugin}" "${plugin_package_name}" + fi + fi + fi + cd ${current_dir} + done +} + +# 安装环境检查,包含:1. 是否已安装;2. 安装所需磁盘空间是否足够;3. +function env_check() { + echo_and_log "\nCheck the environment." "${ECHO}" "${INSTALL_LOG}" + # 检查是否已安装 + check_already_installed + dependence_check "${os_type}" "install" "${package_tool}" + has_root + check_nOk_exit + # 检查sudoers文件存在 + check_sudoers + # 检查用户是否存在 + check_devkit_user + # 检查服务配置文件是否存在 + check_server_config + # 展示结果 + prepare_check_result + # 检查各个插件需要的依赖 + check_plugins_env ${install_tool} + displaying_check_items + get_user_choice + resolve_fail_checklist + # 重复安装的时候初始化状态,避免异常终止清理环境不完全 + status_of_install_folders='' + echo_and_log "Check environment success" "${SUCCESS}" "${INSTALL_LOG}" +} + +function incremental_port() { + # 递增端口 + if [[ "${i}" == "1" ]]; then + port=$((port + 1)) + elif [[ "${i}" == "2" ]]; then + port=$((port + 11)) + elif [[ "${i}" == "3" ]]; then + port=$((port + 111)) + elif [[ "${i}" == "4" ]]; then + port=$((port + 1111)) + elif [[ "${i}" == "5" ]]; then + port=$((port + 11111)) + fi +} + +# 获取可用的nginx端口 +function get_available_port() { + local port=$1 + for ((i = 1; i < 6; i++)); do + for ((j = 0; j < 10; j++)); do + lsof -i :"${port}" >/dev/null 2>&1 + if [[ "$?" == "${SUCCESS}" ]]; then + incremental_port + continue + else + if [[ "${plugin_gunicorn_port},${nginx_port}" =~ ${port} ]]; then + # 端口不能和任何一个有重复 + incremental_port + continue + fi + echo -n "Port ${port} is available, do you want to use it? [y/N]: " + read -t "${TIMEOUT}" answer + if [[ "$?" -gt 128 ]]; then + echo_and_log "Input timeout." "${ERROR}" + exit ${ERROR} + fi + local answer=$(input_value_check ${answer}) + if [[ "${answer}" == "yes" ]]; then + available_port="${port}" + i=7 + elif [[ "${answer}" == "no" ]]; then + exit ${ERROR} + fi + break + fi + done + done +} + +function get_install_ip() { + # 获取用户的ip + if [[ "${server_ip}" ]];then + # 用户通过参数方式进入 + select_ip=${server_ip} + else + if [[ ${GLOBAL_IP} ]]; then + select_ip=${GLOBAL_IP} + fi + fi + + if [[ "$1" == "grpc_server_ip" ]]; then + grpc_server_ip=${select_ip} + else + nginx_ip=${select_ip} + fi +} + +# 检查端口的有效性 +function check_port_effective() { + input_port="$1" + result=$(echo ${input_port} | grep '^[1-9][0-9]*$') + if [[ -z "${result}" ]]; then + echo_and_log "DevKit_params:Invalid port format" "${ERROR}" + return "${ERROR}" + fi + if [[ "${input_port}" -lt 1024 ]] || [[ "${input_port}" -gt 65535 ]]; then + echo_and_log "DevKit_params:the port ${input_port} cannot be less than 1024 or greater than 65535." "${ERROR}" + return "${ERROR}" + fi +} + +function check_port_is_occupied() { + input_port="$1" + if [[ -z "${input_port}" ]]; then + input_port=${input_port:="8086"} + echo -e " Selected nginx port: ${input_port}\n" + fi + lsof -i :"${input_port}" + if [[ "$?" == "${SUCCESS}" ]]; then + echo_and_log "DevKit_params:the port ${input_port} is in use." "${ERROR}" + return "${ERROR}" + fi +} + +function show_color_tip() { + if [[ "$1" == "n" ]]; then + color=31 + tip=" (The current service platform is incompatible)" + else + color=32 + unset tip + fi +} + +function show_plugin_support() { + # Display the software supported by the current system user. + # check_result_list 记录支持不支持状态 + echo " " + echo "Select the plugins to be installed::" ${TIP_COLOR_CHECKING} + printf "%-20s %-20s %-20s\n" " SequenceNumber" "Plug-in" "Support" >>${INSTALL_LOG} + printf "%-20s %-20s %-20s\n" " SequenceNumber" "Plug-in" "Support" + plugins_support_list=($(echo ${plugins_support_list[@]} | tr ' ' ' ')) + plugins_support_num=${#plugins_support_list[@]} + if [[ ${env_type} == 0 || ${architecture} == "x86_64" ]]; then + check_result_list_arm_sso[1]='n' + check_result_list_x86_sso[1]='n' + check_result_list_arm[1]='n' + check_result_list_x86[1]='n' + fi + for ((i = 0; i < ${plugins_support_num}; i++)); do + if [[ "${architecture}" == "aarch64" ]]; then + if [[ "${devkit_install_type}" == "2" ]]; then + show_color_tip "${check_result_list_arm_sso[i]}" + printf "%-20s %-20s %-20s\n" " [$((i + 1))]" "${plugins_support_list[i]}" "${check_result_list_arm_sso[i]}${tip}" >>${INSTALL_LOG} + printf "%-20s %-20s \033[1;${color}m%-20s\033[0m\n" " [$((i + 1))]" "${plugins_support_list[i]}" "${check_result_list_arm_sso[i]}${tip}" + else + show_color_tip "${check_result_list_arm[i]}" + printf "%-20s %-20s %-20s\n" " [$((i + 1))]" "${plugins_support_list[i]}" "${check_result_list_arm[i]}${tip}" >>${INSTALL_LOG} + printf "%-20s %-20s \033[1;${color}m%-20s\033[0m\n" " [$((i + 1))]" "${plugins_support_list[i]}" "${check_result_list_arm[i]}${tip}" + fi + else + if [[ "${devkit_install_type}" == "2" ]]; then + show_color_tip "${check_result_list_x86_sso[i]}" + printf "%-20s %-20s %-20s\n" " [$((i + 1))]" "${plugins_support_list[i]}" "${check_result_list_x86_sso[i]}${tip}" >>${INSTALL_LOG} + printf "%-20s %-20s \033[1;${color}m%-20s\033[0m\n" " [$((i + 1))]" "${plugins_support_list[i]}" "${check_result_list_x86_sso[i]}${tip}" + else + show_color_tip "${check_result_list_x86[i]}" + printf "%-20s %-20s %-20s\n" " [$((i + 1))]" "${plugins_support_list[i]}" "${check_result_list_x86[i]}${tip}" >>${INSTALL_LOG} + printf "%-20s %-20s \033[1;${color}m%-20s\033[0m\n" " [$((i + 1))]" "${plugins_support_list[i]}" "${check_result_list_x86[i]}${tip}" + fi + fi + done +} + +function user_choose_plugin() { + while true; do + num=${#plugins_support_list[@]} + # Install the software according to the sequence selected by the user. + echo " " + echo -n -e "\e[1;37mEnter the serial number of the plug-in that can be installed. Format: a single digit or 'digits+commas', for example, (1 or 1,2 or 1,2,3). To exit the plug-in installation, enter no:\e[0m" + read -t "${TIMEOUT}" -r choose_install + if [[ "$?" -gt 128 ]]; then + echo_and_log "Input timeout." "${ERROR}" + exit ${ERROR} + fi + if [[ "${choose_install}" =~ ^[nN]$|^no$ ]]; then + select_result="" + echo_and_log "Do not install plug-in." "${ECHO}" "${INSTALL_LOG}" + break + fi + if echo "${choose_install}" | grep -qE "([1-$num],){1,$num}[1-$num]$|^[1-$num]$"; then + if [[ ${#choose_install} -eq 1 ]]; then + # Only one is selected by the user. + # Display the item that the user selects to install. + select_result=${plugins_support_list[((${choose_install} - 1))]} + if [[ "${architecture}" == "aarch64" ]]; then + if [[ "${devkit_install_type}" == "2" ]]; then + support_result=${check_result_list_arm_sso[((${choose_install} - 1))]} + else + support_result=${check_result_list_arm[((${choose_install} - 1))]} + fi + else + if [[ "${devkit_install_type}" == "2" ]]; then + support_result=${check_result_list_x86_sso[((${choose_install} - 1))]} + else + support_result=${check_result_list_x86[((${choose_install} - 1))]} + fi + fi + if [[ "${support_result}" == "n" ]]; then + echo_and_log "The service platform is incompatible. The ${select_result} plug-in cannot be installed. please re-select" "${DOING}" + continue + fi + else + # Display repeated user input. + choose_install=$(echo "${choose_install}" | tr ',' ' ' | xargs -n 1 | sort -u) + select_result="" + for i in ${choose_install}; do + select_result="$select_result,${plugins_support_list[(($i - 1))]}" + if [[ "${architecture}" == "aarch64" ]]; then + if [[ "${devkit_install_type}" == "2" ]]; then + support_result=${check_result_list_arm_sso[(($i - 1))]} + else + support_result=${check_result_list_arm[(($i - 1))]} + fi + else + if [[ "${devkit_install_type}" == "2" ]]; then + support_result=${check_result_list_x86_sso[(($i - 1))]} + else + support_result=${check_result_list_x86[(($i - 1))]} + fi + fi + if [[ "${support_result}" == "n" ]]; then + select_result=${plugins_support_list[(($i - 1))]} + break + fi + done + if [[ "${support_result}" == "n" ]]; then + echo_and_log "The service platform is incompatible. The ${select_result} plug-in cannot be installed. please re-select" "${DOING}" + continue + fi + fi + + break + fi + echo_and_log "Invalid input. Select a single digit or multiple sequences and use commas to separate them." ${ERROR} + done +} + +function check_the_package_type() { + # 检查包类型 全量包或者仅框架包 + if [ -f "${current_dir}/lables" ]; then + # 全量包 + package_type=1 + else + package_type=0 + fi +} + +function choose_install_software() { + for ((i = 0; i < 4; i++)); do + if [[ "${i}" == 3 ]]; then + exit "${ERROR}" + fi + if [[ ${package_type} == 1 ]]; then + echo " " + echo "Select an installation mode: " + echo " [1] : Install the DevKit framework and all plugins" + echo " [2] : Install the DevKit framework and selected plugins" + echo " [3] : Install the DevKit framework" + echo -n "Enter the sequence number of the tool to be installed (default: 1): " + read -t "${TIMEOUT}" install_tool + if [[ "$?" -gt 128 ]]; then + echo_and_log "Input timeout." "${ERROR}" + exit ${ERROR} + fi + fi + # 单独的框架包安装 + if [[ ${package_type} == 0 ]]; then + install_tool=3 + fi + if [[ "${install_tool}" == "1" ]] || [[ -z "${install_tool}" ]]; then + choose_all_plugin + install_tool_echo="DevKit framework with plugins including ${install_tool}" + elif [[ "${install_tool}" == "2" ]]; then + show_plugin_support + user_choose_plugin + install_tool="${select_result#,}" + if [[ "${install_tool}" ]]; then + install_tool_echo="DevKit framework with plugins including ${install_tool}" + else + install_tool_echo='' + fi + elif [[ "${install_tool}" == "3" ]]; then + install_tool="framework" + install_tool_echo="DevKit framework" + else + echo_and_log "install tool is wrong ,must be 1 or 2 or 3" "${ERROR}" + continue + fi + install_tool=${install_tool:="framework"} + install_tool_echo=${install_tool_echo:="DevKit framework"} + if [[ ${package_type} == 1 ]]; then + echo_and_log "Selected install_tool: ${install_tool_echo}" "${ECHO}" "${INSTALL_LOG}" + fi + break + done +} + +function get_install_path() { + # 安装路径的读取 + for ((i = 0; i < 4; i++)); do + if [[ "${i}" == 3 ]]; then + exit "${ERROR}" + fi + echo -n "Enter the installation path. (The default path is /opt): " + read -t "${TIMEOUT}" install_path + if [[ "$?" -gt 128 ]]; then + echo_and_log "Input timeout." "${ERROR}" + exit ${ERROR} + fi + if [[ -z "${install_path}" ]]; then + install_path=${install_path:="/opt"} + fi + echo -e " Selected install_path: ${install_path}\n" + if [[ ${install_path} != "/opt" ]]; then + # 检查用户输出的字符串是否符合规范 + check_selinux_status + check_user_input_path ${install_path} + if [ $? == 1 ]; then + continue + fi + if [ -f "${install_path}" ]; then + echo_and_log "\nFile exists: the file '${install_path}' already exists." "${ERROR}" + echo_and_log "\nA file name cannot be used as the installation path." "${ERROR}" + continue + fi + if [[ "${#install_path}" -ge "${PATH_CHAR_MAX}" ]]; then + echo_and_log "The path length exceeds the limit. Enter another one." ${ERROR} + continue + fi + # 检查目录不存在创建目录 + if [[ ! -d "${install_path}" ]]; then + # 创建目录 + create_install_path "${install_path}" + if [ $? == 1 ]; then + exit "${ERROR}" + fi + fi + fi + break + done + # 安装目录权限检测 + path_permission_check ${install_path} + if [ "$?" -ne "${SUCCESS}" ]; then + echo_and_log "Failed to check of the installation path." "${ERROR}" + exit "${ERROR}" + fi + echo_and_log "The permission check of the installation path is successful." "${SUCCESS}" + # 检查磁盘空间是否足够 + check_disk_space "${install_path}" "${DEVKIT_DISK_SPACE_NEED}" + echo_and_log "The space check of the installation path is successful." "${SUCCESS}" +} + +function deal_parameter_mode_install_path() { + local install_path="$1" + # 检查用户输出的字符串是否符合规范 + check_user_input_path ${install_path} + if [ $? == 1 ]; then + exit "${ERROR}" + fi + if [ -f "${install_path}" ]; then + echo_and_log "\nFile exists: the file '${install_path}' already exists." "${ERROR}" + echo_and_log "\nA file name cannot be used as the installation path." "${ERROR}" + exit "${ERROR}" + fi + if [[ "${#install_path}" -ge "${PATH_CHAR_MAX}" ]]; then + echo_and_log "The path length exceeds the limit. Enter another one." ${ERROR} + exit "${ERROR}" + fi + # 检查目录不存在创建目录 + if [[ ! -d "${install_path}" ]]; then + # 创建目录 + create_install_path "${install_path}" + if [ $? == 1 ]; then + exit "${ERROR}" + fi + fi + # 安装目录权限检测 + echo_and_log "\nCheck install path permission" "${DOING}" + path_permission_check ${install_path} + if [ "$?" -ne "${SUCCESS}" ]; then + echo_and_log "Check install path permission Failed" "${ERROR}" + exit "${ERROR}" + fi + echo_and_log "Check install path permission Success" "${SUCCESS}" + # 检查磁盘空间是否足够 + echo_and_log "\nCheck install path space" "${DOING}" + check_disk_space "${install_path}" "${DEVKIT_DISK_SPACE_NEED}" + echo_and_log "Check install path space Success" "${SUCCESS}" +} + +function get_install_port() { + # 安装port的读取和校验 + for ((i = 0; i < 4; i++)); do + if [[ "${i}" == 3 ]]; then + exit "${ERROR}" + fi + local port='' + if [[ "$1" == "nginx_port" ]]; then + echo -n "Please enter the installation port (default: 8086):" + read -t "${TIMEOUT}" port + if [[ "$?" -gt 128 ]]; then + echo_and_log "Input timeout." "${ERROR}" + exit ${ERROR} + fi + fi + if [[ "$1" == "nginx_port" ]]; then + port=${port:="8086"} + echo -e " Selected Nginx port: ${port}" + elif [[ "$1" == "grpc_listen_port" ]]; then + port=${port:="50051"} + echo -e " Selected RPC cluster server port: ${port}" + elif [[ "$1" == "http_listen_port" ]]; then + port=${port:="8002"} + echo -e " Selected HTTP server port: ${port}" + fi + check_port_effective "${port}" + if [[ "$?" != "${SUCCESS}" ]]; then + continue + else + port="${input_port}" + check_port_is_occupied "${port}" + if [[ "$?" != "${SUCCESS}" ]]; then + get_available_port "${port}" + port="${available_port}" + break + else + port=${input_port} + break + fi + fi + done + if [[ "$1" == "nginx_port" ]]; then + nginx_port=${port} + elif [[ "$1" == "grpc_listen_port" ]]; then + grpc_listen_port=${port} + elif [[ "$1" == "http_listen_port" ]]; then + http_listen_port=${port} + fi +} + +# 用户交互模式获取安装参数 +function entry_interactive_mode() { + install_type="install" + echo_and_log "\nObtain the IP address, port number, and installation path required by the tool service." "${ECHO}" "${INSTALL_LOG}" +} + +function entry_parameter_mode() { + echo_and_log "Entry parameter mode" "${DOING}" + while [ -n "$1" ]; do + case "$1" in + -d=* | --dir=*) + is_empty "${install_path}" "Install path" + install_path=$(echo "$1" | awk -F= '{if($2 !="") print $2}') + echo_and_log "Selected install_path: ${install_path}" "${ECHO}" "${INSTALL_LOG}" + deal_parameter_mode_install_path "${install_path}" + ;; + --framework) + is_empty "${install_tool}" "Install tool" + install_tool="framework" + ;; + --normal-install=*) + is_empty "${sso_flag}" "sso_flag" + sso_flag=$(echo "$1" | awk -F= '{if($2 !="") print $2}') + check_sso_legitimate + ;; + --plugin=*) + is_empty "${install_tool}" "Install tool" + install_tool=$(echo "$1" | awk -F= '{if($2 !="") print $2}') + check_plugin_legitimate + ;; + -a | --all) + is_empty "${install_tool}" "Install tool" + choose_all_plugin + ;; + -ip=* | --ip=*) + is_empty "${server_ip}" "Server IP" + server_ip=$(echo "$1" | awk -F= '{if($2 !="") print $2}') + + if [ -z "${server_ip}" ]; then + echo_and_log "DevKit_params:Server IP parameter value is empty" "${ERROR}" + exit "${SUCCESS}" + elif [[ "${server_ip}" = "127.0.0.1" && $(is_orange_pi) != "yes" ]]; then + echo_and_log "DevKit_params:Server IP parameter value cannot be 127.0.0.1" "${ERROR}" + exit "${SUCCESS}" + elif [[ "${server_ip}" =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then + result=$(ip addr show to "${server_ip}") + if [ -z "${result}" ]; then + echo_and_log "DevKit_params:Server IP address does not exist" "${ERROR}" + exit "${SUCCESS}" + fi + else + echo_and_log "DevKit_params:Invalid Server IP Address" "${ERROR}" + exit "${SUCCESS}" + fi + ;; + -p=* | --port=*) + is_empty "${nginx_port}" "Server Port" + nginx_port=$(echo "$1" | awk -F= '{if($2 !="") print $2}') + result=$(echo "${nginx_port}" | grep '^[1-9][0-9]*$') + if [ -z "${nginx_port}" ]; then + echo_and_log "DevKit_params:Server Port parameter value is empty" "${ERROR}" + exit "${SUCCESS}" + elif [ -z "${result}" ]; then + echo_and_log "DevKit_params:Invalid Server Port format" "${ERROR}" + exit "${SUCCESS}" + fi + if [[ "${nginx_port}" -lt "1024" ]] || [[ "${nginx_port}" -gt "65535" ]]; then + echo_and_log "DevKit_params:the Server Port cannot be less than 1024 or greater than 65535." "${ERROR}" + exit "${SUCCESS}" + fi + ;; + --rpc_port=*) + is_empty "${grpc_listen_port}" "Rpc Port" + grpc_listen_port=$(echo "$1" | awk -F= '{if($2 !="") print $2}') + result=$(echo "${grpc_listen_port}" | grep '^[1-9][0-9]*$') + if [ -z "${grpc_listen_port}" ]; then + echo_and_log "DevKit_params:Rpc cluster port parameter value is empty" "${ERROR}" + exit "${SUCCESS}" + elif [ -z "${result}" ]; then + echo_and_log "DevKit_params:Rpc cluster server port format" "${ERROR}" + exit "${SUCCESS}" + fi + if [[ "${grpc_listen_port}" -lt "1024" ]] || [[ "${grpc_listen_port}" -gt "65535" ]]; then + echo_and_log "DevKit_params:Rpc cluster server port cannot be less than 1024 or greater than 65535." "${ERROR}" + exit "${SUCCESS}" + fi + ;; + --http_port=*) + is_empty "${http_listen_port}" "Http Port" + http_listen_port=$(echo "$1" | awk -F= '{if($2 !="") print $2}') + result=$(echo "${http_listen_port}" | grep '^[1-9][0-9]*$') + if [ -z "${http_listen_port}" ]; then + echo_and_log "DevKit_params:Http port parameter value is empty" "${ERROR}" + exit "${SUCCESS}" + elif [ -z "${result}" ]; then + echo_and_log "DevKit_params:Http server port format" "${ERROR}" + exit "${SUCCESS}" + fi + if [[ "${http_listen_port}" -lt "1024" ]] || [[ "${grpc_listen_port}" -gt "65535" ]]; then + echo_and_log "DevKit_params:Http server port cannot be less than 1024 or greater than 65535." "${ERROR}" + exit "${SUCCESS}" + fi + ;; + -h | --help) + print_install_usage + exit "${SUCCESS}" + ;; + *) + echo_and_log "DevKit_params:$1 is not an option" "${ERROR}" + print_install_usage + exit "${SUCCESS}" + ;; + esac + shift + done +} + +function get_server_ip() { + if [ -z "${server_ip}" ]; then + if [ -z "${GLOBAL_IP}" ]; then + local ask_info="Please enter the sequence number of the listed IP address as the web server IP (default: 1):" + local log_tip_info="DevKit_params: sequence number is wrong" + for ((i = 0; i < 4; i++)); do + if [[ "${i}" == 3 ]]; then + exit "${ERROR}" + fi + show_ip_address + echo -n "${ask_info}" + read -t "${TIMEOUT}" numb + if [[ "$?" -gt 128 ]]; then + echo_and_log "Input timeout." "${ERROR}" + exit ${ERROR} + fi + if [[ -z "${numb}" ]]; then + GLOBAL_IP="${ip_array[0]}" + echo -e "${sure_info}${GLOBAL_IP}\n" + break + elif [[ "${numb}" =~ ^[0-9]{1,3}$ ]]; then + if [[ "${numb}" -gt ${len_num} ]] || [[ "${numb}" -lt 1 ]]; then + echo_and_log "${log_tip_info}" "${ERROR}" + continue + fi + GLOBAL_IP="${ip_array[${numb} - 1]}" + echo -e "${sure_info}${GLOBAL_IP}\n" + break + else + echo_and_log "${log_tip_info}" "${ERROR}" + continue + fi + done + else + echo -e "${sure_info}${GLOBAL_IP}\n" + fi + else + echo -e "${sure_info}${server_ip}\n" + fi +} + + + +# 获取安装参数 +function get_install_params() { + echo_and_log "\nStart obtaining installation parameters." "${ECHO}" "${INSTALL_LOG}" + local result="" + get_legality_ip_quantity + if [ "$#" == "0" ]; then + #进入交互模式 + entry_interactive_mode + fi + if [ -z "${install_path}" ]; then + get_install_path + fi + + install_tool=${install_tool:="framework"} + local sure_info=" Selected IP address of the web server: " + # 用户通过参数方式进入 + # 若为香橙派则IP地址设为127.0.0.1 + server_ip="127.0.0.1" + echo -e "${sure_info}${server_ip}\n" + + if [ -z "${nginx_ip}" ]; then + # 映射IP获取 + get_install_ip "nginx_ip" + fi + if [[ "${architecture}" == "aarch64" ]] && [ -z "${grpc_server_ip}" ]; then + # 映射IP获取 + get_install_ip "grpc_server_ip" + fi + if [ -z "${nginx_port}" ]; then + get_install_port "nginx_port" + fi + if [[ -z "${http_listen_port}" ]]; then + get_install_port "http_listen_port" + fi + if [[ "${architecture}" == "aarch64" ]] && [ -z "${grpc_listen_port}" ]; then + get_install_port "grpc_listen_port" + fi + check_django_port_effective + get_framework_version + # 检查用户设置端口防火墙状态 + check_firewalld_status ${nginx_port} + if [[ "${architecture}" == "aarch64" ]]; then + check_firewalld_status ${grpc_listen_port} + fi + if [[ "${status_of_firewall}" == "1" ]]; then + release_port + fi + show_install_msg "${framework_version}" "install" + generate_config +} + +function release_port(){ + i=0 + while true;do + echo -n -e "Firewall port '${disabled_ports} ' unavailable. You can authorize the tool to enable this port. Do you want to continue?[y/N]: " + echo "Firewall port '${disabled_ports} ' unavailable. You can authorize the tool to enable this port. Do you want to continue?[y/N]" >> "${INSTALL_LOG}" + read -t "${TIMEOUT}" -r input + if [[ "$?" -gt 128 ]]; then + echo_and_log "Input timeout." "${ERROR}" + input="no" + fi + local input=$(input_value_check ${input}) + if [[ "$input" == "yes" ]]; then + echo " your selected is $input" >>"${INSTALL_LOG}" + enable_multi_firewall_ports "${disabled_ports}" + break + elif [[ "$input" == "no" ]]; then + echo " your selected is $input" >>"${INSTALL_LOG}" + break + else + if [ "${i}" -gt 3 ]; then + input="no" + fi + let "i++" + echo_and_log "Invalid input." "${ERROR}" "${INSTALL_LOG}" + fi + done +} + +function sso_install() { + redirect_url="https://${nginx_ip}:${nginx_port}" + if [[ "${devkit_install_type}" == "2" ]]; then + rm -f "${install_path}/DevKit/tools/devkit" + bash "${current_dir}/sso_register.sh" "${install_path}" "${redirect_url}" + if [[ "$?" -eq "${ERROR}" ]]; then + exit "${ERROR}" + fi + fi +} + +function sso_install_type() { + # 通过参数形式安装 install.sh --normal-install=1 + if [[ ${sso_flag} ]];then + devkit_install_type=${sso_flag} + echo "The user name and password–based access mode will be used for installation." + return + fi + if [[ ${sso_flag} != "1" ]] && [[ ! -f "${current_dir}/../.vscode_devkit.tag" ]]; then + echo "" + echo 'Select a tool access mode for your installation:' + echo " [1]: User name and password" + echo " [2]: OAuth 2.0-based SSO (You will be automatically logged in to the DevKit once you logged in to the system.)" + echo -e "\e[1;37mIf you select [2], to ensure proper use of the Kunpeng DevKit, ensure that you have installed an external system that implements the OAuth2 authorization interface defined by the Kunpeng DevKit.\e[0m" + # 最多输入3次 + for ((i=0; i<4; i ++)); do + if [[ "${i}" == 3 ]];then + echo -e "\033[33mThe number of entries has exceeded the maximum number of re-entries, exiting.\033[0m" + exit "${SUCCESS}" + fi + echo -n 'Enter the sequence number of the tool access mode for your installation (default: 1):' + read -t "${TIMEOUT}" devkit_install_type + if [[ "$?" -gt 128 ]]; then + echo_and_log "Input timeout." "${ERROR}" + exit ${ERROR} + fi + if [[ "${devkit_install_type}" == "" ]] || [[ "${devkit_install_type}" == "1" ]] || [[ "${devkit_install_type}" == "2" ]]; then + break + fi + done + if [[ "${devkit_install_type}" == "2" ]]; then + echo " The OAuth 2.0 SSO mode will be used for installation." + rm -f "${install_path}/DevKit/tools/repair.sh" + rm -rf "${install_path}/DevKit/workspace/devadmin" + return + else + devkit_install_type=1 + fi + fi + echo " The access mode with the user name and password will be used for the installation." +} + +# 判断django端口是否生效 +function check_django_port_effective() { + # 检查插件端口 + check_port_effective "${plugin_gunicorn_port}" + if [[ "$?" != "${SUCCESS}" ]]; then + exit ${SUCCESS} + else + check_port_is_occupied "${plugin_gunicorn_port}" + if [[ "$?" != "${SUCCESS}" ]]; then + get_available_port "${plugin_gunicorn_port}" + plugin_gunicorn_port="${available_port}" + fi + fi + echo -e " Selected the internal port of the tool: ${plugin_gunicorn_port}\n" +} + +# 生成安装的配置文件 +function generate_config() { + echo_and_log "\nDevKit Configuration Generation" "${ECHO}" "${INSTALL_LOG}" + if [ ! -s "${install_ini}" ]; then + echo_and_log "The installation profile ${install_ini} does not exist or is empty." "${ERROR}" + exit "${ERROR}" + fi + sed_ini "${install_ini}" "USER_NAME=" "USER_NAME=${USER_NAME}" + sed_ini "${install_ini}" "USER_PATH=" "USER_PATH=${USER_PATH}" + sed_ini "${install_ini}" "INSTALL_TOOL=" "INSTALL_TOOL=${install_tool}" + sed_ini "${install_ini}" "INSTALL_PATH=" "INSTALL_PATH=${install_path}" + sed_ini "${install_ini}" "NGINX_IP=" "NGINX_IP=${nginx_ip}" + sed_ini "${install_ini}" "GUNICORN_IP=" "GUNICORN_IP=${GUNICORN_IP}" + sed_ini "${install_ini}" "NGINX_PORT=" "NGINX_PORT=${nginx_port}" + sed_ini "${install_ini}" "PLUGIN_GUNICORN_PORT=" "PLUGIN_GUNICORN_PORT=${plugin_gunicorn_port}" + sed_ini "${install_ini}" "SSO_FLAG=" "SSO_FLAG=${devkit_install_type}" + sed_ini "${install_ini}" "PACKAGE_TOOL=" "PACKAGE_TOOL=${package_tool}" + sed_ini "${install_ini}" "INSTALL_PACKAGE_DIR=" "INSTALL_PACKAGE_DIR=$(cd ${current_dir};pwd)" + + if [[ "${architecture}" == "aarch64" ]]; then + sed_ini "${install_ini}" "GRPC_SERVER_IP=" "GRPC_SERVER_IP=${grpc_server_ip}" + sed_ini "${install_ini}" "GRPC_LISTEN_PORT=" "GRPC_LISTEN_PORT=${grpc_listen_port}" + fi + sed_ini "${install_ini}" "HTTP_PORT=" "HTTP_PORT=${http_listen_port}" + sed_ini "${install_ini}" "IS_SERVER_NODE=" "IS_SERVER_NODE=true" +} + +function install_python() { + local tool_log="${TOOL_LOG}" + echo_and_log "\nInstall python environment" "${ECHO}" "${INSTALL_LOG}" + local tool_dir="${install_path}/DevKit/tools" + local thirdapp_dir="${CURRENT_DIR}/toolkit" + local tool_list=("python3.tar.gz" "python_venv.tar.gz") + local tool_suffix=".tar.gz" + local i=0 + [[ -d "${tool_dir}" ]] && rm_rf "${tool_dir}" + mkdir -p "${tool_dir}" + [[ -f "${tool_log}" ]] && rm_rf "${tool_log}" + touch "${tool_log}" + chmod 600 "${tool_log}" + if [ ! -d "${DEVKIT_TOOL_PATH}" ]; then + mkdir "${DEVKIT_TOOL_PATH}" + chmod 700 "${DEVKIT_TOOL_PATH}" + fi + # 拷贝文件到安装目录 + copy_source + cd "${thirdapp_dir}" + # 安装python和venv + for ((i = 0; i < ${#tool_list[@]}; i++)); do + tar zxfm "${tool_list[$i]}" -C "${tool_dir}" + if [ "$?" -ne "${SUCCESS}" ]; then + echo_and_log "Decompress ${tool_list[$i]} failed" "${ERROR}" "${INSTALL_LOG}" + exit "${ERROR}" + fi + echo_and_log "Install ${tool_list[$i]%%${tool_suffix}}" "${ECHO}" "${INSTALL_LOG}" + done + # 安装django + install_django + # 配置libffi依赖库路径 + config_libffi "${USER_PATH}/lib" "${INSTALL_LOG}" +} + +# 安装devkit +function install_devkit() { + local devkit_dir="${CURRENT_DIR}"/toolkit/DevKit_CLI + local devkit_bin="/usr/bin/devkit" + if [[ ! -d ${devkit_bin} ]]; then + mkdir "${devkit_bin}" + chmod -R 755 "${devkit_bin}" + fi + cp -r "${devkit_dir}"/* "${devkit_bin}/" + cp -r "${devkit_dir}"/.devkit "${devkit_bin}/" + chmod 755 "${devkit_bin}/devkit" "${devkit_bin}/.devkit" "${devkit_bin}/execute.ini" +} + +# 安装第三方组件 +function install_other_tool() { + local tool_log="${TOOL_LOG}" + echo_and_log "\nInstall third-party tools." "${ECHO}" "${INSTALL_LOG}" + local tool_dir="${install_path}/DevKit/tools" + local thirdapp_dir="${CURRENT_DIR}/toolkit" + local install_rpc_cluster='false' + if [[ "${architecture}" == "aarch64" ]]; then + local install_rpc_cluster='true' + fi + local tool_suffix=".tar.gz" + local i=0 + cd "${thirdapp_dir}" + if [[ "${install_rpc_cluster}" == "true" ]]; then + tar zxfm "rpc_cluster.tar.gz" -C "${tool_dir}" + if [ "$?" -ne "${SUCCESS}" ]; then + echo_and_log "Decompress rpc_cluster.tar.gz failed" "${ERROR}" "${INSTALL_LOG}" + exit "${ERROR}" + fi + fi + # 配置std_lib + config_std_lib + config_libprof_lib + i=0 + tar zxfm nginx.tar.gz + if [[ "$?" -ne "${SUCCESS}" ]]; then + echo_and_log "Decompress nginx.tar.gz failed" "${ERROR}" "${INSTALL_LOG}" + exit "${ERROR}" + fi + cd $(basename "nginx.tar.gz" "${tool_suffix}") + echo_and_log "Configure nginx... please wait" "${ECHO}" "${INSTALL_LOG}" + cp auto/configure . + chmod 700 configure + # 系统默认shell解释器为bash,nginx编译脚本中使用的sh部分语法不兼容 + bash ./configure --prefix=${tool_dir}/nginx --with-http_ssl_module --with-http_realip_module --with-http_addition_module --with-pcre --with-cc-opt="-fstack-protector-all -Wl,-z,relro,-z,now -fPIE -pie -I${USER_PATH}/include" --with-ld-opt="-fPIE -pie -Wl,-z,relro,-z,now -L${USER_PATH}/libssl" --with-cc=$(which gcc) --with-cpp=$(which g++) >>"${tool_log}" + if [[ "$?" -ne "${SUCCESS}" ]]; then + echo_and_log "Configure nginx Failed. See tool install log for more information: ${tool_log}" "${ERROR}" "${INSTALL_LOG}" + exit "${ERROR}" + fi + echo_and_log "Make nginx... please wait" "${ECHO}" "${INSTALL_LOG}" + make -j4 >>"${tool_log}" 2>&1 + if [[ "$?" -ne "${SUCCESS}" ]]; then + echo_and_log "Make nginx Failed. See tool install log for more information: ${tool_log}" "${ERROR}" "${INSTALL_LOG}" + exit "${ERROR}" + fi + echo_and_log "Make install nginx... please wait" "${ECHO}" "${INSTALL_LOG}" + make install >>"${tool_log}" + if [[ "$?" -ne "${SUCCESS}" ]]; then + echo_and_log "Make install nginx Failed. See tool install log for more information: ${tool_log}" "${ERROR}" "${INSTALL_LOG}" + exit "${ERROR}" + fi + + if [ -d "${install_path}/DevKit/tools/nginx/logs" ]; then + rm -rf "${install_path}/DevKit/tools/nginx/logs" + fi + + # 创建nginx日志 + if [[ ! -f "${install_path}/DevKit/logs/nginx/access.log" ]]; then + touch ${install_path}/DevKit/logs/nginx/access.log + fi + if [[ ! -f "${install_path}/DevKit/logs/nginx/error.log" ]]; then + touch ${install_path}/DevKit/logs/nginx/error.log + fi + chmod 600 ${install_path}/DevKit/logs/nginx/*.log + + echo_and_log "Install nginx Success" "${SUCCESS}" "${INSTALL_LOG}" + + install_html + chown devkit:devkit -R "$install_path/DevKit" + # cp_rf 卸载脚本 + su_user "strip ${tool_dir}/nginx/sbin/nginx" "${os_type}" +} + +function install_html() { + # 拷贝前端代码 + rm_rf "${current_dir}/devkitFramework" + unzip ${current_dir}/devkitFramework.zip -d ${current_dir} >/dev/null 2>&1 + force_mk_dir "${tool_dir}/nginx/html/devkit/plugins" + mv ${current_dir}/devkitFramework/* ${tool_dir}/nginx/html/devkit + mv ${install_path}/DevKit/config/error.html ${tool_dir}/nginx/html/devkit + chown devkit:devkit ${tool_dir}/nginx/html/devkit -R + # 删除冗余内容 + if [ -f "${tool_dir}/nginx/html/50x.html" ]; then + rm -rf "${tool_dir}/nginx/html/50x.html" + fi + if [ -f "${tool_dir}/nginx/html/index.html" ]; then + rm -rf "${tool_dir}/nginx/html/index.html" + fi +} + +function deal_asm_package() { + local all_asm_path="${install_path}/DevKit/devkitplugins/all_asm" + local inline_asm_path="${install_path}/DevKit/devkitplugins/inline_asm" + cp -rf ${all_asm_path}/bin/llc ${inline_asm_path}/remill/bin/ + mv ${all_asm_path}/bin/remill-lift-12.0 ${inline_asm_path}/remill/bin/ + cp -rf ${all_asm_path}/lib/* ${inline_asm_path}/remill/lib/ +} + +function copy_source() { + cp_rf "${CURRENT_DIR}/portal/*" ${install_path}/DevKit/ # 拷贝框架和插件源文件 + cp_rf ${CURRENT_DIR}/config ${install_path}/DevKit/ + cp_rf ${CURRENT_DIR}/script_port ${tool_dir}/ + cp_rf ${CURRENT_DIR}/script_upgrade ${tool_dir}/ + cp_rf ${CURRENT_DIR}/toolkit/cms ${tool_dir}/ + cp_rf ${CURRENT_DIR}/toolkit/chusrbin ${tool_dir}/ + cp_rf ${CURRENT_DIR}/toolkit/control_nginx ${tool_dir}/ + cp_rf ${CURRENT_DIR}/toolkit/libdevkit_crypto.so ${tool_dir}/ + cp_rf ${CURRENT_DIR}/toolkit/devkit ${tool_dir}/ + cp_rf ${CURRENT_DIR}/toolkit/log ${tool_dir}/ + if [[ "${architecture}" == "aarch64" ]]; then + # 提权脚本 + cp_rf "${CURRENT_DIR}/toolkit/devkit_tool/*" "/usr/bin/devkit_tools/" + fi + if [ -d ${CURRENT_DIR}/sso ]; then + cp_rf ${CURRENT_DIR}/sso ${tool_dir}/ + fi + if [ -f ${CURRENT_DIR}/toolkit/libstdc++.so.6.0.24 ]; then + cp_rf ${CURRENT_DIR}/toolkit/libstdc++.so.6.0.24 ${tool_dir}/ + fi + if [ -f ${CURRENT_DIR}/toolkit/DevKit-LibProf-${framework_version}-Linux-Kunpeng.tar.gz ];then + pushd ${CURRENT_DIR}/toolkit > /dev/null + tar zxfm DevKit-LibProf-${framework_version}-Linux-Kunpeng.tar.gz + if [ -f ${CURRENT_DIR}/toolkit/DevKit-LibProf-${framework_version}-Linux-Kunpeng/libsym.so ];then + cp_rf ${CURRENT_DIR}/toolkit/DevKit-LibProf-${framework_version}-Linux-Kunpeng/libsym.so ${tool_dir}/ + chmod 600 "${tool_dir}/libsym.so" + fi + popd > /dev/null + fi + + force_mk_dir "${tool_dir}/nginx/conf/location_conf" + force_mk_dir "${tool_dir}/nginx/conf/server" + force_mk_dir "${install_path}/DevKit/plugin_packages" + force_mk_dir "${install_path}/DevKit/logs/nginx" # 存放安装插件日志 + force_mk_dir "${install_path}/DevKit/logs/devkitplugins" # 存放插件服务日志 + force_mk_dir "${install_path}/DevKit/logs/devkitframework" # 存放框架服务日志 + force_mk_dir "${install_path}/DevKit/logs/rpc_log" # 存放rpc cluster日志 + force_mk_dir "${install_path}/DevKit/logs/module_log" # 存放module_log日志 + force_mk_dir "${install_path}/DevKit/config/lock_file" # 存放文件锁 + force_mk_dir "${install_path}/DevKit/config/log/operation_log" # 存放插件操作日志配置文件 + force_mk_dir "${install_path}/DevKit/config/log/runtime_log/tmp_log_param" # 存放插件运行日志配置文件 + force_mk_dir "${install_path}/DevKit/tools/clear_user_data" # 创建clear_user_data目录 + force_mk_dir "${install_path}/DevKit/workspace/devadmin" # 创建devadmin工作路径,如果是sso,之后删除 + force_mk_dir "${install_path}/DevKit/workspace/tmp" + force_mk_dir "${install_path}/DevKit/rsa" # 创建rsa目录 + mv ${install_path}/DevKit/config/log/common_cfg.json ${install_path}/DevKit/config/log/runtime_log + mv ${install_path}/DevKit/config/log/log.conf ${install_path}/DevKit/config/log/runtime_log + + force_mk_dir "${install_path}/DevKit/devkitframework/devkitframework/sock" # 框架socket文件 + force_mk_dir "${install_path}/DevKit/devkitplugins/sqlite" # 存放插件数据库,避免上级目录属组为root导致devkit无权限写入 + force_mk_dir "${install_path}/DevKit/devkitplugins/check_env_result" # 存放插件检查环境json,避免上级目录属组为root导致devkit无权限写入 + force_mk_dir "${install_path}/DevKit/devkitframework/pid" + force_mk_dir "${install_path}/DevKit/devkitplugins/pid" + force_mk_dir "${install_path}/DevKit/config/agent_space/ssh/sys_perf/install_node" # 创建agent存储目录 + touch "${install_path}/DevKit/config/restart_lock.lock" + touch "${install_path}/DevKit/logs/log_dump.lock" + mv ${install_path}/DevKit/config/devkit_nginx.conf ${tool_dir}/nginx/conf + # 拷贝install.ini 文件到安装目录下 + cp_rf "${CURRENT_DIR}/${INSTALL_INI}" ${install_path}/DevKit/config + cp_rf "${CURRENT_DIR}/${INSTALL_INI}" ${install_path}/DevKit/config/install_devkit.ini + cp_rf "${CURRENT_DIR}/${INSTALL_INI}" "${DEVKIT_TOOL_PATH}" + chmod 400 "${DEVKIT_TOOL_PATH}/${INSTALL_INI}" + # 拷贝卸载脚本到安装目录下 + # 拷贝 docker_service.sh到/opt/Devkit/tools下 + cp_rf "${CURRENT_DIR}/docker_service.sh" ${install_path}/DevKit/tools + cp_rf "${CURRENT_DIR}/check_env" ${install_path}/DevKit/tools + cp_rf "${CURRENT_DIR}/uninstall.sh" ${install_path}/DevKit/tools + cp_rf "${CURRENT_DIR}/sso_register.sh" ${install_path}/DevKit/tools + cp_rf "${CURRENT_DIR}/upgrade.sh" ${install_path}/DevKit/tools + cp_rf "${CURRENT_DIR}/common.sh" ${install_path}/DevKit/tools + cp_rf "${CURRENT_DIR}/log.sh" ${install_path}/DevKit/tools + cp_rf "${CURRENT_DIR}/const.sh" ${install_path}/DevKit/tools + cp_rf "${CURRENT_DIR}/repair.sh" ${install_path}/DevKit/tools + cp_rf "${CURRENT_DIR}/install_devkit_plugin.sh" ${install_path}/DevKit/tools + cp_rf "${CURRENT_DIR}/uninstall_devkit_plugin.sh" ${install_path}/DevKit/tools + cp_rf "${CURRENT_DIR}/upgrade_devkit_plugin.sh" ${install_path}/DevKit/tools + cp_rf "${CURRENT_DIR}/install_plugin_lock.sh" ${install_path}/DevKit/tools + cp_rf "${CURRENT_DIR}/uninstall_plugin_lock.sh" ${install_path}/DevKit/tools + cp_rf "${CURRENT_DIR}/change_ip_port.sh" ${install_path}/DevKit/tools + cp_rf "${CURRENT_DIR}/build_agent_plugins.sh" ${install_path}/DevKit/tools + cp_rf "${CURRENT_DIR}/openssl_contents" ${install_path}/DevKit/tools + cp_rf "${CURRENT_DIR}/agent_upgrade_entry.sh" ${install_path}/DevKit/tools + chmod 700 ${install_path}/DevKit/devkitframework/devkitframework/sock + chmod 500 ${install_path}/DevKit/tools/*.sh ${install_path}/DevKit/tools/script_port/*.sh +} + +# 配置venv中python及pip包路径 +function config_venv_packages_path() { + local install_path="${install_path}/DevKit" + local config_python_path="${install_path}/tools/python3/bin/python3" + local venv_python_path="${install_path}/tools/python_venv/bin/python3" + local config_list=(python3 django-admin django-admin.py gunicorn sqlformat) + echo_and_log "\nConfigure venv packages path" "${ECHO}" "${INSTALL_LOG}" + cd "${install_path}/tools/python_venv/bin" + for ((i = 0; i < ${#config_list[@]}; i++)); do + if [[ "${i}" -eq "0" ]]; then + if [ -n "${install_path}" ] && [ -h "${venv_python_path}" ]; then + rm -rf ${venv_python_path} + fi + ln -sf ${config_python_path} ${venv_python_path} + if [[ "$?" -ne "${SUCCESS}" ]]; then + echo_and_log "Configure venv ${config_list[$i]%%-*} path failed" "${ERROR}" "${INSTALL_LOG}" + exit "${ERROR}" + fi + else + sed -i "1c #!${venv_python_path}" "${config_list[$i]}" + if [[ "$?" -ne "${SUCCESS}" ]]; then + echo_and_log "Configure venv ${config_list[$i]%%-*} path failed" "${ERROR}" "${INSTALL_LOG}" + exit "${ERROR}" + fi + fi + done + python_venv="${install_path}/tools/python_venv/bin/python3" + echo_and_log "Configure venv packages path Success" "${SUCCESS}" "${INSTALL_LOG}" +} + +# 根据用户自定义的端口和路径修改nginx和gunicorn配置 +function change_server_conf() { + # 修改路径 + local plugin_gunicorn_conf=${install_path}/DevKit/devkitplugins/devkitplugins/gunicorn_plugin.py + local framework_gunicorn_conf=${install_path}/DevKit/devkitframework/devkitframework/gunicorn_framework.py + local nginx_conf=${install_path}/DevKit/tools/nginx/conf/devkit_nginx.conf + + local nginx_conf_service=${install_path}/DevKit/config/devkit_nginx.service + local framework_gunicorn_service=${install_path}/DevKit/config/gunicorn_framework.service + local plugin_gunicorn_service=${install_path}/DevKit/config/gunicorn_plugin.service + + sed_ini "${plugin_gunicorn_conf}" "#INSTALL_PATH#" "${install_path}" "1" + sed_ini "${plugin_gunicorn_conf}" "#PLUGIN_PORT#" "${plugin_gunicorn_port}" "1" + sed_ini "${framework_gunicorn_conf}" "#INSTALL_PATH#" "${install_path}" "1" + + sed_ini "${nginx_conf_service}" "#INSTALL_PATH#" "${install_path}" "1" + sed_ini "${nginx_conf_service}" "#USER_PATH#" "${USER_PATH}" "1" + sed_ini "${framework_gunicorn_service}" "#INSTALL_PATH#" "${install_path}" "1" + sed_ini "${framework_gunicorn_service}" "#USER_PATH#" "${USER_PATH}" "1" + sed_ini "${plugin_gunicorn_service}" "#INSTALL_PATH#" "${install_path}" "1" + sed_ini "${plugin_gunicorn_service}" "#USER_PATH#" "${USER_PATH}" "1" + + # 修改nginx配置文件 + sed_ini "${nginx_conf}" "#external_listen#" "listen ${nginx_ip}:${nginx_port} ssl;" "1" + sed_ini "${nginx_conf}" "#INSTALL_PATH#" "${install_path}" "1" + sed_ini "${nginx_conf}" "##IP##" "${nginx_ip}" "1" + sed_ini "${nginx_conf}" "##NGINX_PORT##" "${nginx_port}" "1" + sed_ini "${nginx_conf}" "##HTTP_PORT##" "${http_listen_port}" "1" + # 修改创建进程数量 + change_process_num +} + +function install_django() { + # 安装拷贝django相关组件 + # 修改activate activate.fish activate.csh 中VIRTUAL_ENV使用 + venv_bin=${install_path}/DevKit/tools/python_venv/bin + sed -i '/^VIRTUAL_ENV=/c\VIRTUAL_ENV=''"'"${install_path}/DevKit/tools/python_venv"'"' $venv_bin/activate + sed -i '/^set -gx VIRTUAL_ENV/c\set -gx VIRTUAL_ENV= ''"'"${install_path}/DevKit/tools/python_venv"'"' $venv_bin/activate.fish + sed -i '/^setenv VIRTUAL_ENV/c\setenv VIRTUAL_ENV ''"'"${install_path}/DevKit/tools/python_venv"'"' $venv_bin/activate.csh + mkdir -p ${USER_PATH}/libsqlite3 ${USER_PATH}/libssl ${USER_PATH}/lib + mv ${install_path}/DevKit/tools/python3/lib/libsqlite* ${USER_PATH}/libsqlite3/ + mv ${install_path}/DevKit/tools/python3/lib/libssl* ${USER_PATH}/libssl/ + mv ${install_path}/DevKit/tools/python3/lib/libcrypto* ${USER_PATH}/libssl/ + mv ${install_path}/DevKit/tools/python3/lib/libpython*so* ${USER_PATH}/lib/ + mv ${install_path}/DevKit/tools/python3/include/include ${USER_PATH}/ + chown -R ${USER_NAME}:${USER_NAME} ${USER_PATH}/libsqlite3 ${USER_PATH}/libssl ${USER_PATH}/lib + chmod 700 ${USER_PATH}/libsqlite3 ${USER_PATH}/libssl ${USER_PATH}/lib ${USER_PATH}/include/openssl/ ${USER_PATH}/include + chmod 600 -R ${USER_PATH}/libsqlite3/* ${USER_PATH}/libssl/* ${USER_PATH}/lib/* + chmod 400 ${USER_PATH}/include/openssl/* +} + +# tar +function tar_check() { + echo_and_log "\nDecompressing files ..." "${ECHO}" + for tar in ${CURRENT_DIR}/*.tar.gz; do + if [[ ${tar##*/} =~ "DevKit-" ]]; then + # 内层插件包此时不需要解压 + continue + fi + tar xvf $tar -C ${CURRENT_DIR}/ >/dev/null 2>&1 + if [ "0" != "$?" ]; then + echo_and_log "\nFailed to decompress the ${tar} file." "${ERROR}" "${INSTALL_LOG}" + echo_and_log "\nFailed to decompress the file." "${ERROR}" "${INSTALL_LOG}" + echo_and_log "\nPlease check possible reasons, such as lack of disk space." "${ERROR}" "${INSTALL_LOG}" + exit "${ERROR}" + fi + done + echo_and_log "Decompressing files success" "${SUCCESS}" "${INSTALL_LOG}" +} + +# 生成django的secret_key +function generate_secret_key() { + local python3="${install_path}/DevKit/tools/python_venv/bin/python3" + local generate_key_path="${install_path}/DevKit/devkitframework/devkitcommon/generate_key.pyc" + local devkit_framework_setting_path="${install_path}/DevKit/devkitframework/devkitframework" + local devkit_plugin_setting_path="${install_path}/DevKit/devkitplugins/devkitplugins" + export LD_LIBRARY_PATH=${USER_PATH}/libsqlite3:${USER_PATH}/libssl:${USER_PATH}/lib + su_user "${python3} ${generate_key_path}" "${os_type}" "${USER_NAME}" +} + +function generate_string() { + rand_string="" + python_path="${install_path}/DevKit/tools/python3/bin/python3" + rand_script_path="${install_path}/DevKit/devkitframework/common/openssl_rand.pyc" + export LD_LIBRARY_PATH=${USER_PATH}/libsqlite3:${USER_PATH}/libssl:${USER_PATH}/lib + rand_string=$(${python_path} ${rand_script_path} -pass 15) + unset LD_LIBRARY_PATH +} + +# 加密nginx启动口令 +function encrypting_password() { + local python3="${install_path}/DevKit/tools/python_venv/bin/python3" + local passphrase_path="${install_path}/DevKit/tools/nginx/sbin" + local password="$1" + + local encrypt_py="${install_path}/DevKit/tools/script_port/install_encrypting.pyc" + if [[ ! -f "${encrypt_py}" ]]; then + cp -rf "${CURRENT_DIR}/script_port/install_encrypting.pyc" "${encrypt_py}" + chown "${USER_NAME}:${USER_NAME}" "${encrypt_py}" + fi + su_user_cert "${python3} ${encrypt_py} ${install_path} ${passphrase_path}" "${password}" "${os_type}" "${USER_NAME}" + + if [ "$?" -ne "${SUCCESS}" ]; then + echo_and_log "Encrypting passphase Failed" "${ERROR}" "${INSTALL_LOG}" + exit "${ERROR}" + fi + force_mk_dir "${passphrase_path}/common/nginx" + mv ${passphrase_path}/common/kronos/* ${passphrase_path}/common/nginx + echo_and_log "Encrypting passphase success!" "${SUCCESS}" "${INSTALL_LOG}" +} + +function install_crt_procedure() { + openssl_dir=${current_dir}/openssl_contents/openssl_conf + openssl_bin_dir=${current_dir}/openssl_contents/openssl_bin + local openssl_path="${openssl_dir}/openssl.cnf" + generate_string + local password_server=${rand_string} + generate_string + local password_ca=${rand_string} + encrypting_password "${password_server}" + local cn_random_str=$(head -n 10 "/dev/urandom" | md5sum | head -c 4) + if [ -z "${nginx_ip}" ]; then + local install_ini="${DEVKIT_CONF}/${INSTALL_INI}" + nginx_ip=$(grep -w NGINX_IP "${install_ini}" | awk -F= '{if($2 !="") print $2}') + if [ -z "${nginx_ip}" ]; then + echo_and_log "NGINX_IP get failed" "${ERROR}" "${INSTALL_LOG}" + exit "${ERROR}" + fi + fi + # 生成秘钥交换文件 + openssl dhparam -out "${install_path}/DevKit/rsa/dhparam.pem" 2048 >/dev/null 2>&1 + export LD_LIBRARY_PATH=${USER_PATH}/libsqlite3:${USER_PATH}/libssl:${USER_PATH}/lib + export PATH="${openssl_bin_dir}:$PATH" + # 生成ca.key + openssl genrsa -aes256 -passout "stdin" -out "${install_path}/DevKit/rsa/ca.key" 4096 <<<"${password_ca}" >/dev/null 2>&1 + # 生成ca.crt + openssl req -new -x509 -sha256 -days 365 -subj "/C=CN/ST=ZHJ/L=HZH/O=HW/OU=AC/CN=IT Product ${cn_random_str}" -passin "stdin" -key "${install_path}/DevKit/rsa/ca.key" -out "${install_path}/DevKit/rsa/ca.crt" -config ${openssl_path} <<<"${password_ca}" >/dev/null 2>&1 + # 生成server.key + openssl genrsa -aes256 -passout "stdin" -out "${install_path}/DevKit/rsa/pontus" 4096 <<<"${password_server}" >/dev/null 2>&1 + # 生成server.csr + tmp_config_file="${install_path}/DevKit/$(cat /dev/urandom | head -n 10 | md5sum | head -c 10)-devkit_nginx_req_config.txt" + (cat ${openssl_path} <(printf "[SAN]\nsubjectAltName=DNS:Devkit,IP:${nginx_ip}\nextendedKeyUsage=serverAuth,clientAuth")) >${tmp_config_file} + chmod 600 ${tmp_config_file} + openssl req -new -sha256 -key "${install_path}/DevKit/rsa/pontus" -subj "/C=CN/ST=ZHJ/L=HZH/O=HW/OU=AC/CN=Devkit" -reqexts SAN \ + -config ${tmp_config_file} \ + -passin "stdin" -out "${install_path}/DevKit/rsa/server.csr" <<<"${password_server}" >/dev/null 2>&1 + # 生成server.crt + openssl x509 -req -extfile ${tmp_config_file} \ + -extensions SAN -CA "${install_path}/DevKit/rsa/ca.crt" -CAkey "${install_path}/DevKit/rsa/ca.key" \ + -CAcreateserial -days 365 -passin "stdin" -in "${install_path}/DevKit/rsa/server.csr" -out "${install_path}/DevKit/rsa/server.crt" <<<"${password_ca}" >/dev/null 2>&1 + if [ ! -f "${install_path}/DevKit/rsa/dhparam.pem" ] || [ ! -f "${install_path}/DevKit/rsa/ca.crt" ] || [ ! -f "${install_path}/DevKit/rsa/server.crt" ] || [ ! -f "${install_path}/DevKit/rsa/pontus" ] || [ ! -f "${install_path}/DevKit/rsa/server.csr" ]; then + echo_and_log "Failed to generate the certificate" "${ERROR}" "${INSTALL_LOG}" + exit "${ERROR}" + fi + # 删除无用文件 + if [ -e "${tmp_config_file}" ]; then + rm -rf "${tmp_config_file}" + fi + local rsa_file=(ca.key ca.srl) + erasing_file "${install_path}/DevKit/rsa" ${rsa_file[@]} + unset LD_LIBRARY_PATH + chown "${USER_NAME}:${USER_NAME}" "${install_path}/DevKit/rsa" -R + su_user "chmod g-rwx,o-rwx '${install_path}/DevKit/rsa' -R" "${os_type}" "${USER_NAME}" + su_user "chmod 400 ${install_path}/DevKit/rsa/*" "${os_type}" "${USER_NAME}" + # 删除生成口令 + unset rand_string + unset password_server + unset password_ca + echo_and_log "Generate the certificate Success" "${SUCCESS}" "${INSTALL_LOG}" +} + +function change_nginx_cert() { + local fingerprint=$1 + local spare_fingerprint=$2 + if [[ -z "${fingerprint}" ]] || [[ -z "${spare_fingerprint}" ]]; then + echo_and_log "Nginx fingerprint change Failed,fingerprint is empty" "${ERROR}" "${INSTALL_LOG}" + exit "${ERROR}" + fi + local nginx_conf="${install_path}/DevKit/tools/nginx/conf/devkit_nginx.conf" + if [[ -f "${nginx_conf}" ]]; then + sed -i "s%pin-sha256='a'%pin-sha256='${fingerprint}'%g" "${nginx_conf}" + sed -i "s%pin-sha256='b'%pin-sha256='${spare_fingerprint}'%g" "${nginx_conf}" + else + echo_and_log "Nginx fingerprint change Failed, nginx.conf does not exist" "${ERROR}" "${INSTALL_LOG}" + exit "${ERROR}" + fi +} + +# 生成证书 +function create_cert() { + old_mask=$(umask) + umask 077 + echo_and_log "\nIt may take a few minutes to generate the certificate. Please wait..." "${ECHO}" "${INSTALL_LOG}" + local openssl_version=$(openssl version -a) + if [ -z $? ]; then + echo_and_log "\nNo found openssl" "${ERROR}" "${INSTALL_LOG}" + exit "${ERROR}" + fi + install_crt_procedure + export LD_LIBRARY_PATH=${USER_PATH}/libsqlite3:${USER_PATH}/libssl:${USER_PATH}/lib + local openssl_path=${current_dir}/openssl_contents/openssl_conf/openssl.cnf + local public_key=$(openssl req -in "${install_path}/DevKit/rsa/server.csr" -config ${openssl_path} -pubkey -noout | openssl pkey -pubin -outform der | openssl dgst -sha256 -binary | openssl enc -base64) + unset LD_LIBRARY_PATH + change_nginx_cert "${public_key}" "${public_key}" + umask $old_mask + echo_and_log "Certificate generated successfully. You can import the root certificate to the browser to mask security alarms when you access the tool. The root certificate is stored in $install_path/DevKit/rsa/ca.crt." "${SUCCESS}" "${INSTALL_LOG}" + echo " " +} + +# 生成机机证书 +function create_grpc_cert() { + local node_ip="${nginx_ip}" + if [[ "${architecture}" == "aarch64" ]]; then + node_ip="${grpc_server_ip}" + fi + su_user "${install_path}/DevKit/tools/python_venv/bin/python3 ${install_path}/DevKit/devkitframework/certificatemanager/install_grpc_cert.pyc ${install_path}/DevKit/ ${node_ip}" "${os_type}" + echo_and_log "The grpc certificate generated successfully." "${SUCCESS}" "${INSTALL_LOG}" +} + +function create_rpc_config() { + # 修改rpc相关配置文件 + if [[ "${architecture}" == "aarch64" ]]; then + local rpc_server_log_conf=${install_path}/DevKit/tools/rpc_cluster/server/conf/cfg.ini + local rpc_server_conf=${install_path}/DevKit/tools/rpc_cluster/server/conf/serverConfig.ini + local rpc_client_conf=${install_path}/DevKit/tools/rpc_cluster/client/conf/client.ini + local rpc_client_id=${install_path}/DevKit/tools/rpc_cluster/client/conf/client.id + local script_path=${USER_PATH}/script + mkdir -p ${script_path} + chmod 700 ${script_path} + chown devkit:devkit ${USER_PATH}/script + mv ${install_path}/DevKit/tools/rpc_cluster/server/script/run_rpc_client.sh ${script_path} + chown devkit:devkit ${script_path}/run_rpc_client.sh + chmod 400 ${script_path}/run_rpc_client.sh + mv ${install_path}/DevKit/tools/rpc_cluster/server/script/run_node_devkitclient_by_sudo.sh ${script_path} + chown devkit:devkit ${script_path}/run_node_devkitclient_by_sudo.sh + chmod 400 ${script_path}/run_node_devkitclient_by_sudo.sh + if [[ -f "${rpc_server_log_conf}" ]]; then + sed_ini "${rpc_server_log_conf}" "/opt/DevKit" "${install_path}/DevKit" 1 + fi + if [[ -f "${rpc_server_conf}" ]]; then + sed_ini "${rpc_server_conf}" "GRPC_SERVER_IP=" "GRPC_SERVER_IP=${grpc_server_ip}" + sed_ini "${rpc_server_conf}" "GRPC_LISTEN_PORT=" "GRPC_LISTEN_PORT=${grpc_listen_port}" + sed_ini "${rpc_server_conf}" "WORK_KEY_PATH=" "WORK_KEY_PATH=${install_path}/DevKit/rsa/grpc_cert/server/" + sed_ini "${rpc_server_conf}" "SERVER_CERT_PATH=" "SERVER_CERT_PATH=${install_path}/DevKit/rsa/grpc_cert/devkit_servercert.pem" + sed_ini "${rpc_server_conf}" "CA_CERT_PATH=" "CA_CERT_PATH=${install_path}/DevKit/rsa/grpc_cert/devkit_cacert.pem" + sed_ini "${rpc_server_conf}" "STORAGE_PATH=" "STORAGE_PATH=${install_path}/DevKit/tools/rpc_cluster/server/storage/server" + fi + if [[ -f "${rpc_client_conf}" ]]; then + sed_ini "${rpc_client_conf}" "serverIP =" "serverIP = ${grpc_server_ip}" + sed_ini "${rpc_client_conf}" "serverPort =" "serverPort = ${grpc_listen_port}" + sed_ini "${rpc_client_conf}" "caCertFile =" "caCertFile = ${install_path}/DevKit/rsa/grpc_cert/devkit_cacert.pem" + sed_ini "${rpc_client_conf}" "clientCertFile =" "clientCertFile = ${install_path}/DevKit/rsa/grpc_cert/devkit_clientcert.pem" + sed_ini "${rpc_client_conf}" "clientKeyFile =" "clientKeyFile = ${install_path}/DevKit/rsa/grpc_cert/devkit_clientcert.pem" + sed_ini "${rpc_client_conf}" "workKeyFile =" "workKeyFile = ${install_path}/DevKit/rsa/grpc_cert/client" + + fi + if [[ -f "${rpc_client_id}" ]]; then + echo "${grpc_server_ip}" >${rpc_client_id} + fi + local collector_comp=${install_path}/DevKit/tools/rpc_cluster/client/conf/collector-comp.ini + if [[ -f "${collector_comp}" ]]; then + sed -i "s@compBinaryName = /opt@compBinaryName = ${install_path}@" ${collector_comp} + fi + if [[ -f /proc/sys/kernel/perf_event_paranoid ]]; then + echo -1 >/proc/sys/kernel/perf_event_paranoid + fi + if [[ -f /proc/sys/kernel/watchdog ]]; then + echo 0 >/proc/sys/kernel/watchdog + fi + fi +} + +# 创建rpc_task_pipe +function create_rpc_task_pipe() { + local rpc_task_pipe="${install_path}/DevKit/devkitframework/rpc_service/rpc_task_pipe" + mkfifo "${rpc_task_pipe}" + chown devkit:devkit "${rpc_task_pipe}" + chmod 600 "${rpc_task_pipe}" + echo_and_log "Create rpc_task_pipe successfully." "${SUCCESS}" "${INSTALL_LOG}" +} + +function deal_devkit_service_conf() { + local aim_dir=${SYSTEM_DIR_LIST["${os_type}"]} + # 配置到OS + # 容器不拷贝 删除目录内容 + if [[ ${system_is_container} == 1 ]]; then + rm_rf "${install_path}/DevKit/config/${NGINX_SERVICE}" + rm_rf "${install_path}/DevKit/config/${GUNICORN_PLUGIN_SERVICE}" + rm_rf "${install_path}/DevKit/config/${GUNICORN_FRAMEWORK_SERVICE}" + return + fi + # 增加service生效 + mv "${install_path}/DevKit/config/${NGINX_SERVICE}" "${aim_dir}" + mv "${install_path}/DevKit/config/${GUNICORN_PLUGIN_SERVICE}" "${aim_dir}" + mv "${install_path}/DevKit/config/${GUNICORN_FRAMEWORK_SERVICE}" "${aim_dir}" + + chmod 500 "${aim_dir}/${NGINX_SERVICE}" + chmod 500 "${aim_dir}/${GUNICORN_PLUGIN_SERVICE}" + chmod 500 "${aim_dir}/${GUNICORN_FRAMEWORK_SERVICE}" + chown root:root "${aim_dir}/${NGINX_SERVICE}" "${aim_dir}/${GUNICORN_PLUGIN_SERVICE}" "${aim_dir}/${GUNICORN_FRAMEWORK_SERVICE}" +} + +function container_start_service() { + # 启动ngixn + bash ${install_path}/DevKit/tools/docker_service.sh "start" "devkit_nginx" + if [ "$?" -ne 0 ]; then + echo_and_log "start devkit_nginx.service failed" "${ERROR}" + exit ${ERROR} + fi + # 启动framework + bash ${install_path}/DevKit/tools/docker_service.sh "start" "gunicorn_framework" + if [ "$?" -ne 0 ]; then + echo_and_log "start gunicorn_framework.service failed" "${ERROR}" + exit ${ERROR} + fi + # 启动plugin + bash ${install_path}/DevKit/tools/docker_service.sh "start" "gunicorn_plugin" + if [ "$?" -ne 0 ]; then + echo_and_log "start gunicorn_plugin.service failed" "${ERROR}" + exit ${ERROR} + fi +} + +# 开机自启动及启动服务 +function start_devkit_service() { + local log=$1 + echo_and_log "\nStart devkit nginx service, please wait..." "${ECHO}" "${log}" + if [[ ${system_is_container} == 1 ]]; then + container_start_service + else + call_service_start "devkit_nginx" + call_service_start "gunicorn_framework" + call_service_start "gunicorn_plugin" + fi + echo_and_log "Start DevKit service success" "${SUCCESS}" "${log}" +} + +function add_devkit_sudo_log() { + sudo_file="/etc/sudoers.d/devkit_sudoers" + if grep "Defaults logfile=/var/log/sudo.log" "$sudo_file"; then + logger "sudo.log conf is already in the ${common_install_user} sudoers." ${TIP_COLOR_ECHO} + else + sed -i '$a'" Defaults logfile=/var/log/sudo.log #$common_install_user" "$sudo_file" + fi + if [ "0" != "$?" ]; then + file_rm $current_dir/portal $current_dir/webui $current_dir/cmd + return 2 + fi + return 0 +} + +function change_process_num() { + core_num=$(cat /proc/cpuinfo | grep "processor" | wc -l) + local framework_gunicorn_conf=${install_path}/DevKit/devkitframework/devkitframework/gunicorn_framework.py + if [ "${core_num}" -lt 4 ]; then + sed -i "s/workers = multiprocessing.cpu_count()/workers = 4/" ${framework_gunicorn_conf} + elif [ "${core_num}" -ge 4 ] && [ "${core_num}" -le 8 ]; then + sed -i "s/workers = multiprocessing.cpu_count()/workers = ${core_num}/" ${framework_gunicorn_conf} + else + sed -i "s/workers = multiprocessing.cpu_count()/workers = 8/" ${framework_gunicorn_conf} + fi +} + +function deal_devkit_sudoers_config() { + # /etc/sudoers.d 目录不存在 + local sudo_file="/etc/sudoers" + if [ ! -d "/etc/sudoers.d" ]; then + mkdir "/etc/sudoers.d" + chmod 750 /etc/sudoers.d + fi + # 可能为devkit_sudoers同名目录或者文件 + if [ -e "/etc/sudoers.d/devkit_sudoers" ]; then + # 重复安装 + rm -rf "/etc/sudoers.d/devkit_sudoers" + fi + touch "/etc/sudoers.d/devkit_sudoers" + if ! grep -qE "^#includedir /etc/sudoers.d\s*$" "$sudo_file"; then + sed -i '$a'"#includedir /etc/sudoers.d" "$sudo_file" + sed_ini "${install_ini}" "SUDOERS_CONFIG=" "SUDOERS_CONFIG=1" + fi + # 创建/usr/bin/devkit_tools 存放要执行的脚本 + force_mk_dir "/usr/bin/devkit_tools" + chmod 700 "/usr/bin/devkit_tools" +} + +# 初始化数据迁移文件 +function init_migrations() { + # 修改admin json内容 + local user=${USER_NAME} + admin_json_path=${install_path}/DevKit/devkitframework/user/admin.json + worker_json_path=${install_path}/DevKit/devkitframework/user/worker.json + weak_password_json_path=${install_path}/DevKit/devkitframework/weakpassword/weak_password.json + sed -i "s#\"WORKSPACE\"#\"${install_path}/DevKit/workspace/devadmin\"#g" ${admin_json_path} + bash ${current_dir}/devkit_db_migrate.sh ${install_path} ${USER_PATH} ${devkit_install_type} + # 添加devkitworker用户 + export LD_LIBRARY_PATH=${USER_PATH}/libsqlite3:${USER_PATH}/libssl:${USER_PATH}/lib + ${install_path}/DevKit/tools/python_venv/bin/python3 ${install_path}/DevKit/devkitframework/manage.pyc loaddata ${worker_json_path} + rm_rf ${weak_password_json_path} + rm_rf ${admin_json_path} + rm_rf ${worker_json_path} + # 添加本机节点信息 + echo " " + if [[ "${architecture}" == "aarch64" ]]; then + ${install_path}/DevKit/tools/python_venv/bin/python3 "${install_path}/DevKit/devkitframework/node_manager/init_local_node.pyc" "${install_path}" "${grpc_server_ip}" + else + ${install_path}/DevKit/tools/python_venv/bin/python3 "${install_path}/DevKit/devkitframework/node_manager/init_local_node.pyc" "${install_path}" "${nginx_ip}" + fi + chown -R devkit:devkit "${install_path}/DevKit" +} + +function exit_clean() { + exit_code="$?" + copy_install_log + if [ ${exit_code} != 0 ] && [[ "${EXIT_FLAG}" == "TRUE" ]]; then + EXIT_FLAG="FALSE" + return_install_info "install" "Error" "End" "devkit" + return_install_info "install" "Deployment_End" "failed" "Deployment_End" + is_clear_from_log=$(grep -E "Clearable" ${INSTALL_LOG} | awk -F "=" '{print $2}' | tail -n 1) + if [[ "${is_clear_from_log}" = "True" ]]; then + clean_residue + fi + exit 1 + fi +} + +function install_plugin_script(){ + local plugin_name=$1 + cd ${current_dir} + if [[ ${plugin_name} == "sys_perf" ]]; then + if [[ "${sys_perf_noessential_lost}" ]]; then + echo_and_log "The following optional components choose been installed:${sys_perf_noessential_lost}" "${DOING}" + fi + if [[ "${sys_perf_essential_lost}" ]]; then + return_install_info "install" "Error" "Failed to install" "${plugin_name}" + echo_and_log "Failed to install the ${plugin_name} plug-in. The following necessary components have not been installed:${sys_perf_essential_lost}" "${ERROR}" + return 1 + fi + fi + if [[ ${plugin_name} == "java_perf" ]]; then + if [[ "${java_perf_noessential_lost}" ]]; then + echo_and_log "The following optional components choose been installed:${java_perf_essential_lost}" "${DOING}" + fi + if [[ "${java_perf_essential_lost}" ]]; then + return_install_info "install" "Error" "Failed to install" "${plugin_name}" + echo_and_log "Failed to install the ${plugin_name} plug-in.The following necessary components have not been installed:${java_perf_essential_lost}" "${ERROR}" + return 1 + fi + fi + if [[ ${plugin_name} == "sys_diagnosis" ]]; then + if [[ "${sys_diagnosis_noessential_lost}" ]]; then + echo_and_log "The following optional components choose been installed:${sys_diagnosis_noessential_lost}" "${DOING}" + fi + if [[ "${sys_diagnosis_essential_lost}" ]]; then + return_install_info "install" "Error" "Failed to install" "${plugin_name}" + echo_and_log "Failed to install the ${plugin_name} plug-in. The following necessary components have not been installed:${sys_diagnosis_essential_lost}" "${ERROR}" + return 1 + fi + fi + # 创建临时文件 + touch "${install_path}/DevKit/workspace/.install_${plugin_name}_flag" + chown devkit:devkit "${install_path}/DevKit/workspace/.install_${plugin_name}_flag" + bash ${install_path}/DevKit/tools/install_devkit_plugin.sh ${plugin_name} + if [ "$?" == 0 ]; then + return_install_info "install" "Success" "success" "${plugin_name}" + return 0 + else + return_install_info "install" "Error" "Failed to install" "${plugin_name}" + return 1 + fi +} + +function record_install_plugin(){ + install_tool="$1" + plugin_name=${install_tool##devkit.} + return_install_info "install" "Start" "start" "${plugin_name}" + install_plugin_script "${plugin_name}" + if [ $? -eq 0 ]; then + install_res="success" + else + install_res="failed" + fi + record_install_plugin_status+=("${plugin_name}-&-${install_res}") +} + +function install_plugin() { + # 安装插件 + record_install_plugin_status=() + if [[ ${install_tool} == "framework" ]]; then + return + fi + if [[ ${install_tool} =~ ',' ]]; then + for plugin_name in $(echo ${install_tool} | tr "," " "); do + record_install_plugin ${plugin_name} + done + else + record_install_plugin ${install_tool} + fi +} + +function tar_package_check() { + local attempt_tar_compress=60 + for ((i = 1; i <= ${attempt_tar_compress}; i++)); do + if [[ ${i} -eq ${attempt_tar_compress} ]]; then + tar $@ + else + tar $@ 2>/dev/null + fi + if [ $? != "${SUCCESS}" ]; then + sleep 1 + continue + else + return 0 + fi + done + return 1 +} + +function generate_sign() { + script_file="${install_path}/DevKit/devkitframework/devkitcommon/common_utils/generate_sign_files.py" + if [[ ! -f "${script_file}" ]]; then + script_file="${install_path}/DevKit/devkitframework/devkitcommon/common_utils/generate_sign_files.pyc" + if [[ -f "${script_file}" ]]; then + su - devkit -s /bin/bash -c "python3 ${script_file}" + if [[ "$?" == "0" ]]; then + echo_and_log "Signature verification key generated successfully" "${SUCCESS}" "${INSTALL_LOG}" + return + fi + fi + fi + echo_and_log "Failed to generate the signature verification key" "${ERROR}" "${INSTALL_LOG}" + exit "${ERROR}" +} + +# 生成agent安装包 +function generate_agent_package() { + cd "${CURRENT_DIR}" + + if [ ! -d "${CURRENT_DIR}/toolkit" ]; then + if [ -e "${CURRENT_DIR}/toolkit.tar.gz" ]; then + tar zxfm "${CURRENT_DIR}/toolkit.tar.gz" + else + echo_and_log "Generate agent package failed, file not exists: ${CURRENT_DIR}/toolkit.tar.gz" "${ERROR}" + exit "${ERROR}" + fi + fi + if [ -f ${CURRENT_DIR}/toolkit/DevKit-LibProf-${framework_version}-Linux-Kunpeng.tar.gz ];then + pushd ${CURRENT_DIR}/toolkit > /dev/null + tar zxfm DevKit-LibProf-${framework_version}-Linux-Kunpeng.tar.gz + if [ -f ${CURRENT_DIR}/toolkit/DevKit-LibProf-${framework_version}-Linux-Kunpeng/libsym.so ];then + cp_rf ${CURRENT_DIR}/toolkit/DevKit-LibProf-${framework_version}-Linux-Kunpeng/libsym.so ${CURRENT_DIR}/toolkit + chmod 600 "${CURRENT_DIR}/toolkit/libsym.so" + fi + popd > /dev/null + fi + force_mk_dir "${CURRENT_DIR}/agent_install_package/toolkit" + local toolkit_package_list=(python3.tar.gz python_venv.tar.gz rpc_cluster.tar.gz libdevkit_crypto.so libstdc++.so.6.0.24 log devkit_tool libsym.so) + # 拷贝 + for ((i = 0; i < ${#toolkit_package_list[@]}; i++)); do + if [ -e "${CURRENT_DIR}/toolkit/${toolkit_package_list[$i]}" ]; then + cp_rf "${CURRENT_DIR}/toolkit/${toolkit_package_list[$i]}" "${CURRENT_DIR}/agent_install_package/toolkit" + fi + done + if [ -e "${CURRENT_DIR}/portal/devkitframework/certificatemanager/update_certificate/update_work_key.pyc" ]; then + cp_rf "${CURRENT_DIR}/portal/devkitframework/certificatemanager/update_certificate/update_work_key.pyc" "${CURRENT_DIR}/agent_install_package/toolkit" + elif [ -e "${install_path}/DevKit/devkitframework/certificatemanager/update_certificate/update_work_key.pyc" ]; then + cp_rf "${install_path}/DevKit/devkitframework/certificatemanager/update_certificate/update_work_key.pyc" "${CURRENT_DIR}/agent_install_package/toolkit" + fi + local agent_package_list=(const.sh common.sh dependence_operate.sh agent_uninstall_entry.sh log.sh update_node_cert_by_sudo.sh process_node_plugin_by_sudo.sh) + for ((i = 0; i < ${#agent_package_list[@]}; i++)); do + if [ -e "${CURRENT_DIR}/${agent_package_list[$i]}" ]; then + cp_rf "${CURRENT_DIR}/${agent_package_list[$i]}" "${CURRENT_DIR}/agent_install_package" + else + echo_and_log "File not exists: ${CURRENT_DIR}/${agent_package_list[$i]}, continue" "${DOING}" + fi + done + + local home_file_list=(lib libsqlite3 libssl include devkit_conf script) + force_mk_dir "${CURRENT_DIR}/agent_install_package/devkit_home" + for ((i = 0; i < ${#home_file_list[@]}; i++)); do + if [ -e "${USER_PATH}/${home_file_list[$i]}" ]; then + if [[ "${home_file_list[$i]}" == "lib" ]]; then + force_mk_dir "${CURRENT_DIR}/agent_install_package/devkit_home/lib" + cp "${USER_PATH}"/lib/libpython* "${CURRENT_DIR}/agent_install_package/devkit_home/lib" + else + cp_rf "${USER_PATH}/${home_file_list[$i]}" "${CURRENT_DIR}/agent_install_package/devkit_home" + fi + else + if [[ "${architecture}" == "aarch64" ]]; then + echo_and_log "File not exists: ${USER_PATH}/${home_file_list[$i]}, continue" "${DOING}" + fi + fi + done + # 打包命令行工具 + force_mk_dir "${CURRENT_DIR}/agent_install_package/devkit_cli" + local cli_file_list=(.devkit devkit execute.ini) + local devkit_bin="/usr/bin/devkit" + for ((i = 0; i < ${#cli_file_list[@]}; i++)); do + if [ -e "${devkit_bin}/${cli_file_list[$i]}" ]; then + cp_rf "${devkit_bin}/${cli_file_list[$i]}" "${CURRENT_DIR}/agent_install_package/devkit_cli" + fi + done + + # 打包命令行工具 + force_mk_dir "${CURRENT_DIR}/agent_install_package/devkit_cli" + local cli_file_list=(.devkit devkit execute.ini) + local devkit_bin="/usr/bin/devkit" + for ((i = 0; i < ${#cli_file_list[@]}; i++)); do + if [ -e "${devkit_bin}/${cli_file_list[$i]}" ]; then + cp_rf "${devkit_bin}/${cli_file_list[$i]}" "${CURRENT_DIR}/agent_install_package/devkit_cli" + fi + done + + # 打包验签公钥文件 + local verify_script_dir="${CURRENT_DIR}/agent_install_package/verify_script" + force_mk_dir "${verify_script_dir}" + local sign_pub="${install_path}/DevKit/rsa/sign_cert/public_key.pem" + if [[ -f "${sign_pub}" ]]; then + cp "${sign_pub}" "${verify_script_dir}" + fi + local sign_script="${CURRENT_DIR}/toolkit/signature_verification" + if [[ -f "${sign_script}" ]]; then + cp "${sign_script}" "${verify_script_dir}" + fi + + cd ${CURRENT_DIR} + tar_package_check -zcf ${install_path}/DevKit/tools/agent_install_package.tar.gz agent_install_package + if [ $? != "${SUCCESS}" ]; then + echo_and_log "\nGenerate agent package failed! Maybe a problem occurred with shared directory synchronization." "${ERROR}" "${INSTALL_LOG}" + exit ${ERROR} + fi + chown "${USER_NAME}":"${USER_NAME}" ${install_path}/DevKit/tools/agent_install_package.tar.gz + chmod 600 ${install_path}/DevKit/tools/agent_install_package.tar.gz + if [ -d "${CURRENT_DIR}/agent_install_package" ]; then + rm_rf "${CURRENT_DIR}/agent_install_package" + fi + + # 复制agent安装脚本到安装目录 + local agent_deploy_script=(agent_install_entry.sh agent_uninstall_entry.sh agent_uninstall.expect) + for ((i = 0; i < ${#agent_deploy_script[@]}; i++)); do + if [ -e "${CURRENT_DIR}/${agent_deploy_script[$i]}" ]; then + cp_rf "${CURRENT_DIR}/${agent_deploy_script[$i]}" "${install_path}/DevKit/tools/" + chown "${USER_NAME}":"${USER_NAME}" "${install_path}/DevKit/tools/${agent_deploy_script[$i]}" + if [ "${agent_deploy_script[$i]}" == "agent_deploy.expect" ]; then + chown root:root "${install_path}/DevKit/tools/agent_deploy.expect" + fi + chmod 500 "${install_path}/DevKit/tools/${agent_deploy_script[$i]}" + else + echo_and_log "File not exists: ${CURRENT_DIR}/${agent_deploy_script[$i]}, continue" "${DOING}" + fi + done + if [ -e "${install_path}/DevKit/tools/agent_install_package.tar.gz" ]; then + echo_and_log "Generate agent package success" "${SUCCESS}" "${INSTALL_LOG}" + else + echo_and_log "Generate agent package failed" "${ERROR}" "${INSTALL_LOG}" + fi +} + +function change_file_path_permission() { + # 修改文件的权限 + local devkit_logs_dir=${install_path}/DevKit/logs + chmod 400 $(find ${install_path}/DevKit/ -regex ".*\.css\|.*\.js\|.*\.html\|.*\.png\|.*\.svg\|.*\.gif\|.*\.PNG\|.*\.ico\|.*\.md\|.*\.hhc\|.*\.hhk\|.*\.hhp\|.*\.cipher\|.*\.py\|.*\.pyc") + chmod 500 $(find ${install_path}/DevKit/tools/python_venv/bin/ -type f) + chmod 400 $(find ${install_path}/DevKit/tools/python_venv/lib/python3.9 -name "*\.py") + chmod -R 500 ${install_path}/DevKit/tools/python3/ + chmod 600 ${install_path}/DevKit/tools/python_venv/pyvenv.cfg + chmod 400 $(find ${install_path}/DevKit/tools/python3/include/python3.9 -name "*\.h") + chmod 400 $(find ${install_path}/DevKit/tools/python3/lib -name "*\.so") + chmod 700 $(find ${install_path}/DevKit/ -type d) + chmod 500 ${install_path}/DevKit/devkitplugins/devkitcommon/porting/tool/modulelog ${install_path}/DevKit/tools/clear_user_data + chmod 550 ${install_path}/DevKit/devkitplugins/cmake ${install_path}/DevKit/devkitplugins/cmake/bin + chmod 500 $(find ${install_path}/DevKit/tools/python3/ -type d) + chmod 500 $(find ${install_path}/DevKit/tools/python_venv -type d) + chmod 500 $(find ${install_path}/DevKit/tools/python_venv/lib -type f) + # lock_file保存锁文件,包括日志文件锁 + chmod 770 ${install_path}/DevKit/config/lock_file + chmod 600 ${install_path}/DevKit/config/*.json + chmod 400 $(find ${install_path}/DevKit/tools/python_venv/lib -type f) $(find ${install_path}/DevKit/devkitframework/node_manager/ -name *.xlsx) ${install_path}/DevKit/config/766848.txt ${install_path}/DevKit/config/decode_gcm.so ${install_path}/DevKit/config/version.conf ${install_path}/DevKit/config/location.conf + chmod 400 $(find ${install_path}/DevKit/tools/python_venv/lib -type f) $(find ${install_path}/DevKit/devkitframework/node_manager/ -name *.xlsx) + chmod 550 $(find ${install_path}/DevKit/tools/log/lib/ -type f) + chmod 550 ${install_path}/DevKit/tools/libdevkit_crypto.so + chmod 600 $(find ${install_path}/DevKit/tools/nginx/conf -type f) + chmod 600 ${install_path}/DevKit/tools/nginx/nginx.pid ${install_path}/DevKit/devkitframework/pid/pid + chmod 500 ${install_path}/DevKit/tools/nginx/sbin/nginx + chmod 600 ${install_path}/DevKit/tools/nginx/sbin/zeus + chmod 600 $(find ${install_path}/DevKit/tools/nginx/sbin/common/ -type f) + chmod 600 $(find ${install_path}/DevKit/ -name db.sqlite3) + chmod 710 ${install_path}/DevKit ${install_path}/DevKit/devkitplugins ${install_path}/DevKit/devkitplugins \ + ${install_path}/DevKit/workspace ${install_path}/DevKit/config/log ${install_path}/DevKit/config/log/runtime_log ${install_path}/DevKit/logs ${install_path}/DevKit/tools/log ${install_path}/DevKit/tools/log/lib + chmod 770 ${install_path}/DevKit/logs/module_log + if [ "${devkit_install_type}" != "2" ]; then + chmod 710 ${install_path}/DevKit/workspace/devadmin + fi + chmod 700 ${install_path}/DevKit/workspace/tmp ${install_path}/DevKit/devkitplugins/check_env_result + chmod 600 ${devkit_logs_dir}/devkitframework/devkit_framework.log ${devkit_logs_dir}/devkitplugins/devkit_plugin.log \ + ${devkit_logs_dir}/nginx/*.log ${devkit_logs_dir}/log_dump.lock + + need_change_root_owner=(install_devkit_plugin.sh upgrade_devkit_plugin.sh uninstall_devkit_plugin.sh common.sh const.sh + uninstall.sh upgrade.sh log.sh install_plugin_lock.sh uninstall_plugin_lock.sh change_ip_port.sh cms docker_service.sh + build_agent_plugins.sh check_env agent_upgrade_entry.sh) + for script in ${need_change_root_owner[@]}; do + chown root:root ${install_path}/DevKit/tools/${script} + chmod 500 ${install_path}/DevKit/tools/${script} + done + if [ "${devkit_install_type}" != "2" ]; then + chown root:root ${install_path}/DevKit/tools/repair.sh + chmod 500 ${install_path}/DevKit/tools/repair.sh + fi + chmod 501 ${install_path}/DevKit/tools/cms + chown devkit:devkit ${install_path}/DevKit/tools/openssl_contents/ -R + chmod 500 ${install_path}/DevKit/tools/openssl_contents/openssl_bin/openssl ${install_path}/DevKit/tools/chusrbin ${install_path}/DevKit/tools/control_nginx + chmod 400 ${install_path}/DevKit/tools/openssl_contents/openssl_conf/openssl.cnf ${install_path}/DevKit/config/dependency_dictionary/version + # 先改权限,再改属主,否则会导致devkit用户的gunicrn进程无法访问${install_path}/DevKit目录下的文件导致启动失败 + chmod 755 ${install_path}/DevKit + chmod 755 ${install_path}/DevKit/tools + chmod 500 ${install_path}/DevKit/tools/script_upgrade + chmod 400 ${install_path}/DevKit/tools/script_upgrade/* + chmod 755 ${install_path}/DevKit/config + chmod 600 ${install_path}/DevKit/config/sign/pubkey.pem + chmod 600 ${install_path}/DevKit/config/log/runtime_log/log.conf + chmod 640 ${install_path}/DevKit/config/log/runtime_log/common_cfg.json + chmod 660 ${install_path}/DevKit/config/lock_file/plugin_log_config.lock + chmod 600 ${install_path}/DevKit/config/restart_lock.lock $(find ${install_path}/DevKit/devkitplugins/cmake/ -regex ".*\.xml\|.*\.json") + chmod 600 $(find ${install_path}/DevKit/devkitplugins/inline_asm -regex ".*\.conf\|.*\.json") ${install_path}/DevKit/devkitplugins/prevision/conf/PrevisionLogCfg.json + chmod 600 $(find ${install_path}/DevKit/devkitplugins/all_asm -regex ".*\.conf\|.*\.json") + chmod 500 $(find ${install_path}/DevKit/devkitplugins/all_asm/bin -name *.sh) ${install_path}/DevKit/devkitplugins/check_asm_env.sh + chmod 500 $(find ${install_path}/DevKit/devkitplugins/cmake/ -name *.sh) + chown root:root ${install_path}/DevKit/tools/script_upgrade -R + chown root:root ${install_path}/DevKit/config/install.ini + chown root:root ${install_path}/DevKit + chown root:root ${install_path}/DevKit/config/ + chown root:root ${install_path}/DevKit/tools + chmod 600 ${install_path}/DevKit/config/install.ini ${install_path}/DevKit/config/install_devkit.ini + # 更改rpc_cluster权限为最小 + if [[ -d ${install_path}/DevKit/tools/rpc_cluster/ ]]; then + chmod 700 $(find ${install_path}/DevKit/tools/rpc_cluster/ -type d) + chmod 400 $(find ${install_path}/DevKit/tools/rpc_cluster/ -type f) + chmod 500 ${install_path}/DevKit/tools/rpc_cluster/server/bin/devkitserver + chmod 500 ${install_path}/DevKit/tools/rpc_cluster/client/bin/devkitclient + chmod 600 ${install_path}/DevKit/tools/rpc_cluster/server/conf/* + chmod -f 600 ${install_path}/DevKit/tools/rpc_cluster/server/logs/* + fi + # sudo file + local devkit_tools_path="/usr/bin/devkit_tools/" + for ((i=0;i<${#SUDO_FILES_LIST[@]};i++)) + do + local sudo_file="${devkit_tools_path}/${SUDO_FILES_LIST[$i]}" + if [[ -e "${sudo_file}" ]]; then + chmod 500 "${sudo_file}" + fi + done +} + +function clean_pycache_file(){ + local pycache_files=$(find ${install_path}/DevKit/tools/python_venv/ -user root -type d | grep __pycache__) + for pycache_file in ${pycache_files[@]} ; do + if [ -d ${pycache_file} ]; then + rm -rf ${pycache_file} + fi + done +} + +function backup_log_param() { + # 备份log_param 避免卸载插件导致框架服务异常 + runtime_log_path="${install_path}/DevKit/config/log/runtime_log" + tmp_log_param="${install_path}/DevKit/config/log/runtime_log/tmp_log_param" + while true; do + if [ -f "${runtime_log_path}/log_param.json" ]; then + sleep 3 # 防止服务写入json数据不完全或者为空 + cp -rf "${runtime_log_path}/log_param.json" ${tmp_log_param} + chmod 660 ${tmp_log_param} + break + else + continue + fi + done +} + +function create_record_installed_file() { + local record_installed_file_path="/root/tmp/.install_record" + if [ ! -d "/root/tmp" ]; then + mkdir -p /root/tmp + fi + if [ ! -f "${record_installed_file_path}" ]; then + touch ${record_installed_file_path} + chmod 400 ${record_installed_file_path} + fi + echo "install_plugin=" > ${record_installed_file_path} +} + +function main() { + check_vscode_install_tag "install" + create_log "${INSTALL_LOG}" + check_cpu_type + check_system_type + check_architecture + check_the_package_type + # 获取os类型 + get_os_type "${install_ini}" "${INSTALL_LOG}" + # 获取工具安装类别rpm dpkg + get_package_tool "${INSTALL_LOG}" + if [ "$#" != "0" ]; then + entry_parameter_mode "$@" + fi + # 安装方式选择 + sso_install_type + # 创建安装日志 + if [[ -z ${install_tool} ]]; then + # 安装框架 + choose_install_software + fi + env_check + # 获取安装参数并生成配置文件 + get_install_params "$@" + echo "Installation Start Phase:Clearable=True" >>${INSTALL_LOG} + # 创建用户 + create_user "${USER_NAME}" + # 配置用户环境变量 + configure_user_env "${USER_NAME}" + # 解压内层包 + tar_check + # 创建devkitworkx用户 + create_multi_user + # 安装python组件 + install_python + # 安装命令行工具 + install_devkit + # 配置虚拟环境中python软链接路径及第三方包的python解释器启动路径 + config_venv_packages_path + # SSO方式安装工具 + sso_install + # 添加nginx日志转储 + add_crontab ${install_path} + # 安装第三方组件 + install_other_tool + # 配置nginx端口和django端口和rpc配置 + change_server_conf + # 生成人机证书 + create_cert + # 拷贝服务到系统目录下 + deal_devkit_service_conf + # 页面输出提示安装成功 + cp_rf "${CURRENT_DIR}/${INSTALL_INI}" ${DEVKIT_CONF} + chown ${USER_NAME}:${USER_NAME} ${DEVKIT_CONF}/${INSTALL_INI} + chmod 400 ${DEVKIT_CONF}/${INSTALL_INI} + # 生成django的secret_key + generate_secret_key + # 初始化数据 + init_migrations + # 生成机机证书,机机证书信息需要入库,所以需要在数据库生成之后执行 + create_grpc_cert + # 创建rpc相关配置 + create_rpc_config + # 创建rpc任务传递管道文件 + create_rpc_task_pipe + # 检查汇编依赖 + install_asm_dep ${install_path} + # 启动服务 + start_devkit_service ${INSTALL_LOG} + # 备份log_param + backup_log_param + # sudoer配置 + add_devkit_sudo_list + # 系统高危命令 + copy_system_sudo_files + # 清除解压内容避免安装目录重复 + rm_rf "${CURRENT_DIR}/devkitFramework" + rm_rf "${CURRENT_DIR}/portal" + rm_rf "${CURRENT_DIR}/toolkit" + return_install_info "install" "Success" "success" "devkit" + change_file_path_permission + del_file_chattr "add" "${install_path}" + create_record_installed_file + devkit_tools_config_init + # 安装插件 + install_plugin + # 清理python缓存文件 + clean_pycache_file + record_installed_plugins + # 任何针对chusbin的修改都会修改cap_setuid状态 + setcap cap_setuid=eip ${install_path}/DevKit/tools/chusrbin + # 生成签名密钥 + generate_sign + # 生成agent安装包 + generate_agent_package + # 展示已安装插件信息 + if [[ ${UPGRADE_FLAG} == "false" ]]; then + displaying_installed_msg + fi + echo "Installation Start Phase:Clearable=FALSE" >>${INSTALL_LOG} +} + +main $@ diff --git a/scripts/devkit/workspace.cache.json b/scripts/devkit/workspace.cache.json new file mode 100644 index 0000000000000000000000000000000000000000..60649a03543e37cdf590deb7b599e6d4e16982eb --- /dev/null +++ b/scripts/devkit/workspace.cache.json @@ -0,0 +1,20 @@ +{ + "DevKitIsFirstAct": false, + "cache": { + "theme": "dark", + "deploymentType": null, + "notShowdeploymentDialog": null, + "language": "zh", + "updateThemeFlag": false, + "remoteConfigData": { + "ip": "127.0.0.1", + "port": "8086", + "selectCert": false, + "certPath": "" + }, + "isFromLogin": false + }, + "cacheSecrtKeyList": [ + "sessionStorage-https://127.0.0.1:8086" + ] + } \ No newline at end of file diff --git a/scripts/install_devkit.sh b/scripts/install_devkit.sh new file mode 100644 index 0000000000000000000000000000000000000000..99f3f10481d2b60a7aad2143a812d38a051a310d --- /dev/null +++ b/scripts/install_devkit.sh @@ -0,0 +1,106 @@ +#!/bin/bash + +KIT_DEPS=" +numactl-debuginfo numactl-libs numactl-debugsource file passwd which hostname procps +iproute make acl gcc-c++ gcc glibc openssl sudo sqlite wget lsof unzip gzip expect libcap rpm-build +e2fsprogs crontabs pcre pcre-devel zlib zlib-devel openssl-devel pcre-tools pcre2-devel alsa-lib libdrm +libgbm nspr nss nss-util libxkbfile xdg-utils perf dmidecode sysstat numactl libffi-devel libunwind +strace pciutils lsscsi initscripts policycoreutils ethtool rsyslog traceroute tcpdump fio ipmitool libaio-devel numactl-devel +" + +DEVKIT_REPO="https://gitee.com/kunpeng_compute/KunPengDevBoard-DevKit.git" + +DEVKIT_ROOT=${OUTPUT}/KunPengDevBoard-DevKit + +VSCODE_URL="https://vscode.download.prss.microsoft.com/dbazure/download/stable/e170252f762678dec6ca2cc69aba1570769a5d39/code-1.88.1-1712770627.el8.aarch64.rpm" +CPPTOOLS_URL="${DEVKIT_ROOT}/cpptools-linux-aarch64.vsix" +KIT_PULGIN_URL="https://mirrors.huaweicloud.com/kunpeng/archive/DevKit/Packages/Kunpeng_DevKit_IDE/Kunpeng%20DevKit-24.0.2.vsix" +MSCEINT_URL="${DEVKIT_ROOT}/MS-CEINTL.vscode-language-pack-zh-hans-1.88.2024041009.vsix" +GPC_URL="${DEVKIT_ROOT}/kunpeng-gpc-1.0.0-1.aarch64.rpm" +GPC_DEVEL_URL="${DEVKIT_ROOT}/kunpeng-gpc-devel-1.0.0-1.aarch64.rpm" +DEVKIT_URL="https://mirrors.huaweicloud.com/kunpeng/archive/DevKit/Packages/Kunpeng_DevKit/DevKit-All-24.0.T10-Linux-Kunpeng.tar.gz" + +execute_user="openEuler" + +function install_kitdeps() +{ + yum --releasever ${RELEASEVER} --forcearch ${ARCH} --installroot=${ROOTFS}/ install ${KIT_DEPS} -y -c "${YUM_CONF}" + + if [ ! -d ${DEVKIT_ROOT} ]; then + pushd ${OUTPUT} + git clone ${DEVKIT_REPO} + popd + fi + download_file ${KIT_PULGIN_URL} ${DEVKIT_ROOT} +} + +function install_plugins() +{ + local plugin=$(basename "$1") + + local file=${DEVKIT_ROOT}/${plugin} + if [[ -f "${file}" ]]; then + cp "${file}" "${ROOTFS}/${plugin}" + display_alert "Installing " "${plugin}" "info" + run_on_rootfs "code --no-sandbox --user-data-dir ~ --install-extension ${plugin}" + rm ${ROOTFS}/${plugin} + else + display_alert "Install failed " "${plugin}" "error" + fi +} + +function install_vscode() +{ + code_rpm=$(download_file "$VSCODE_URL" "${DEVKIT_ROOT}" | tail -n 1) + localinstall_package ${DEVKIT_ROOT} ${code_rpm} + + install_plugins ${CPPTOOLS_URL} + install_plugins ${KIT_PULGIN_URL} + install_plugins ${MSCEINT_URL} + + mkdir -p ${ROOTFS}/home/${execute_user}/.vscode/ + cp -f ${SRC}/scripts/devkit/argv.json ${ROOTFS}/home/${execute_user}/.vscode/argv.json +} + +function install_kunpeng_sdk() +{ + gpc_rpm=$(basename "$GPC_URL") + localinstall_package ${DEVKIT_ROOT} ${gpc_rpm} + + gpc_devel_rpm=$(basename "$GPC_DEVEL_URL") + localinstall_package ${DEVKIT_ROOT} ${gpc_devel_rpm} +} + +function install_kit() +{ + download_file "$DEVKIT_URL" "${DEVKIT_ROOT}" + tar zxf ${DEVKIT_ROOT}/DevKit-All-24.0.T10-Linux-Kunpeng.tar.gz -C ${OUTPUT}/ + tar zxf ${OUTPUT}/DevKit-All-24.0.T10-Linux-Kunpeng/DevKit-All-24.0.T10-Linux-Kunpeng.tar.gz -C ${OUTPUT}/ + mv ${OUTPUT}/DevKit-All-24.0.T10-Linux-Kunpeng ${ROOTFS}/tmp/DevKit-All-24.0.T10-Linux-Kunpeng + cp -f ${SRC}/scripts/devkit/common.sh ${ROOTFS}/tmp/DevKit-All-24.0.T10-Linux-Kunpeng/common.sh + cp -f ${SRC}/scripts/devkit/install_devkit.sh ${ROOTFS}/tmp/DevKit-All-24.0.T10-Linux-Kunpeng/install_devkit.sh + cp -f ${SRC}/scripts/devkit/deploy_devkit.sh ${ROOTFS}/tmp/deploy_devkit.sh + + mount_chroot ${ROOTFS} + run_on_rootfs "expect /tmp/deploy_devkit.sh /tmp/DevKit-All-24.0.T10-Linux-Kunpeng" + umount_chroot ${ROOTFS} + + rm -rf ${ROOTFS}/tmp/DevKit-All-24.0.T10-Linux-Kunpeng + +} + +function init_devkit_service() { + devkit_extension_path=${ROOTFS}/home/${execute_user}/.vscode/extensions/kunpengfamily.kunpeng-dev-kit-24.0.2 + mkdir -p ${devkit_extension_path} + cp ${SRC}/scripts/devkit/workspace.cache.json ${devkit_extension_path}/workspace.cache.json + + chown -R 1200:1200 ${ROOTFS}/home/${execute_user}/.vscode +} + +function install_devkit() { + install_kitdeps + install_vscode + install_kunpeng_sdk + install_kit + init_devkit_service +} \ No newline at end of file diff --git a/scripts/make_rootfs.sh b/scripts/make_rootfs.sh index 09442124fb179c0207d248e833c5f7a45225690a..5510d7be6b06d08d99e418574e9cae2b3654e505 100755 --- a/scripts/make_rootfs.sh +++ b/scripts/make_rootfs.sh @@ -159,6 +159,7 @@ function make_filesystem() fix_timesyncd fix_gnome process_chroot + install_devkit make_overlay rm ${ROOTFS}/etc/resolv.conf