|
@@ -0,0 +1,2954 @@
|
|
|
|
|
+#!/bin/bash
|
|
|
|
|
+#== AIX(Advanced Interactive eXecutive)是IBM基于AT&T Unix System V开发的一套类UNIX操作系统,运行在IBM专有的Power系列芯片设计的小型机硬件系统之上
|
|
|
|
|
+#== 以【#== 】开头的注释会在打包时删除
|
|
|
|
|
+#DEBUG== 以【#DEBUG== 】开头的注释会在调试打包时保留,正式打包时删除
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+#==脚本执行中遇到不存在的变量就报错
|
|
|
|
|
+set -o nounset
|
|
|
|
|
+#==脚本执行中报错即刻退出
|
|
|
|
|
+set -o errexit
|
|
|
|
|
+#==脚本执行只要一个子命令失败,整个管道命令就失败
|
|
|
|
|
+set -o pipefail
|
|
|
|
|
+
|
|
|
|
|
+readonly BRAND_FORMAL_NAME="Cloudwise"
|
|
|
|
|
+readonly BRAND_PRODUCT_NAME="euspace"
|
|
|
|
|
+readonly BRAND_PARENT_PRODUCT_NAME="omniagent"
|
|
|
|
|
+readonly BRAND_AGENT_PRODUCT_NAME="${BRAND_FORMAL_NAME} ${BRAND_PRODUCT_NAME}"
|
|
|
|
|
+readonly BRAND_FORMAL_NAME_LOWER="cloudwise"
|
|
|
|
|
+readonly BRAND_PRODUCT_NAME_LOWER="euspace"
|
|
|
|
|
+readonly BRAND_AGENT_DEFAULT_USER_AND_GROUP_NAME_CLOUDWISE="cloudwise"
|
|
|
|
|
+
|
|
|
|
|
+readonly AIX_DF_SPECIFIC_FLAG=
|
|
|
|
|
+readonly CONF_LD_PRELOAD=
|
|
|
|
|
+
|
|
|
|
|
+PARAM_DISABLE_SYSTEM_LOGS_ACCESS=
|
|
|
|
|
+
|
|
|
|
|
+#== 安装包版本项
|
|
|
|
|
+readonly AGENT_BUILD_DATE=25.09.2020
|
|
|
|
|
+readonly AGENT_INSTALLER_VERSION=1.2.0
|
|
|
|
|
+readonly AGENT_BUILD_DATE_INFO=""
|
|
|
|
|
+readonly AGENT_BUILD_TAG=""
|
|
|
|
|
+readonly AGENT_BUILD_UPLOADER=""
|
|
|
|
|
+#== 安装包版本项
|
|
|
|
|
+
|
|
|
|
|
+#== **********************************************************
|
|
|
|
|
+#== 配置重要文件名称
|
|
|
|
|
+#== **********************************************************
|
|
|
|
|
+#== CW-ServerAgent
|
|
|
|
|
+readonly AGENT_PROC="euspace"
|
|
|
|
|
+#== **********************************************************
|
|
|
|
|
+#== 配置目录
|
|
|
|
|
+#== **********************************************************
|
|
|
|
|
+readonly INSTALL_BASE=/opt
|
|
|
|
|
+#== /opt/cloudwise/oneagent/agents 目录
|
|
|
|
|
+readonly BASE_INSTALL_DIR=${INSTALL_BASE}/${BRAND_FORMAL_NAME_LOWER}/${BRAND_PARENT_PRODUCT_NAME}/agents
|
|
|
|
|
+#== cloudwise/oneagent/agents/chaosd
|
|
|
|
|
+readonly INSTALL_FOLDER=${BRAND_FORMAL_NAME_LOWER}/${BRAND_PARENT_PRODUCT_NAME}/agents/${BRAND_PRODUCT_NAME_LOWER}
|
|
|
|
|
+#== cloudwise/oneagent/agents/chaosd/version
|
|
|
|
|
+readonly INSTALL_VERSION_FOLDER=${INSTALL_FOLDER}/${AGENT_INSTALLER_VERSION}
|
|
|
|
|
+#== /opt/cloudwise/oneagent/agents/chaosd/version
|
|
|
|
|
+readonly INSTALL_DIR=${INSTALL_BASE}/${INSTALL_VERSION_FOLDER}
|
|
|
|
|
+#== /opt/cloudwise/oneagent/agents/chaosd
|
|
|
|
|
+readonly AGENT_BASE_DIR=${INSTALL_BASE}/${INSTALL_FOLDER}
|
|
|
|
|
+
|
|
|
|
|
+#== /opt/cloudwise/cwserveragent/conf
|
|
|
|
|
+readonly AGENT_CONF_DIR="${INSTALL_DIR}/conf"
|
|
|
|
|
+#== agent 初始化脚本目录 /opt/cloudwise/cwserveragent/scripts
|
|
|
|
|
+readonly AGENT_SCRIPTS_DIR="${INSTALL_DIR}/scripts"
|
|
|
|
|
+#== agent 初始化脚本目录 /opt/cloudwise/cwserveragent/runtime
|
|
|
|
|
+readonly AGENT_RUNTIME_DIR="${INSTALL_DIR}/runtime"
|
|
|
|
|
+#== agent 初始化脚本目录 /opt/cloudwise/cwserveragent/bin
|
|
|
|
|
+readonly AGENT_BIN_DIR="${INSTALL_DIR}/bin"
|
|
|
|
|
+#== agent 初始化脚本目录 /opt/cloudwise/cwserveragent/lib
|
|
|
|
|
+#== readonly AGENT_LIB_DIR="${INSTALL_DIR}/lib"
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+readonly AGENTS_BASE_DIR="${INSTALL_DIR}/agents"
|
|
|
|
|
+
|
|
|
|
|
+readonly META_BASE_DIR="${INSTALL_DIR}/meta"
|
|
|
|
|
+
|
|
|
|
|
+readonly LOG_DIR_NAME="logs"
|
|
|
|
|
+#== /opt/cloudwise/cwserveragent/logs
|
|
|
|
|
+readonly LOG_DIR=${INSTALL_DIR}/${LOG_DIR_NAME}
|
|
|
|
|
+
|
|
|
|
|
+#== /var/log/cloudwise/cwserveragent/
|
|
|
|
|
+readonly INSTALLER_LOG_DIR="/var/log/${INSTALL_FOLDER}"
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+#== server-agent.ini
|
|
|
|
|
+#== hostId文件
|
|
|
|
|
+readonly INSTALLER_CONF_FILE_NAME="installation.conf"
|
|
|
|
|
+#== 部署在容器内的状态信息
|
|
|
|
|
+readonly INSTALLER_CONF_FILE="${AGENT_CONF_DIR}/${INSTALLER_CONF_FILE_NAME}"
|
|
|
|
|
+
|
|
|
|
|
+#== 【0】=
|
|
|
|
|
+readonly INSTALLER_LOCK_FILE="/tmp/${BRAND_FORMAL_NAME_LOWER}_${BRAND_PRODUCT_NAME_LOWER}.lock"
|
|
|
|
|
+
|
|
|
|
|
+readonly INIT_SYSTEM_SYSV="SysV"
|
|
|
|
|
+#== 系统 systemd
|
|
|
|
|
+readonly INIT_SYSTEM_SYSTEMD="systemd"
|
|
|
|
|
+#== cw-serveragent
|
|
|
|
|
+readonly SERVICE_SCRIPT_FILE="cw-oneagent"
|
|
|
|
|
+#== cw-serveragent.service
|
|
|
|
|
+readonly SYSTEMD_UNIT_FILE_AGENT="${SERVICE_SCRIPT_FILE}.service"
|
|
|
|
|
+#== 系统文件目录
|
|
|
|
|
+readonly SYSTEMD_UNIT_FILES_DIR="/etc/systemd/system/"
|
|
|
|
|
+
|
|
|
|
|
+#== 【0】=【退出码】执行成功
|
|
|
|
|
+readonly EXIT_CODE_OK=0
|
|
|
|
|
+readonly EXIT_CODE_GENERIC_ERROR=1
|
|
|
|
|
+readonly EXIT_CODE_NOT_ENOUGH_SPACE=6
|
|
|
|
|
+readonly EXIT_CODE_NOT_ENOUGH_MEMORY=7
|
|
|
|
|
+#== 【0】=无效参数
|
|
|
|
|
+readonly EXIT_CODE_INVALID_PARAM=8
|
|
|
|
|
+readonly EXIT_CODE_INSUFFICIENT_PERMISSIONS=9
|
|
|
|
|
+
|
|
|
|
|
+#== 【退出码】接收信号
|
|
|
|
|
+readonly EXIT_CODE_SIGNAL_RECEIVED=12
|
|
|
|
|
+readonly EXIT_CODE_ANOTHER_INSTALLER_RUNNING=13
|
|
|
|
|
+readonly EXIT_CODE_CORRUPTED_PACKAGE=16
|
|
|
|
|
+#== 【退出码】管理系统环境变量配置
|
|
|
|
|
+readonly EXIT_CODE_MISCONFIGURED_ENVIRONMENT=17
|
|
|
|
|
+readonly EXIT_CODE_UNSUPPORTED_DOWNGRADE=18
|
|
|
|
|
+readonly EXIT_CODE_OS_NOT_SUPPORTED=19
|
|
|
|
|
+
|
|
|
|
|
+readonly EXTERNAL_TAR_SIZE=233820160
|
|
|
|
|
+readonly ARTIFACTS_SIZE=953271934
|
|
|
|
|
+#**********************************************************
|
|
|
|
|
+# Logs
|
|
|
|
|
+#**********************************************************
|
|
|
|
|
+toLogFile() {
|
|
|
|
|
+ if [ -e "${LOG_FILE}" ]; then
|
|
|
|
|
+ printf '%s UTC %s\n' "$(date -u +"%Y-%m-%d %H:%M:%S")" "$*" >>"${LOG_FILE}" 2>/dev/null
|
|
|
|
|
+ fi
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+toConsoleOnly() {
|
|
|
|
|
+ printf '%s %s\n' "$(date +"%H:%M:%S")" "$*" 2>/dev/null
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+toLogInfo() {
|
|
|
|
|
+ toLogFile "[INFO]" "$@"
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+toLogWarn() {
|
|
|
|
|
+ toLogFile "[WARN]" "$@"
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+toLogError() {
|
|
|
|
|
+ toLogFile "[ERROR]" "$@"
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+toLogAdaptive() {
|
|
|
|
|
+ local success="${1}"
|
|
|
|
|
+ shift
|
|
|
|
|
+ if [ "${success}" -eq 0 ]; then
|
|
|
|
|
+ toLogInfo "$@"
|
|
|
|
|
+ else
|
|
|
|
|
+ toLogError "$@"
|
|
|
|
|
+ fi
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+toConsoleInfo() {
|
|
|
|
|
+ toConsoleOnly "$@"
|
|
|
|
|
+ toLogInfo "$@"
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+toConsoleWarn() {
|
|
|
|
|
+ toConsoleOnly "Warn:" "$@"
|
|
|
|
|
+ toLogWarn "$@"
|
|
|
|
|
+} >&2
|
|
|
|
|
+
|
|
|
|
|
+toConsoleError() {
|
|
|
|
|
+ toConsoleOnly "Error:" "$@"
|
|
|
|
|
+ toLogError "$@"
|
|
|
|
|
+} >&2
|
|
|
|
|
+
|
|
|
|
|
+#== 【0】【3】【4】=创建不存在的目录,并设置权限
|
|
|
|
|
+createDirIfNotExistAndSetRights() {
|
|
|
|
|
+ local dir="${1}"
|
|
|
|
|
+ local rights="${2}"
|
|
|
|
|
+
|
|
|
|
|
+ toConsoleInfo "#DEBUG== createDirIfNotExistAndSetRights --- ${rights} --- ${dir}"
|
|
|
|
|
+ if [ ! -d "${dir}" ]; then
|
|
|
|
|
+ toLogInfo "Creating directory ${dir} with rights ${rights}"
|
|
|
|
|
+ local message
|
|
|
|
|
+ if ! message="$(mkdir -p "${dir}" 2>&1)"; then
|
|
|
|
|
+ toConsoleWarn "Cannot create ${dir} directory."
|
|
|
|
|
+ toLogWarn "Error message: ${message}"
|
|
|
|
|
+ return 1
|
|
|
|
|
+ fi
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ if ! message="$(chmod "${rights}" "${dir}" 2>&1)"; then
|
|
|
|
|
+ toConsoleWarn "Cannot change permisions of ${dir} directory to ${rights}."
|
|
|
|
|
+ toLogWarn "Error message: ${message}"
|
|
|
|
|
+ return 1
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ return 0
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+createCurrentVersionSymlink() {
|
|
|
|
|
+ toLogInfo "Creating symlink to current version..."
|
|
|
|
|
+
|
|
|
|
|
+ local currentVersionLink="${AGENT_BASE_DIR}/current"
|
|
|
|
|
+ local tempLink="${currentVersionLink}.tmp"
|
|
|
|
|
+
|
|
|
|
|
+ if ! commandErrorWrapper ln -s "${AGENT_INSTALLER_VERSION}" "${tempLink}"; then
|
|
|
|
|
+ toLogError "Failed to create current version link"
|
|
|
|
|
+ return
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ if ! commandErrorWrapper arch_moveReplaceTarget "${tempLink}" "${currentVersionLink}"; then
|
|
|
|
|
+ toLogError "Failed to set up current version link"
|
|
|
|
|
+ commandErrorWrapper rm -f "${tempLink}"
|
|
|
|
|
+ return
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ toLogInfo "Current version link created: ${currentVersionLink} -> ${AGENT_INSTALLER_VERSION}"
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【0】=创建日志目录及日志文件installation_$$.log
|
|
|
|
|
+createLogDirsIfMissing() {
|
|
|
|
|
+ createDirIfNotExistAndSetRights "${INSTALL_BASE}" u+rwx,g+rx,o+rx
|
|
|
|
|
+ createDirIfNotExistAndSetRights "${BASE_INSTALL_DIR}" u+rwx,g+rx,o+rx
|
|
|
|
|
+ #== agents根目录
|
|
|
|
|
+ createDirIfNotExistAndSetRights "${AGENT_BASE_DIR}" 1775
|
|
|
|
|
+ createDirIfNotExistAndSetRights "${INSTALL_DIR}" 1775
|
|
|
|
|
+# createDirIfNotExistAndSetRights "${LOG_DIR}" 1777
|
|
|
|
|
+ createDirIfNotExistAndSetRights "${INSTALLER_LOG_DIR}" 1777
|
|
|
|
|
+
|
|
|
|
|
+# for agentLog in ${PLUGIN_LOG_NAMES}; do
|
|
|
|
|
+# createDirIfNotExistAndSetRights "${LOG_DIR}/${agentLog}" 1777
|
|
|
|
|
+# done
|
|
|
|
|
+
|
|
|
|
|
+ touch "${LOG_FILE}"
|
|
|
|
|
+ setRightsForFiles "${LOG_FILE}" 766
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#**********************************************************
|
|
|
|
|
+# Platform characteristics detection
|
|
|
|
|
+#**********************************************************
|
|
|
|
|
+
|
|
|
|
|
+#== 【5】=获取系统发型版本
|
|
|
|
|
+getOsReleasePath() {
|
|
|
|
|
+ local osReleasePath="/etc/os-release"
|
|
|
|
|
+ if [ ! -f "${osReleasePath}" ]; then
|
|
|
|
|
+ osReleasePath="/usr/lib/os-release"
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ printf '%s' "${osReleasePath}"
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+parseOsReleaseFile() {
|
|
|
|
|
+ local osReleasePath="$(getOsReleasePath)"
|
|
|
|
|
+
|
|
|
|
|
+ #shellcheck disable=SC1090
|
|
|
|
|
+ . "${osReleasePath}"
|
|
|
|
|
+ local distrib="${NAME-}"
|
|
|
|
|
+ if [ -z "${distrib}" ]; then
|
|
|
|
|
+ distrib="${ID-}"
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ local version="${VERSION_ID-}"
|
|
|
|
|
+ if printf '%s' "${distrib}" | grep -iq "debian"; then
|
|
|
|
|
+ version="$(cat /etc/debian_version)"
|
|
|
|
|
+ elif printf '%s' "${distrib}" | grep -iq "fedora" && [ "${VARIANT_ID-}" = "coreos" ]; then
|
|
|
|
|
+ distrib="${distrib} CoreOS"
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ printf '%s %s' "${distrib}" "${version}"
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【5】=获取系统发型版本
|
|
|
|
|
+detectLinuxDistribution() {
|
|
|
|
|
+ if [ -f /etc/oracle-release ]; then
|
|
|
|
|
+ cat /etc/oracle-release
|
|
|
|
|
+ elif [ -f /etc/fedora-release ]; then
|
|
|
|
|
+ if [ -f "$(getOsReleasePath)" ]; then
|
|
|
|
|
+ (
|
|
|
|
|
+ parseOsReleaseFile
|
|
|
|
|
+ )
|
|
|
|
|
+ else
|
|
|
|
|
+ cat /etc/fedora-release
|
|
|
|
|
+ fi
|
|
|
|
|
+ elif [ -f /etc/redhat-release ]; then
|
|
|
|
|
+ cat /etc/redhat-release
|
|
|
|
|
+ elif [ -f "$(getOsReleasePath)" ]; then
|
|
|
|
|
+ (
|
|
|
|
|
+ parseOsReleaseFile
|
|
|
|
|
+ )
|
|
|
|
|
+ elif [ -f /etc/SuSE-release ]; then
|
|
|
|
|
+ head -1 /etc/SuSE-release
|
|
|
|
|
+ elif [ -f /etc/lsb-release ]; then
|
|
|
|
|
+ (
|
|
|
|
|
+ . /etc/lsb-release
|
|
|
|
|
+ printf "%s %s" "${DISTRIB_ID-}" "${DISTRIB_RELEASE-}"
|
|
|
|
|
+ )
|
|
|
|
|
+ elif ls /etc/*release* >/dev/null 2>&1; then
|
|
|
|
|
+ # Generic fallback
|
|
|
|
|
+ cat /etc/*release*
|
|
|
|
|
+ else
|
|
|
|
|
+ printf "AIX %s" "$(oslevel -s 2>&1)"
|
|
|
|
|
+ fi
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【3】=检查系统init (INIT_SYSTEM、INIT_SYSTEM_VERSION)
|
|
|
|
|
+checkInitSystem() {
|
|
|
|
|
+ local version
|
|
|
|
|
+ if version="$(systemctl --version 2>&1)"; then
|
|
|
|
|
+ if [ -d "${SYSTEMD_UNIT_FILES_DIR}" ]; then
|
|
|
|
|
+ readonly INIT_SYSTEM=${INIT_SYSTEM_SYSTEMD}
|
|
|
|
|
+ else
|
|
|
|
|
+ readonly INIT_SYSTEM=${INIT_SYSTEM_SYSV}
|
|
|
|
|
+ toLogWarn "${INIT_SYSTEM_SYSTEMD} was detected but ${SYSTEMD_UNIT_FILES_DIR} does not exist, using ${INIT_SYSTEM_SYSV} handling as a fallback"
|
|
|
|
|
+ fi
|
|
|
|
|
+ else
|
|
|
|
|
+ readonly INIT_SYSTEM=${INIT_SYSTEM_SYSV}
|
|
|
|
|
+ if ! version="$(init --version 2>&1)"; then
|
|
|
|
|
+ if ! version="$(chkconfig --version 2>&1)"; then
|
|
|
|
|
+ version="$(head -n1 /etc/inittab 2>&1)"
|
|
|
|
|
+ fi
|
|
|
|
|
+ fi
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ readonly INIT_SYSTEM_VERSION="$(printf '%s' "${version}" 2>/dev/null | head -n1)"
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【3】=设置系统初始化脚本目录
|
|
|
|
|
+setLocationOfScripts() {
|
|
|
|
|
+ toLogInfo "Determining location of scripts..."
|
|
|
|
|
+
|
|
|
|
|
+ if [ "${INIT_SYSTEM}"x = "${INIT_SYSTEM_SYSTEMD}"x ] || [ "${ARCH_ARCH}"x = "AIX"x ]; then
|
|
|
|
|
+ #== /opt/cloudwise/cwserveragent/scripts
|
|
|
|
|
+ readonly INIT_DIR="${AGENT_SCRIPTS_DIR}"
|
|
|
|
|
+ else
|
|
|
|
|
+ if [ -d "/etc/init.d" ]; then
|
|
|
|
|
+ readonly INIT_DIR="/etc/init.d"
|
|
|
|
|
+ elif [ -d "/sbin/init.d" ]; then
|
|
|
|
|
+ readonly INIT_DIR="/sbin/init.d"
|
|
|
|
|
+ elif [ -d "/etc/rc.d" ]; then
|
|
|
|
|
+ readonly INIT_DIR="/etc/rc.d"
|
|
|
|
|
+ else
|
|
|
|
|
+ return 1
|
|
|
|
|
+ fi
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ toLogInfo "Location of scripts ${INIT_DIR}"
|
|
|
|
|
+ return 0
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【0】=检查系统结构(X86_64\IA64\X86)
|
|
|
|
|
+detectArchitecture() {
|
|
|
|
|
+ local detected_arch=
|
|
|
|
|
+ if isAvailable arch; then
|
|
|
|
|
+ #== arch指令主要用于显示当前主机的硬件结构类型,查询结果与uname一致,我们可以看到它输出的结果有:i386、i486、mips、alpha等
|
|
|
|
|
+ detected_arch="$(arch | tr '[:lower:]' '[:upper:]')"
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ if [ -z "${detected_arch}" ]; then
|
|
|
|
|
+ detected_arch="$(uname -m | tr '[:lower:]' '[:upper:]')"
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ printf '%s' "${detected_arch}"
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#**********************************************************
|
|
|
|
|
+# Misc functions
|
|
|
|
|
+#**********************************************************
|
|
|
|
|
+
|
|
|
|
|
+#== 【1】【4】【5】【6】=获取 agent (64\32)位数lib目录(""或lib64)
|
|
|
|
|
+getBinariesFolderByBitness() {
|
|
|
|
|
+ local bitness="${1}"
|
|
|
|
|
+ if [ "${bitness}" -eq 32 ]; then
|
|
|
|
|
+ bitness=""
|
|
|
|
|
+ fi
|
|
|
|
|
+ printf 'lib%s' "${bitness}"
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【1】【2】【5】【6】=获取 agent tools/lib64/smartagentctl 路径
|
|
|
|
|
+#== getAgentCtlBinPath
|
|
|
|
|
+
|
|
|
|
|
+#== 【1】【4】【5】【6】=获取 agent 64位数lib路径(lib64/installaction)
|
|
|
|
|
+#== getAgentInstallActionPath
|
|
|
|
|
+
|
|
|
|
|
+#== 【5】【6】=获取OS bin配置路径 /opt/cloudwise/cwserveragent/lib64/cloudwiseosconfig
|
|
|
|
|
+getOsConfigBinPath() {
|
|
|
|
|
+ printf "%s" "${INSTALL_DIR}/lib64/${AGENT_OS_CONFIG_BIN}"
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【5】=设置agent进程可用
|
|
|
|
|
+setProcessAgentEnabled() {
|
|
|
|
|
+ local enabled="${1}"
|
|
|
|
|
+ toLogInfo "Setting process agent enabled: ${enabled}..."
|
|
|
|
|
+ local changeStatus=
|
|
|
|
|
+ #== 调用 agent 64位数lib路径(lib64/installaction)执行指令 --set-process-agent-enabled
|
|
|
|
|
+ changeStatus=$("$(getAgentInstallActionPath)" --set-process-agent-enabled "${enabled}" 2>&1)
|
|
|
|
|
+ toLogAdaptive $? "Process agent enable(${enabled}) status: ${changeStatus}"
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【1】【4】【5】【6】=获取命令执行错误信息,并写日志
|
|
|
|
|
+commandErrorWrapper() {
|
|
|
|
|
+ local command="${*}"
|
|
|
|
|
+ local errorFile="/tmp/smartagent_commanderror_$$"
|
|
|
|
|
+
|
|
|
|
|
+ ${command} 2>"${errorFile}"
|
|
|
|
|
+ local returnCode=$?
|
|
|
|
|
+
|
|
|
|
|
+ if [ ${returnCode} -ne 0 ]; then
|
|
|
|
|
+ toLogWarn "Command '${command}' failed, return code: ${returnCode}, message: $(cat "${errorFile}")"
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ rm -f "${errorFile}"
|
|
|
|
|
+
|
|
|
|
|
+ return ${returnCode}
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【3】=是否独立的namespace
|
|
|
|
|
+isNamespaceIsolated() {
|
|
|
|
|
+ local pid="${1}"
|
|
|
|
|
+ local namespace="${2}"
|
|
|
|
|
+ local initNamespaceId
|
|
|
|
|
+ local processNamespaceId
|
|
|
|
|
+ initNamespaceId="$(readlink "/proc/1/ns/${namespace}" 2>/dev/null | tr -dc '0-9')"
|
|
|
|
|
+ processNamespaceId="$(readlink "/proc/${pid}/ns/${namespace}" 2>/dev/null | tr -dc '0-9')"
|
|
|
|
|
+
|
|
|
|
|
+ if [ ! "${initNamespaceId}" ] || [ ! "${processNamespaceId}" ]; then
|
|
|
|
|
+ toLogInfo "Link to /proc/*/ns/${namespace} does not exist"
|
|
|
|
|
+ printf 'error'
|
|
|
|
|
+ return
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ if [ "${initNamespaceId}"x != "${processNamespaceId}"x ]; then
|
|
|
|
|
+ printf 'true'
|
|
|
|
|
+ else
|
|
|
|
|
+ printf 'false'
|
|
|
|
|
+ fi
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【0】=检查是否root
|
|
|
|
|
+checkRootAccess() {
|
|
|
|
|
+ toConsoleInfo "Checking root privileges..."
|
|
|
|
|
+
|
|
|
|
|
+ if [ "$(id -u)"x != "0"x ]; then
|
|
|
|
|
+ toConsoleError "NOT OK"
|
|
|
|
|
+ return 1
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ toConsoleInfo "OK"
|
|
|
|
|
+ return 0
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【3】=删除存在的路径
|
|
|
|
|
+removeIfExists() {
|
|
|
|
|
+ local pathToRemove="${1}"
|
|
|
|
|
+ if [ ! -e "${pathToRemove}" ]; then
|
|
|
|
|
+ toLogInfo "${pathToRemove} does not exist, skipping removal"
|
|
|
|
|
+ return
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ local output
|
|
|
|
|
+ if ! output="$(rm -rf "${pathToRemove}" 2>&1)"; then
|
|
|
|
|
+ toLogWarn "Failed to remove ${pathToRemove}: ${output}"
|
|
|
|
|
+ fi
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#**********************************************************
|
|
|
|
|
+# SELinux related functions
|
|
|
|
|
+#**********************************************************
|
|
|
|
|
+
|
|
|
|
|
+#== 【5】【6】=执行 systemctl 命令
|
|
|
|
|
+executeSystemctlCommand() {
|
|
|
|
|
+ local command="${1}"
|
|
|
|
|
+ local unit="${2}"
|
|
|
|
|
+
|
|
|
|
|
+ if [ "$(id -u)" != 0 ]; then
|
|
|
|
|
+ #== 执行使用 os config bin
|
|
|
|
|
+ executeUsingOsConfigBin "${command}" "${unit}"
|
|
|
|
|
+ return $?
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ local output=
|
|
|
|
|
+ #== shellcheck disable=SC2086
|
|
|
|
|
+ #== 执行 systemctl 命令
|
|
|
|
|
+ output="$(systemctl "${command}" ${unit} 2>&1)"
|
|
|
|
|
+ local exitCode=$?
|
|
|
|
|
+
|
|
|
|
|
+ if [ ${exitCode} -eq 0 ]; then
|
|
|
|
|
+ toLogInfo "Successfully executed: systemctl ${command} ${unit}"
|
|
|
|
|
+ else
|
|
|
|
|
+ toLogError "Failed to execute: systemctl ${command} ${unit}"
|
|
|
|
|
+ toLogError "Command output: ${output}"
|
|
|
|
|
+ if [ -n "${unit}" ]; then
|
|
|
|
|
+ local reachBackNumSeconds=360
|
|
|
|
|
+ toLogError "journalctl output: $(journalctl -u "${unit}" --since=-${reachBackNumSeconds} 2>&1)"
|
|
|
|
|
+ fi
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ return ${exitCode}
|
|
|
|
|
+} 2>>"${LOG_FILE}"
|
|
|
|
|
+
|
|
|
|
|
+#== 【6】=运行初始化命令(通过 service 方式 或 直接运行可执行命令)
|
|
|
|
|
+executeInitScriptCommand() {
|
|
|
|
|
+ local command=
|
|
|
|
|
+ local parameters="$*"
|
|
|
|
|
+ local output=
|
|
|
|
|
+ local exitCode=
|
|
|
|
|
+
|
|
|
|
|
+ if isAvailable service; then
|
|
|
|
|
+ command="service"
|
|
|
|
|
+ parameters="${SERVICE_SCRIPT_FILE} ${parameters}"
|
|
|
|
|
+ else
|
|
|
|
|
+ command="${INIT_DIR}/${SERVICE_SCRIPT_FILE}"
|
|
|
|
|
+ fi
|
|
|
|
|
+ output="$("${command}" "${parameters}" 2>&1)"
|
|
|
|
|
+ exitCode=$?
|
|
|
|
|
+ toLogAdaptive ${exitCode} "Executed ${command} ${parameters}, exitCode = ${exitCode}, output: ${output}"
|
|
|
|
|
+ return ${exitCode}
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【0】=信号捕获,并执行回调函数
|
|
|
|
|
+signalHandler() {
|
|
|
|
|
+ local signal="${1}"
|
|
|
|
|
+ local callback="${2}"
|
|
|
|
|
+ toLogWarn "process received signal: ${signal}"
|
|
|
|
|
+ ${callback}
|
|
|
|
|
+ exit ${EXIT_CODE_SIGNAL_RECEIVED}
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【0】=配置信号捕获和回调
|
|
|
|
|
+configureSignalHandling() {
|
|
|
|
|
+ local callback="${1}"
|
|
|
|
|
+ for signal in HUP INT QUIT ABRT ALRM TERM; do
|
|
|
|
|
+ # shellcheck disable=SC2064
|
|
|
|
|
+ trap "signalHandler '${signal}' '${callback}'" ${signal}
|
|
|
|
|
+ done
|
|
|
|
|
+
|
|
|
|
|
+ trap "" PIPE
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【0】删除权限
|
|
|
|
|
+removeSecretsFromString() {
|
|
|
|
|
+ printf "%s" "$*" | sed 's#\(LICENSE=\)[[:alnum:]]\{16\}#\1***#'
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【3】【5】=检查目录写权限
|
|
|
|
|
+testWriteAccessToDir() {
|
|
|
|
|
+ local errorFile="/tmp/smartagent_commandError_$$"
|
|
|
|
|
+ local dir="${1}"
|
|
|
|
|
+ local tmpfilename
|
|
|
|
|
+ if [ "${ARCH_ARCH}"x = "AIX"x ]; then
|
|
|
|
|
+ tmpfilename="${dir}/.tmp_${BRAND_PRODUCT_NAME_LOWER}.$$${RANDOM}"
|
|
|
|
|
+ touch "${tmpfilename}" 2>"${errorFile}"
|
|
|
|
|
+ else
|
|
|
|
|
+ tmpfilename="$(mktemp -p "${dir}" ".tmp_${BRAND_PRODUCT_NAME_LOWER}.XXXXXXXXXXXXXX" 2>"${errorFile}")"
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ #== shellcheck disable=SC2181
|
|
|
|
|
+ if [ $? -ne 0 ]; then
|
|
|
|
|
+ toLogInfo "$(cat "${errorFile}")"
|
|
|
|
|
+ rm -f "${errorFile}"
|
|
|
|
|
+ return 1
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ rm -f "${tmpfilename}" "${errorFile}"
|
|
|
|
|
+ return 0
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【0】=设置PATH
|
|
|
|
|
+setPATH() {
|
|
|
|
|
+ local prependToPATH="/usr/sbin:/usr/bin:/sbin:/bin"
|
|
|
|
|
+ if [ "${PATH}" ]; then
|
|
|
|
|
+ PATH=${prependToPATH}:${PATH}
|
|
|
|
|
+ else
|
|
|
|
|
+ PATH=${prependToPATH}
|
|
|
|
|
+ fi
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【5】【6】=是否非root权限
|
|
|
|
|
+isNonRootModeEnabled() {
|
|
|
|
|
+ #== 调用 agent 64位数lib路径(lib64/installaction)执行指令 --get-drop-root-privileges
|
|
|
|
|
+ local output
|
|
|
|
|
+ output="$(getValueFromConfigFile "${CONF_FIELD_NM_NON_ROOT_MODE}" "${LEGACY_AGENT_CONF_FILE}" "${PARAM_NON_ROOT_MODE}")"
|
|
|
|
|
+ printf '%s' "${output}" | grep -qE "(true|no_ambient)"
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【5】=自动启动工具
|
|
|
|
|
+runAutostartAddingTool() {
|
|
|
|
|
+ local prefix="${1}"
|
|
|
|
|
+ local file="${2}"
|
|
|
|
|
+ local suffix="${3}"
|
|
|
|
|
+ local output
|
|
|
|
|
+
|
|
|
|
|
+ local command="${prefix} ${file} ${suffix}"
|
|
|
|
|
+ toLogInfo "Executing ${command}"
|
|
|
|
|
+ output="$(${command} 2>&1)"
|
|
|
|
|
+ local status=$?
|
|
|
|
|
+ if [ "${output}" ]; then
|
|
|
|
|
+ toLogAdaptive ${status} "${output}"
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ return ${status}
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【0】【5】=查找软链接真实地址(通过ls命令)
|
|
|
|
|
+readLinkFromLs() {
|
|
|
|
|
+ local path="${1}"
|
|
|
|
|
+ local result="${path}"
|
|
|
|
|
+ local lsOutput
|
|
|
|
|
+ local parsedLinkTarget
|
|
|
|
|
+ lsOutput="$(ls -dl "${path}" 2>/dev/null)"
|
|
|
|
|
+ if printf '%s' "${lsOutput}" | grep -q " -> "; then
|
|
|
|
|
+ parsedLinkTarget="$(printf '%s' "${lsOutput}" | sed 's|^.* -> ||')"
|
|
|
|
|
+ if [ "${parsedLinkTarget}" ]; then
|
|
|
|
|
+ result="${parsedLinkTarget}"
|
|
|
|
|
+ else
|
|
|
|
|
+ toLogWarn "Failed to parse ls output '${lsOutput}'"
|
|
|
|
|
+ fi
|
|
|
|
|
+ fi
|
|
|
|
|
+ printf '%s' "${result}"
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【0】【5】=查找软链接真实地址(通过readlink 或 ls 命令)
|
|
|
|
|
+readLink() {
|
|
|
|
|
+ local args=-e
|
|
|
|
|
+ local path="${1}"
|
|
|
|
|
+ if [ "${2}" ]; then
|
|
|
|
|
+ args="${1}"
|
|
|
|
|
+ path="${2}"
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ (
|
|
|
|
|
+ if [ "${ARCH_ARCH}"x = "AIX"x ]; then
|
|
|
|
|
+ path="${PATH}:/opt/freeware/bin"
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ #== 通过 readlink 命令查找地址
|
|
|
|
|
+ if isAvailable readlink; then
|
|
|
|
|
+ #shellcheck disable=SC2086
|
|
|
|
|
+ readlink ${args} "${path}"
|
|
|
|
|
+ else
|
|
|
|
|
+ toLogInfo "readlink command not found, falling back to parsing ls output"
|
|
|
|
|
+ readLinkFromLs "${path}"
|
|
|
|
|
+ fi
|
|
|
|
|
+ )
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【0】【3】【4】【5】【6】=检查命令是否有效/是否存在
|
|
|
|
|
+isAvailable() {
|
|
|
|
|
+ command -v "${1}" >/dev/null 2>&1
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【0】【1】【3】【5】=读取配置文件配置参数信息
|
|
|
|
|
+getValueFromConfigFile() {
|
|
|
|
|
+ local key="${1}"
|
|
|
|
|
+ local configFile="${2}"
|
|
|
|
|
+ local defaultValue="${3}"
|
|
|
|
|
+ local value
|
|
|
|
|
+ value="$(sed -n "s|^${key}=||p" "${configFile}" 2>/dev/null)"
|
|
|
|
|
+
|
|
|
|
|
+ if [ "${value}" ]; then
|
|
|
|
|
+ printf '%s' "${value}"
|
|
|
|
|
+ else
|
|
|
|
|
+ printf '%s' "${defaultValue}"
|
|
|
|
|
+ fi
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【1】【5】=删除配置文件中配置
|
|
|
|
|
+removeValueFromConfigFile() {
|
|
|
|
|
+ local key="${1}"
|
|
|
|
|
+ local configFile="${2}"
|
|
|
|
|
+ local output
|
|
|
|
|
+ if ! output="$(cp -p "${configFile}" "${configFile}.tmp" 2>&1)"; then
|
|
|
|
|
+ toLogWarn "Unable to initialize ${configFile}.tmp file using source file, privileges and ownership will not be preserved: ${output}"
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ if sed "/^${key}/d" "${configFile}" >"${configFile}.tmp"; then
|
|
|
|
|
+ mv -f "${configFile}.tmp" "${configFile}"
|
|
|
|
|
+ else
|
|
|
|
|
+ toLogWarn "Failed to remove ${key} from ${configFile}"
|
|
|
|
|
+ rm -f "${configFile}.tmp"
|
|
|
|
|
+ fi
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 写配置到配置文件信息
|
|
|
|
|
+writeParamToConfigFile() {
|
|
|
|
|
+ local key="${1}"
|
|
|
|
|
+ local newValue="${2}"
|
|
|
|
|
+ local configFile="${3}"
|
|
|
|
|
+ local value
|
|
|
|
|
+ value="$(sed -n "s|^${key}=||p" "${configFile}" 2>/dev/null)"
|
|
|
|
|
+ toConsoleInfo "#DEBUG== writeParamToConfigFile --> edit ${key}=${value} to ${key}=${newValue}, configFile: ${configFile}"
|
|
|
|
|
+ if [ "${value}" ]; then
|
|
|
|
|
+ sed -i "s|^${key}=.*|${key}=${newValue}|" "${configFile}" 2>/dev/null
|
|
|
|
|
+ else
|
|
|
|
|
+ echo "${key}=${newValue}" >>"${configFile}" 2>/dev/null
|
|
|
|
|
+ fi
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+writeContentToConfigFile() {
|
|
|
|
|
+ local newValue="${1}"
|
|
|
|
|
+ local configFile="${2}"
|
|
|
|
|
+ toConsoleInfo "#DEBUG== writeContentToConfigFile --> edit ${newValue}, configFile: ${configFile}"
|
|
|
|
|
+
|
|
|
|
|
+ echo "${newValue}" > "${configFile}" 2>/dev/null
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 修改scripts/smartagent脚本配置信息
|
|
|
|
|
+editScriptFileParam() {
|
|
|
|
|
+ local key="${1}"
|
|
|
|
|
+ local newValue="${2}"
|
|
|
|
|
+ local file="${3}"
|
|
|
|
|
+ local value
|
|
|
|
|
+ value="$(sed -n "s|^${key}=||p" "${file}" 2>/dev/null)"
|
|
|
|
|
+ toConsoleInfo "#DEBUG== editScriptFileParam --> edit ${key}=${value} to ${key}=${newValue}, configFile: ${file}"
|
|
|
|
|
+ if [ "${value}" ]; then
|
|
|
|
|
+ sed -i "s|^${key}=.*|${key}=${newValue}|" "${file}" 2>/dev/null
|
|
|
|
|
+ fi
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【0】=是否存在多个同时安装操作【通过判断 INSTALLER_LOCK_FILE 】
|
|
|
|
|
+isAnotherInstallationRunning() {
|
|
|
|
|
+ if [ ! -f "${INSTALLER_LOCK_FILE}" ]; then
|
|
|
|
|
+ return 1
|
|
|
|
|
+ fi
|
|
|
|
|
+ local pidFromLockFile
|
|
|
|
|
+ local nameFromLockFile
|
|
|
|
|
+ pidFromLockFile="$(head -n 1 "${INSTALLER_LOCK_FILE}")"
|
|
|
|
|
+ nameFromLockFile="$(tail -n 1 "${INSTALLER_LOCK_FILE}")"
|
|
|
|
|
+ if [ "$(wc -l <"${INSTALLER_LOCK_FILE}")" -ne 2 ] || [ -z "${pidFromLockFile}" ] || [ -z "${nameFromLockFile}" ]; then
|
|
|
|
|
+ toConsoleWarn "Installation lock file ${INSTALLER_LOCK_FILE} is damaged, skipping uniqueness check."
|
|
|
|
|
+ toConsoleWarn "Lock file contents: '$(cat ${INSTALLER_LOCK_FILE})'"
|
|
|
|
|
+ return 1
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ #== shellcheck disable=SC2009
|
|
|
|
|
+ #== 获取正在执行安装的进程信息
|
|
|
|
|
+ local foundProcesses
|
|
|
|
|
+ foundProcesses="$(pgrep -f "pid,args" 2>&1 | grep -w "${nameFromLockFile}" | grep -v " grep ")"
|
|
|
|
|
+ if printf '%s' "${foundProcesses}" | awk '{ print $1 }' | grep -wq "${pidFromLockFile}"; then
|
|
|
|
|
+ local errorMessage="Another ${BRAND_PRODUCT_NAME} installer or uninstaller is already running"
|
|
|
|
|
+ if printf '%s' "${foundProcesses}" | grep -q "${DOWNLOADS_DIR}"; then
|
|
|
|
|
+ errorMessage="${errorMessage} (AutoUpdate is in progress)"
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ toConsoleError "${errorMessage}, PID ${pidFromLockFile}. Exiting."
|
|
|
|
|
+ return 0
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ toConsoleInfo "Lock file exists but corresponding installation process does not run, contents of lock file: ${pidFromLockFile}, ${nameFromLockFile}."
|
|
|
|
|
+ return 1
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【0】=创建安装标示文件 /tmp/${BRAND_PRODUCT_NAME_LOWER}.lock
|
|
|
|
|
+createInstallationLockFile() {
|
|
|
|
|
+ printf '%s\n%s\n' "$$" "$0" >"${INSTALLER_LOCK_FILE}" 2>/dev/null
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【0】【6】删除安装标示文件 /tmp/${BRAND_PRODUCT_NAME_LOWER}.lock
|
|
|
|
|
+removeInstallationLockFile() {
|
|
|
|
|
+ toLogInfo "Removing installation lock file."
|
|
|
|
|
+ rm -f "${INSTALLER_LOCK_FILE}"
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【0】基础启动日志信息
|
|
|
|
|
+logBasicStartupInformation() {
|
|
|
|
|
+ toLogInfo "Command line: $(removeSecretsFromString "${@}")"
|
|
|
|
|
+ toLogInfo "Shell options: $-"
|
|
|
|
|
+ toLogInfo "Working dir: $(pwd)"
|
|
|
|
|
+ toLogInfo "PID: $$"
|
|
|
|
|
+ toLogInfo "Parent process: $(
|
|
|
|
|
+ printf '\n'
|
|
|
|
|
+ ps -o user,pid,ppid,comm -p ${PPID} 2>&1
|
|
|
|
|
+ )"
|
|
|
|
|
+ toLogInfo "User id: $(id -u)"
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 解压文件编码
|
|
|
|
|
+readonly UNPACK_BINARY=base64
|
|
|
|
|
+#== 解压文件编码参数
|
|
|
|
|
+readonly UNPACK_BINARY_ARGS="-di"
|
|
|
|
|
+
|
|
|
|
|
+readonly ARCH_ARCH="X86"
|
|
|
|
|
+
|
|
|
|
|
+#== 【0】=检查系统指令集(X86_64\IA64\X86)
|
|
|
|
|
+arch_checkArchitectureCompatibility() {
|
|
|
|
|
+ #== 【0】=检查系统结构(X86_64)
|
|
|
|
|
+ local arch
|
|
|
|
|
+ arch="$(detectArchitecture)"
|
|
|
|
|
+ if [ "${arch}"x = "X86_64"x ] || [ "${arch}"x = "IA64"x ]; then
|
|
|
|
|
+ arch="X86_64"
|
|
|
|
|
+ else
|
|
|
|
|
+ arch="$(uname -m | sed -e 's/i.86/x86/' | sed -e 's/i86pc/x86/' | tr '[:lower:]' '[:upper:]')"
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ printf '%s' "${arch}"
|
|
|
|
|
+ [ "${arch}"x = "X86_64"x ] || [ "${arch}"x = "AARCH64"x ]
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【5】=获取 lib 目录
|
|
|
|
|
+arch_getLibMacro() {
|
|
|
|
|
+ local libMacro=""
|
|
|
|
|
+ if [ "${SYSTEM_LIB32}" ]; then
|
|
|
|
|
+ #== shellcheck disable=SC2016
|
|
|
|
|
+ libMacro="/${LIB}"
|
|
|
|
|
+ fi
|
|
|
|
|
+ printf "%s" "${libMacro}"
|
|
|
|
|
+}
|
|
|
|
|
+#== 'timeout' requires gnu-coreutils8, i.e. it is not available on RHEL5, that's why we need this utility function
|
|
|
|
|
+#== 【3】【5】=执行命令超时配置
|
|
|
|
|
+
|
|
|
|
|
+#== 【0】【3】=获取文件权限信息
|
|
|
|
|
+arch_getAccessRights() {
|
|
|
|
|
+ stat --format='%A' "${1}"
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【4】=替换目录
|
|
|
|
|
+arch_moveReplaceTarget() {
|
|
|
|
|
+ local source="${1}"
|
|
|
|
|
+ local target="${2}"
|
|
|
|
|
+ mv -fT "${source}" "${target}"
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+#== xz 压缩包文件名 Cloudwise-SmartAgent
|
|
|
|
|
+readonly INTERNAL_TAR_FILE_NAME=${BRAND_FORMAL_NAME}-${BRAND_PRODUCT_NAME}.tar.xz
|
|
|
|
|
+
|
|
|
|
|
+#== -安装日志: installation-{timestamp}.log,如,installation-20220601110912.log
|
|
|
|
|
+readonly LOG_FILE="${INSTALLER_LOG_DIR}/installation-$(date -u +"%Y%m%d%H%M%S").log"
|
|
|
|
|
+#readonly LOG_FILE="${INSTALLER_LOG_DIR}/installation_$$.log"
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+#== 【临时目录】安装临时目录
|
|
|
|
|
+readonly TMP_DIR=${INSTALL_DIR}_install_$$
|
|
|
|
|
+#== 【临时目录】解压缓存目录
|
|
|
|
|
+readonly UNPACK_CACHE=${BASE_INSTALL_DIR}/unpack_cache
|
|
|
|
|
+#== 【临时目录】从sh文件读取压缩文件 tarfile_$$.base64
|
|
|
|
|
+readonly EXTERNAL_TAR_FILE=${BASE_INSTALL_DIR}/tarfile_$$.base64
|
|
|
|
|
+#== 【临时目录】xz 压缩包文件
|
|
|
|
|
+readonly INTERNAL_TAR_FILE=${INSTALL_DIR}/${INTERNAL_TAR_FILE_NAME}
|
|
|
|
|
+
|
|
|
|
|
+#== 【0】=
|
|
|
|
|
+readonly INSTALLER_FILE=${0}
|
|
|
|
|
+#== 旧配置文件
|
|
|
|
|
+readonly LEGACY_AGENT_CONF_FILE="${AGENT_CONF_DIR}/${BRAND_PRODUCT_NAME_LOWER}.conf"
|
|
|
|
|
+
|
|
|
|
|
+#== 【0】=
|
|
|
|
|
+readonly LINES_TO_SEARCH_FOR_SIGNATURE_AND_PARAMS=50
|
|
|
|
|
+
|
|
|
|
|
+#== 【0】=
|
|
|
|
|
+readonly HELP_URL=""
|
|
|
|
|
+
|
|
|
|
|
+readonly CONF_FIELD_NM_DATA_SERVER="DataServer"
|
|
|
|
|
+readonly CONF_FIELD_NM_CONFIG_SERVER="ConfigServer"
|
|
|
|
|
+readonly CONF_FIELD_NM_LICENSE="License"
|
|
|
|
|
+readonly CONF_FIELD_NM_JSON_CONF="JSON_CONF"
|
|
|
|
|
+readonly CONF_FIELD_NM_USER="User"
|
|
|
|
|
+readonly CONF_FIELD_NM_GROUP="Group"
|
|
|
|
|
+readonly CONF_FIELD_NM_DATA_STORAGE="DataStorage"
|
|
|
|
|
+readonly CONF_FIELD_NM_NON_ROOT_MODE="NonRootMode"
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+#== 配置默认用户权限
|
|
|
|
|
+readonly BASE_OMNI_INSTALL_DIR=${INSTALL_BASE}/${BRAND_FORMAL_NAME_LOWER}/${BRAND_PARENT_PRODUCT_NAME}
|
|
|
|
|
+readonly BASE_OMNI_INSTALL_CONF_DIR=${BASE_OMNI_INSTALL_DIR}/conf/installation.conf
|
|
|
|
|
+BRAND_AGENT_DEFAULT_USER_AND_GROUP_NAME="$(getValueFromConfigFile "${CONF_FIELD_NM_GROUP}" "${BASE_OMNI_INSTALL_CONF_DIR}" "${BRAND_AGENT_DEFAULT_USER_AND_GROUP_NAME_CLOUDWISE}")"
|
|
|
|
|
+
|
|
|
|
|
+#== Those are read from params section appended to installer by the server
|
|
|
|
|
+#== 【0】=【参数】数据服务地址
|
|
|
|
|
+PARAM_DATA_SERVER=
|
|
|
|
|
+#== 【0】=【参数】配置服务地址
|
|
|
|
|
+PARAM_CONFIG_SERVER=
|
|
|
|
|
+#== 【0】=【参数】license
|
|
|
|
|
+PARAM_LICENSE=
|
|
|
|
|
+
|
|
|
|
|
+PARAM_JSON_CONF=
|
|
|
|
|
+
|
|
|
|
|
+#== 【0】=【参数】安装路径
|
|
|
|
|
+PARAM_INSTALL_DIR=${INSTALL_DIR}
|
|
|
|
|
+#== 【0】=【参数】用户
|
|
|
|
|
+PARAM_USER=
|
|
|
|
|
+#== 【0】=【参数】用户组
|
|
|
|
|
+PARAM_GROUP=
|
|
|
|
|
+#== 【0】=【参数】非root模式
|
|
|
|
|
+PARAM_NON_ROOT_MODE=true
|
|
|
|
|
+
|
|
|
|
|
+PARAM_USER_LOGIN=false
|
|
|
|
|
+
|
|
|
|
|
+#== 【0】=【参数】不允许root回退
|
|
|
|
|
+PARAM_DISABLE_ROOT_FALLBACK=false
|
|
|
|
|
+#== 【0】=【参数】数据存储目录
|
|
|
|
|
+PARAM_DATA_STORAGE=
|
|
|
|
|
+#== 【0】=【参数】通过容器部署
|
|
|
|
|
+#== PARAM_INTERNAL_DEPLOYED_VIA_CONTAINER=false
|
|
|
|
|
+#== 【0】=【参数】跳过SELinux策略安装
|
|
|
|
|
+#== PARAM_INTERNAL_SKIP_SELINUX_POLICY_INSTALLER=false
|
|
|
|
|
+#== 【0】=【参数】是否使用解压缓存
|
|
|
|
|
+PARAM_INTERNAL_USE_UNPACK_CACHE=false
|
|
|
|
|
+#== 【0】=【参数】是否不使用 dump
|
|
|
|
|
+#== PARAM_INTERNAL_DISABLE_DUMPPROC=
|
|
|
|
|
+#== 【0】=【参数】是否跳过非root检查
|
|
|
|
|
+PARAM_INTERNAL_NON_ROOT_MODE_SKIP_PRIVILEGES_CHECK=false
|
|
|
|
|
+#== 【0】【1】=【参数】额外的配置
|
|
|
|
|
+#== PARAM_INTERNAL_PASS_THROUGH_SETTERS=
|
|
|
|
|
+#== 【0】=检查是否降级安装
|
|
|
|
|
+SKIP_DOWNGRADE_CHECK=false
|
|
|
|
|
+
|
|
|
|
|
+SKIP_PRIVILEGES_CHECK=false
|
|
|
|
|
+
|
|
|
|
|
+#== 自定义字符串参数
|
|
|
|
|
+PARAM_TEST=
|
|
|
|
|
+#== 自定义字BOOL参数
|
|
|
|
|
+PARAM_BOOL=
|
|
|
|
|
+
|
|
|
|
|
+#== 【0】=常规日志
|
|
|
|
|
+initializeLog() {
|
|
|
|
|
+ toConsoleInfo "Installation started, version ${AGENT_INSTALLER_VERSION}, build date: ${AGENT_BUILD_DATE}, PID $$."
|
|
|
|
|
+ toLogInfo "Started from: ${INSTALLER_FILE}"
|
|
|
|
|
+
|
|
|
|
|
+ if [ -f /proc/version ]; then
|
|
|
|
|
+ toLogInfo "System version: $(cat /proc/version)"
|
|
|
|
|
+ else
|
|
|
|
|
+ toLogInfo "System version: $(uname -a)"
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ toLogInfo "Path: ${PATH}"
|
|
|
|
|
+ toLogInfo "INSTALL_DIR: ${INSTALL_DIR}"
|
|
|
|
|
+ toLogInfo "Resolved installation path: $(readLink -e "${INSTALL_DIR}" 2>/dev/null)"
|
|
|
|
|
+ logBasicStartupInformation "${@}"
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#**********************************************************
|
|
|
|
|
+# Signing related stuff
|
|
|
|
|
+#**********************************************************
|
|
|
|
|
+#== 【0】【4】=通过占位分割读取位置
|
|
|
|
|
+locateDelimiter() {
|
|
|
|
|
+ #== 占位符
|
|
|
|
|
+ local delimiter="${1}"
|
|
|
|
|
+ #== 从文件结尾读取行数
|
|
|
|
|
+ local linesToReadFromEnd="${2}"
|
|
|
|
|
+ local linesCount
|
|
|
|
|
+ local offset
|
|
|
|
|
+ if [ "${linesToReadFromEnd}" ]; then
|
|
|
|
|
+ #== 文件总行数n(实际行数=n+1)
|
|
|
|
|
+ linesCount="$(wc -l "${INSTALLER_FILE}" | awk '{print $1}')"
|
|
|
|
|
+ #== 从后往前读取【linesToReadFromEnd】行
|
|
|
|
|
+ offset="$(tail -n"${linesToReadFromEnd}" "${INSTALLER_FILE}" 2>/dev/null | awk '/^'"${delimiter}"'/ { print NR; exit }')"
|
|
|
|
|
+ if [ -n "${offset}" ]; then
|
|
|
|
|
+ printf "%d" "$((linesCount - linesToReadFromEnd + offset))"
|
|
|
|
|
+ fi
|
|
|
|
|
+ else
|
|
|
|
|
+ #== 读取占位符所在行(实际行数=n+1)
|
|
|
|
|
+ awk '/^'"${delimiter}"'/ { print NR; exit }' "${INSTALLER_FILE}"
|
|
|
|
|
+ fi
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【0】=从指定行范围读取配置参数
|
|
|
|
|
+readParam() {
|
|
|
|
|
+ local paramName="${1}"
|
|
|
|
|
+ local paramsSectionBeggining="${2}"
|
|
|
|
|
+ local paramsSectionEnd="${3}"
|
|
|
|
|
+
|
|
|
|
|
+ sed -n "${paramsSectionBeggining},${paramsSectionEnd} s/^${paramName}=//p" "${INSTALLER_FILE}"
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【0】=读取以【----PARAMETERS】开始到 【----PARAMETERS--】之间的参数
|
|
|
|
|
+readParamsSection() {
|
|
|
|
|
+ local sectionName="----PARAMETERS"
|
|
|
|
|
+ local begin
|
|
|
|
|
+ local end
|
|
|
|
|
+ begin=$(locateDelimiter "${sectionName}" ${LINES_TO_SEARCH_FOR_SIGNATURE_AND_PARAMS})
|
|
|
|
|
+ end=$(locateDelimiter "${sectionName}--" ${LINES_TO_SEARCH_FOR_SIGNATURE_AND_PARAMS})
|
|
|
|
|
+
|
|
|
|
|
+ if [ -z "${begin}" ] || [ -z "${end}" ]; then
|
|
|
|
|
+ return
|
|
|
|
|
+ fi
|
|
|
|
|
+ #== 从指定行范围读取配置参数
|
|
|
|
|
+ local value
|
|
|
|
|
+ if value="$(readParam PARAM_DATA_SERVER "${begin}" "${end}")"; then
|
|
|
|
|
+ PARAM_DATA_SERVER="${value}"
|
|
|
|
|
+ fi
|
|
|
|
|
+ if value="$(readParam PARAM_CONFIG_SERVER "${begin}" "${end}")"; then
|
|
|
|
|
+ PARAM_CONFIG_SERVER="${value}"
|
|
|
|
|
+ fi
|
|
|
|
|
+ if value="$(readParam PARAM_LICENSE "${begin}" "${end}")"; then
|
|
|
|
|
+ PARAM_LICENSE="${value}"
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ if value="$(readParam PARAM_JSON_CONF "${begin}" "${end}")"; then
|
|
|
|
|
+ PARAM_JSON_CONF="${value}"
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ if value="$(readParam PARAM_USER "${begin}" "${end}")"; then
|
|
|
|
|
+ PARAM_USER="${value}"
|
|
|
|
|
+ fi
|
|
|
|
|
+ if value="$(readParam PARAM_GROUP "${begin}" "${end}")"; then
|
|
|
|
|
+ PARAM_GROUP="${value}"
|
|
|
|
|
+ fi
|
|
|
|
|
+ if value="$(readParam PARAM_NON_ROOT_MODE "${begin}" "${end}")"; then
|
|
|
|
|
+ if value="$(getBoolParam "${value}")"; then
|
|
|
|
|
+ PARAM_NON_ROOT_MODE="${value}"
|
|
|
|
|
+ fi
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ if value="$(readParam PARAM_USER_LOGIN "${begin}" "${end}")"; then
|
|
|
|
|
+ if value="$(getBoolParam "${value}")"; then
|
|
|
|
|
+ PARAM_USER_LOGIN="${value}"
|
|
|
|
|
+ fi
|
|
|
|
|
+ fi
|
|
|
|
|
+ toConsoleInfo "#DEBUG== install sh params, DATA_SERVER: ${PARAM_DATA_SERVER}, PARAM_CONFIG_SERVER: ${PARAM_CONFIG_SERVER}, PARAM_LICENSE:${PARAM_LICENSE}"
|
|
|
|
|
+ toConsoleInfo "#DEBUG== install sh params, PARAM_USER: ${PARAM_USER}, PARAM_GROUP: ${PARAM_GROUP}, PARAM_USER_LOGIN: ${PARAM_USER_LOGIN}, PARAM_NON_ROOT_MODE:${PARAM_NON_ROOT_MODE}"
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【0】【6】=清空安装临时文件
|
|
|
|
|
+#== ${INSTALL_DIR}_install_$$
|
|
|
|
|
+#== EXTERNAL_TAR_FILE=${INSTALL_DIR}/tarfile_$$.base64
|
|
|
|
|
+#== ${INSTALL_DIR}/Dynatrace-OneAgent.tar.xz
|
|
|
|
|
+#== ${INSTALL_DIR}/xzdec
|
|
|
|
|
+#== /tmp/${BRAND_PRODUCT_NAME_LOWER}.lock
|
|
|
|
|
+cleanInstallationTemporaryFiles() {
|
|
|
|
|
+ toLogInfo "Cleaning installation temporary files"
|
|
|
|
|
+
|
|
|
|
|
+ rm -f "${EXTERNAL_TAR_FILE}" "${INTERNAL_TAR_FILE}" "${INSTALL_DIR}/xzdec"
|
|
|
|
|
+ rm -Rf "${TMP_DIR}"
|
|
|
|
|
+
|
|
|
|
|
+ local keepInstallationLockFile="${1}"
|
|
|
|
|
+ if [ -z "${keepInstallationLockFile}" ]; then
|
|
|
|
|
+ removeInstallationLockFile
|
|
|
|
|
+ fi
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 完成安装后清理临时目录
|
|
|
|
|
+finishInstallation() {
|
|
|
|
|
+ if [ $# -eq 2 ]; then
|
|
|
|
|
+ cleanInstallationTemporaryFiles "${2}"
|
|
|
|
|
+ else
|
|
|
|
|
+ cleanInstallationTemporaryFiles ""
|
|
|
|
|
+ fi
|
|
|
|
|
+ toLogInfo "Installation finished, PID $$, exit code: ${1}."
|
|
|
|
|
+ changeWorkingDir "${CURR_PATH}"
|
|
|
|
|
+ if [ "${CONF_LD_PRELOAD}"x = "true"x ]; then
|
|
|
|
|
+ exec /bin/bash && exit 0
|
|
|
|
|
+ fi
|
|
|
|
|
+ exit "${1}"
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#**********************************************************
|
|
|
|
|
+# Create folders, copy files, set rights
|
|
|
|
|
+#**********************************************************
|
|
|
|
|
+
|
|
|
|
|
+#== 【3】=创建临时目录
|
|
|
|
|
+prepareTempFolder() {
|
|
|
|
|
+ #== 删除存在的路径
|
|
|
|
|
+ removeIfExists "${TMP_DIR}"
|
|
|
|
|
+
|
|
|
|
|
+ toLogInfo "Creating temporary folder $TMP_DIR"
|
|
|
|
|
+ createDirIfNotExistAndSetRights "${TMP_DIR}" 755
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【4】=设置文件可执行权限
|
|
|
|
|
+setRightsForFiles() {
|
|
|
|
|
+ local file="${1}"
|
|
|
|
|
+ local perms="${2}"
|
|
|
|
|
+
|
|
|
|
|
+ if [ -e "${file}" ]; then
|
|
|
|
|
+ chmod "${perms}" "${file}"
|
|
|
|
|
+ fi
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+setRightsForDir() {
|
|
|
|
|
+ local dir="${1}"
|
|
|
|
|
+ local perms="${2}"
|
|
|
|
|
+
|
|
|
|
|
+ if [ -d "${dir}" ]; then
|
|
|
|
|
+ chmod -R "${perms}" "${dir}"
|
|
|
|
|
+ fi
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【4】=安装类型(f:文件,d:目录)递归设置权限
|
|
|
|
|
+chmod4FilesRecursively() {
|
|
|
|
|
+ local dir="${1}"
|
|
|
|
|
+ local type="${2}"
|
|
|
|
|
+ local mask="${3}"
|
|
|
|
|
+ find "${dir}" -type "${type}" -exec chmod "${mask}" {} \;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【4】=移动目录到指定位置
|
|
|
|
|
+moveFolderToDestination() {
|
|
|
|
|
+ local source="${1}"
|
|
|
|
|
+ local destination="${2}"
|
|
|
|
|
+ local fullDestination
|
|
|
|
|
+ fullDestination="${destination}/$(basename "${source}")"
|
|
|
|
|
+ local output
|
|
|
|
|
+
|
|
|
|
|
+ toLogInfo "Moving ${source} to ${destination}"
|
|
|
|
|
+ if [ ! -e "${fullDestination}" ]; then
|
|
|
|
|
+ if output="$(mv -f "${source}" "${destination}" 2>&1)"; then
|
|
|
|
|
+ toLogInfo "Moving Successfully."
|
|
|
|
|
+ return
|
|
|
|
|
+ fi
|
|
|
|
|
+ toLogWarn "Failed to move ${source} to ${destination}: ${output}, attempting to copy"
|
|
|
|
|
+ else
|
|
|
|
|
+ toLogInfo "${fullDestination} already exists, attempting to copy"
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ if ! output="$(cp -Rfp "${source}" "${destination}" 2>&1)"; then
|
|
|
|
|
+ toLogError "Failed to copy ${source} to ${destination}: ${output}"
|
|
|
|
|
+ fi
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【4】=将 bin 下版本内容移动到安装目录
|
|
|
|
|
+installVersionedContent() {
|
|
|
|
|
+ toLogInfo "Installing versioned content..."
|
|
|
|
|
+ createDirIfNotExistAndSetRights "${AGENT_BIN_DIR}" 755
|
|
|
|
|
+
|
|
|
|
|
+ local sourceDir="${TMP_DIR}/bin"
|
|
|
|
|
+ if [ ! -d "${AGENT_BIN_DIR}" ]; then
|
|
|
|
|
+ moveFolderToDestination "${sourceDir}" "${AGENT_BIN_DIR}"
|
|
|
|
|
+ return
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ toLogInfo "Directory ${AGENT_BIN_DIR} already exist, repairing the directory"
|
|
|
|
|
+ rm -rf "${AGENT_BIN_DIR}"
|
|
|
|
|
+ moveFolderToDestination "${sourceDir}" "${AGENT_BIN_DIR}"
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【4】=创建当前版本软连接
|
|
|
|
|
+
|
|
|
|
|
+#== 【4】=删除存在的目录
|
|
|
|
|
+listAndRemoveDirectoryIfExists() {
|
|
|
|
|
+ local directory="${1}"
|
|
|
|
|
+ if [ -d "${directory}" ]; then
|
|
|
|
|
+ toLogInfo "${directory} exists, removing it."
|
|
|
|
|
+ toLogInfo "Contents: $(ls -lR "${directory}")"
|
|
|
|
|
+ rm -rf "${directory}"
|
|
|
|
|
+ fi
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【4】=临时目录中conf 移动到 agent 安装目录中
|
|
|
|
|
+setupConfFolder() {
|
|
|
|
|
+ toLogInfo "Setup conf folder..."
|
|
|
|
|
+ #== 移动目录到指定位置
|
|
|
|
|
+ moveFolderToDestination "${TMP_DIR}/conf" "${INSTALL_DIR}"
|
|
|
|
|
+
|
|
|
|
|
+ chmod 755 "${AGENT_CONF_DIR}"
|
|
|
|
|
+
|
|
|
|
|
+ toLogInfo "Setup conf done."
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【4】=给距离当前目录至少 ${mindepth} 个子目录的所有文件设置权限
|
|
|
|
|
+chmodFilesWithMindepth() {
|
|
|
|
|
+ local dir="${1}"
|
|
|
|
|
+ local mindepth="${2}"
|
|
|
|
|
+ local mask="${3}"
|
|
|
|
|
+
|
|
|
|
|
+ if [ "${ARCH_ARCH}"x = "AIX"x ]; then
|
|
|
|
|
+ #== 安装类型(f:文件,d:目录)递归设置权限
|
|
|
|
|
+ chmod4FilesRecursively "${1}" f "${3}"
|
|
|
|
|
+ else
|
|
|
|
|
+ #== 查找深度距离当前目录至少 ${mindepth} 个子目录的所有文件
|
|
|
|
|
+ find "${dir}" -mindepth "${mindepth}" -print0 | xargs -r -0 chmod "${mask}"
|
|
|
|
|
+ fi
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【4】=配置其他文件(cwserveragent.service、installer.version)
|
|
|
|
|
+setupMiscFiles() {
|
|
|
|
|
+ toLogInfo "Setup misc files..."
|
|
|
|
|
+ #== 创建 cwserveragent.service
|
|
|
|
|
+ createSystemdUnitFile
|
|
|
|
|
+ #== echo "${AGENT_INSTALLER_VERSION}" >"${INSTALL_DIR}/installer.version"
|
|
|
|
|
+ mv -f "${TMP_DIR}/installer.version" "${INSTALL_DIR}/"
|
|
|
|
|
+ toLogInfo "Setup misc done."
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【4】=创建 cwserveragent.service
|
|
|
|
|
+createSystemdUnitFile() {
|
|
|
|
|
+ toLogInfo "creating init scripts ${AGENT_SCRIPTS_DIR}"
|
|
|
|
|
+ if [ "${INIT_SYSTEM}"x = "${INIT_SYSTEM_SYSV}"x ]; then
|
|
|
|
|
+ return
|
|
|
|
|
+ fi
|
|
|
|
|
+ createDirIfNotExistAndSetRights "${AGENT_SCRIPTS_DIR}" 755
|
|
|
|
|
+ cat <<EOF >${AGENT_SCRIPTS_DIR}/${SYSTEMD_UNIT_FILE_AGENT}
|
|
|
|
|
+[Unit]
|
|
|
|
|
+Description=${BRAND_AGENT_PRODUCT_NAME}
|
|
|
|
|
+After=network-online.target
|
|
|
|
|
+Wants=network-online.target
|
|
|
|
|
+
|
|
|
|
|
+[Service]
|
|
|
|
|
+User=root
|
|
|
|
|
+ExecStart=${AGENT_SCRIPTS_DIR}/${SERVICE_SCRIPT_FILE} start
|
|
|
|
|
+ExecStop=${AGENT_SCRIPTS_DIR}/${SERVICE_SCRIPT_FILE} stop
|
|
|
|
|
+Type=forking
|
|
|
|
|
+#Restart=always
|
|
|
|
|
+KillMode=process
|
|
|
|
|
+TimeoutSec=240
|
|
|
|
|
+
|
|
|
|
|
+[Install]
|
|
|
|
|
+WantedBy=multi-user.target
|
|
|
|
|
+EOF
|
|
|
|
|
+
|
|
|
|
|
+ setRightsForFiles "${AGENT_SCRIPTS_DIR}/${SYSTEMD_UNIT_FILE_AGENT}" 755
|
|
|
|
|
+ if [ "${INIT_DIR}"x != "${AGENT_SCRIPTS_DIR}"x ]; then
|
|
|
|
|
+ cp -f "${AGENT_SCRIPTS_DIR}/${SYSTEMD_UNIT_FILE_AGENT}" ${INIT_DIR}
|
|
|
|
|
+ toLogInfo "Copy scripts ${AGENT_SCRIPTS_DIR}/${SYSTEMD_UNIT_FILE_AGENT} to ${INIT_DIR} done."
|
|
|
|
|
+ fi
|
|
|
|
|
+ toLogInfo "creating init scripts ${AGENT_SCRIPTS_DIR} done."
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+setupAll() {
|
|
|
|
|
+# moveFolderToDestination "${TMP_DIR}/package_dir/*" "${INSTALL_DIR}"
|
|
|
|
|
+#ls ${TMP_DIR}/package_dir/*
|
|
|
|
|
+
|
|
|
|
|
+ #== 移动所有文件到目录
|
|
|
|
|
+ cp -Rfp ${TMP_DIR}/package_dir/* "${INSTALL_DIR}"
|
|
|
|
|
+ local installVersionFile="${INSTALL_DIR}/installer.version"
|
|
|
|
|
+ echo ${AGENT_INSTALLER_VERSION} > ${installVersionFile}
|
|
|
|
|
+# mv ${INSTALL_DIR}/package_dir/* ${INSTALL_DIR}
|
|
|
|
|
+# echo "${TMP_DIR}/*" "${INSTALL_DIR}/"
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【4】=配置 lib、conf、bin、cwserveragent.service、installer.version、plugins
|
|
|
|
|
+setupOptDir() {
|
|
|
|
|
+ createDirIfNotExistAndSetRights "${INSTALL_DIR}" 1775
|
|
|
|
|
+ #== 临时目录中conf 移动到 agent 安装目录中
|
|
|
|
|
+ setupConfFolder
|
|
|
|
|
+ #== 将 bin 下版本内容移动到安装目录
|
|
|
|
|
+ installVersionedContent
|
|
|
|
|
+ #== 配置其他文件(cwserveragent.service、installer.version)
|
|
|
|
|
+ setupMiscFiles
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【4】=复制临时目录 scripts/cwserveragent 到指定目录下
|
|
|
|
|
+copyScriptsToDirectory() {
|
|
|
|
|
+ local scriptLocation="${1}"
|
|
|
|
|
+ #== scripts/cwserveragent
|
|
|
|
|
+ local scriptFile="${TMP_DIR}/scripts/${SERVICE_SCRIPT_FILE}"
|
|
|
|
|
+
|
|
|
|
|
+ toLogInfo "Copy scripts ${scriptFile} to ${scriptLocation} begin."
|
|
|
|
|
+
|
|
|
|
|
+ local output
|
|
|
|
|
+ if ! output="$(cp "${scriptFile}" "${scriptLocation}/" 2>&1)"; then
|
|
|
|
|
+ toLogError "Failed to copy ${scriptFile} to ${scriptLocation}, output: ${output}"
|
|
|
|
|
+ return
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ setRightsForFiles "${scriptLocation}/${SERVICE_SCRIPT_FILE}" 755
|
|
|
|
|
+ toLogInfo "Copy scripts ${scriptFile} to ${scriptLocation} done."
|
|
|
|
|
+
|
|
|
|
|
+ #== scripts/uninstall.sh
|
|
|
|
|
+# local scriptLocation="${1}"
|
|
|
|
|
+# #== scripts/cwserveragent
|
|
|
|
|
+# local scriptFile="${TMP_DIR}/scripts/uninstall.sh"
|
|
|
|
|
+#
|
|
|
|
|
+# toLogInfo "Copy scripts ${scriptFile} to ${scriptLocation} begin."
|
|
|
|
|
+#
|
|
|
|
|
+# local output
|
|
|
|
|
+# if ! output="$(cp "${scriptFile}" "${scriptLocation}/" 2>&1)"; then
|
|
|
|
|
+# toLogError "Failed to copy ${scriptFile} to ${scriptLocation}, output: ${output}"
|
|
|
|
|
+# return
|
|
|
|
|
+# fi
|
|
|
|
|
+# setRightsForFiles "${scriptLocation}/uninstall.sh" 755
|
|
|
|
|
+# toLogInfo "Copy scripts ${scriptFile} to ${scriptLocation} done."
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【4】=复制临时目录 scripts/cwserveragent 到指定目录下
|
|
|
|
|
+copyScripts() {
|
|
|
|
|
+ toLogInfo "Copy scripts..."
|
|
|
|
|
+ #== 创建目录 /opt/cloudwise/cwserveragent/scripts
|
|
|
|
|
+ createDirIfNotExistAndSetRights "${AGENT_SCRIPTS_DIR}" 755
|
|
|
|
|
+ #== 创建目录 /opt/cloudwise/{product}/agents
|
|
|
|
|
+ createDirIfNotExistAndSetRights "${AGENTS_BASE_DIR}" 775
|
|
|
|
|
+ #== 创建目录 /opt/cloudwise/{product}/meta
|
|
|
|
|
+ createDirIfNotExistAndSetRights "${META_BASE_DIR}" 775
|
|
|
|
|
+ #== 创建目录 /opt/cloudwise/{product}/runtime
|
|
|
|
|
+ createDirIfNotExistAndSetRights "${AGENT_RUNTIME_DIR}" 775
|
|
|
|
|
+
|
|
|
|
|
+ #== scripts/uninstall.sh
|
|
|
|
|
+ local uninstallScript="${TMP_DIR}/scripts/uninstall.sh"
|
|
|
|
|
+ toLogInfo "Copy scripts ${uninstallScript} to ${INSTALL_DIR} begin."
|
|
|
|
|
+ local output
|
|
|
|
|
+ if ! output="$(cp "${uninstallScript}" "${INSTALL_DIR}/uninstall.sh" 2>&1)"; then
|
|
|
|
|
+ toLogError "Failed to copy ${uninstallScript} to ${INSTALL_DIR}/uninstall.sh, output: ${output}"
|
|
|
|
|
+ else
|
|
|
|
|
+ setRightsForFiles "${INSTALL_DIR}/uninstall.sh" 755
|
|
|
|
|
+ fi
|
|
|
|
|
+ toLogInfo "Copy scripts ${uninstallScript} to ${INSTALL_DIR} done."
|
|
|
|
|
+
|
|
|
|
|
+ #== 复制临时目录 scripts/ 到安装目录 /opt/cloudwise/cwserveragent/scripts
|
|
|
|
|
+ copyScriptsToDirectory "${AGENT_SCRIPTS_DIR}"
|
|
|
|
|
+ if [ "${INIT_DIR}"x != "${AGENT_SCRIPTS_DIR}"x ]; then
|
|
|
|
|
+ copyScriptsToDirectory "${INIT_DIR}"
|
|
|
|
|
+ fi
|
|
|
|
|
+ toLogInfo "Copy scripts done."
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【4】=调用 agent 64位数lib路径(lib64/installaction)执行指令 --create-cluster-timestamp-file
|
|
|
|
|
+createFirstClusterTimestampFile() {
|
|
|
|
|
+ toLogInfo "Creating firstClusterTimestamp file"
|
|
|
|
|
+ #== 调用 agent 64位数lib路径(lib64/installaction)执行指令 --create-cluster-timestamp-file
|
|
|
|
|
+ "$(getAgentInstallActionPath)" "--create-cluster-timestamp-file" >>"${LOG_FILE}" 2>&1
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【4】=配置数据存储目录
|
|
|
|
|
+setupDataStorageDir() {
|
|
|
|
|
+ toLogInfo "Setup datastorage dir..."
|
|
|
|
|
+ local dataStorage
|
|
|
|
|
+ dataStorage="$(getValueFromConfigFile "${CONF_FIELD_NM_DATA_STORAGE}" "${LEGACY_AGENT_CONF_FILE}" "${DATA_STORAGE_DIR}")"
|
|
|
|
|
+ if [ "${dataStorage}"x = "${LOG_DIR}"x ]; then
|
|
|
|
|
+ toLogInfo "Detected legacy data storage setting, changing it to the new default location"
|
|
|
|
|
+ writeParamToConfigFile "${CONF_FIELD_NM_DATA_STORAGE}" "${DATA_STORAGE_DIR}" "${LEGACY_AGENT_CONF_FILE}"
|
|
|
|
|
+ writeParamToConfigFile "${CONF_FIELD_NM_DATA_STORAGE}" "${DATA_STORAGE_DIR}" "${INSTALLER_CONF_FILE}"
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ if [ "${PARAM_DATA_STORAGE}" ]; then
|
|
|
|
|
+ writeParamToConfigFile "${CONF_FIELD_NM_DATA_STORAGE}" "${PARAM_DATA_STORAGE}" "${LEGACY_AGENT_CONF_FILE}"
|
|
|
|
|
+ writeParamToConfigFile "${CONF_FIELD_NM_DATA_STORAGE}" "${PARAM_DATA_STORAGE}" "${INSTALLER_CONF_FILE}"
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ toLogInfo "Setup datastorage dir done."
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#**********************************************************
|
|
|
|
|
+# Processing command line parameters
|
|
|
|
|
+#**********************************************************
|
|
|
|
|
+#== 【0】=help
|
|
|
|
|
+displayHelp() {
|
|
|
|
|
+ printf '%s\n' "Usage: $(basename "${INSTALLER_FILE}") [-h] [-v] "
|
|
|
|
|
+ #== printf '%s\n' "Usage: $(basename "${INSTALLER_FILE}") [-h] [-v] [DATA_SERVER=https://server_address:server_port] [CONFIG_SERVER=configService] [LICENSE=license] [INSTALL_DIR=install_path]"
|
|
|
|
|
+ local beginStr="Usage: "
|
|
|
|
|
+ local pad="${#beginStr}"
|
|
|
|
|
+
|
|
|
|
|
+ printf "\n\n"
|
|
|
|
|
+
|
|
|
|
|
+ pad=25
|
|
|
|
|
+ printf "%-${pad}s%s\n" "-h, --help" "Display this help and exit."
|
|
|
|
|
+ printf "%-${pad}s%s\n" "-v, --version" "Print version and exit."
|
|
|
|
|
+
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+printParamMessage() {
|
|
|
|
|
+ local paramNm="${1}"
|
|
|
|
|
+ local paramValue="${2}"
|
|
|
|
|
+ toConsoleInfo "---> Parameter ${paramNm}=${paramValue}."
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+printOtherParamMessage() {
|
|
|
|
|
+ local param="${1}"
|
|
|
|
|
+ toConsoleInfo "---> Parameter ${param}"
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【0】=大小写转化,并返回判断结果
|
|
|
|
|
+istrcmp() {
|
|
|
|
|
+ local s1
|
|
|
|
|
+ local s2
|
|
|
|
|
+ s1="$(printf '%s' "${1}" | tr '[:upper:]' '[:lower:]')"
|
|
|
|
|
+ s2="$(printf '%s' "${2}" | tr '[:upper:]' '[:lower:]')"
|
|
|
|
|
+ [ "${s1}"x = "${s2}"x ]
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【0】=
|
|
|
|
|
+isParamTrue() {
|
|
|
|
|
+ [ "${1}"x = "1"x ] || [ "${1}"x = "true"x ] || [ "${1}"x = "enable"x ] || [ "${1}"x = "yes"x ]
|
|
|
|
|
+}
|
|
|
|
|
+#== 【1】【5】=
|
|
|
|
|
+isParamFalse() {
|
|
|
|
|
+ [ "${1}"x = "0"x ] || [ "${1}"x = "false"x ] || [ "${1}"x = "disable"x ] || [ "${1}"x = "no"x ]
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【1】【5】=
|
|
|
|
|
+invertBoolValue() {
|
|
|
|
|
+ local valueToInvert="${1}"
|
|
|
|
|
+ if isParamFalse "${valueToInvert}"; then
|
|
|
|
|
+ printf '%s' "true"
|
|
|
|
|
+ else
|
|
|
|
|
+ printf '%s' "false"
|
|
|
|
|
+ fi
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== shellcheck disable=SC2003
|
|
|
|
|
+#== 【0】=获取参数值
|
|
|
|
|
+getParamValue() {
|
|
|
|
|
+ local paramName="${1}"
|
|
|
|
|
+ local input="${2}"
|
|
|
|
|
+ local paramNameLength="${#paramName}"
|
|
|
|
|
+ paramNameLength=$((paramNameLength + 1))
|
|
|
|
|
+ local partParam
|
|
|
|
|
+ partParam="$(expr substr "${input}" 1 ${paramNameLength})"
|
|
|
|
|
+# partParam=$(substr "${input}" 1 ${paramNameLength})
|
|
|
|
|
+ if ! istrcmp "${partParam}" "${paramName}="; then
|
|
|
|
|
+ return 1
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ local valueSeparator=$((paramNameLength + 1))
|
|
|
|
|
+ local value
|
|
|
|
|
+ value="$(expr substr "${input}" ${valueSeparator} 1000)"
|
|
|
|
|
+# value=$(substr "${input}" ${valueSeparator} 1000)
|
|
|
|
|
+ if [ -z "${value}" ]; then
|
|
|
|
|
+ return 1
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ printf '%s' "${value}"
|
|
|
|
|
+ return 0
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【0】=获取bool参数
|
|
|
|
|
+readBoolParam() {
|
|
|
|
|
+ local value
|
|
|
|
|
+ value="$(getParamValue "${1}" "${2}")"
|
|
|
|
|
+
|
|
|
|
|
+ if value="$(getBoolParam "${value}")"; then
|
|
|
|
|
+ printf "%s" "${value}"
|
|
|
|
|
+ return 0
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ return 1
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【0】=获取bool参数
|
|
|
|
|
+getBoolParam() {
|
|
|
|
|
+ local value="${1}"
|
|
|
|
|
+ if [ "${value}" ]; then
|
|
|
|
|
+ if isParamFalse "${value}"; then
|
|
|
|
|
+ printf "false"
|
|
|
|
|
+ return 0
|
|
|
|
|
+ fi
|
|
|
|
|
+ if isParamTrue "${value}"; then
|
|
|
|
|
+ printf "true"
|
|
|
|
|
+ return 0
|
|
|
|
|
+ fi
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ return 1
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【0】=校验格式是否规范[1、大于4个字符且不能"cw."开头,2、不能超过100字符,3、只能包含字母数字字符,连字符,下划线和点。]
|
|
|
|
|
+validateParameter() {
|
|
|
|
|
+ local name="${1}"
|
|
|
|
|
+ local value="${2}"
|
|
|
|
|
+ if [ "$(printf '%s' "${value}" | cut -c -3)"x = "cw."x ]; then
|
|
|
|
|
+ toConsoleError "${name} must not begin with 'cw.'"
|
|
|
|
|
+ finishInstallation "${EXIT_CODE_INVALID_PARAM}"
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ if [ "${#value}" -gt 100 ]; then
|
|
|
|
|
+ toConsoleError "Maximum allowed length of ${name} is 100."
|
|
|
|
|
+ finishInstallation "${EXIT_CODE_INVALID_PARAM}"
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ if printf '%s' "${value}" | grep -q "[^[:alnum:]._-]"; then
|
|
|
|
|
+ toConsoleError "${name} can only contain alphanumeric characters, hyphen, underscore and dot."
|
|
|
|
|
+ finishInstallation "${EXIT_CODE_INVALID_PARAM}"
|
|
|
|
|
+ fi
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【0】=验证用户和用户组是否匹配
|
|
|
|
|
+validateUserAndGroupParameters() {
|
|
|
|
|
+ local user="${1}"
|
|
|
|
|
+ local group="${2}"
|
|
|
|
|
+ local permittedNameRegex='^[[:alnum:]._][[:alnum:]._-]{2,31}$'
|
|
|
|
|
+
|
|
|
|
|
+ if [ ! "${group}" ]; then
|
|
|
|
|
+ group="${user}"
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ if ! printf '%s' "${user}" | grep -qE "${permittedNameRegex}"; then
|
|
|
|
|
+ toConsoleError "USER can only contain alphanumeric characters, hyphen, underscore and dot, and must have length from 3 to 32 characters."
|
|
|
|
|
+ finishInstallation "${EXIT_CODE_INVALID_PARAM}"
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ if ! printf '%s' "${group}" | grep -qE "${permittedNameRegex}"; then
|
|
|
|
|
+ toConsoleError "GROUP can only contain alphanumeric characters, hyphen, underscore and dot, and must have length from 3 to 32 characters."
|
|
|
|
|
+ finishInstallation "${EXIT_CODE_INVALID_PARAM}"
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ #== 校验用户/用户组信息
|
|
|
|
|
+ validateUserPrimaryGroup "${user}" "${group}"
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【0】【3】【5】=获取系统权限信息
|
|
|
|
|
+getSystemEntityInfo() {
|
|
|
|
|
+ local database="${1}"
|
|
|
|
|
+ local valueToCheck="${2}"
|
|
|
|
|
+
|
|
|
|
|
+ #== 校验命令getent是否存在
|
|
|
|
|
+ if ! isAvailable "getent"; then
|
|
|
|
|
+ toLogInfo "Command getent is not available"
|
|
|
|
|
+ return 2
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ #== 查看系统权限
|
|
|
|
|
+ local output
|
|
|
|
|
+ output="$(getent "${database}" "${valueToCheck}" 2>&1)"
|
|
|
|
|
+ local returnCode=$?
|
|
|
|
|
+
|
|
|
|
|
+ if [ "${returnCode}" != 0 ]; then
|
|
|
|
|
+ if [ "${returnCode}" != 2 ]; then
|
|
|
|
|
+ toLogWarn "Failed to check ${valueToCheck} in ${database} database, message: ${output}, code: ${returnCode}"
|
|
|
|
|
+ fi
|
|
|
|
|
+ return 1
|
|
|
|
|
+ elif [ ! "${output}" ]; then
|
|
|
|
|
+ toLogWarn "Failed to get user information: getent returned no output"
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ printf '%s' "${output}"
|
|
|
|
|
+ return 0
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【0】【3】=查看用户/用户组信息
|
|
|
|
|
+isEntityPassedById() {
|
|
|
|
|
+ local database="${1}"
|
|
|
|
|
+ local name="${2}"
|
|
|
|
|
+
|
|
|
|
|
+ local output
|
|
|
|
|
+ output="$(getSystemEntityInfo "${database}" "${name}")"
|
|
|
|
|
+ local returnCode=$?
|
|
|
|
|
+
|
|
|
|
|
+ if [ ${returnCode} -ne 0 ]; then
|
|
|
|
|
+ if [ ${returnCode} -eq 2 ]; then
|
|
|
|
|
+ toLogInfo "Installer will not be able to verify whether entity was passed by name or by ID"
|
|
|
|
|
+ fi
|
|
|
|
|
+ return 1
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ local nameFromDatabase
|
|
|
|
|
+ nameFromDatabase="$(printf '%s' "${output}" | cut -d: -f1)"
|
|
|
|
|
+
|
|
|
|
|
+ if [ "${nameFromDatabase}"x = "${name}"x ]; then
|
|
|
|
|
+ return 1
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ toLogWarn "Name from config and from ${database} system database do not match"
|
|
|
|
|
+ toLogWarn "Config: ${name}, database: ${nameFromDatabase}"
|
|
|
|
|
+ return 0
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【0】【3】【5】=用户是否存在
|
|
|
|
|
+userExistsInSystem() {
|
|
|
|
|
+ local user="${1}"
|
|
|
|
|
+
|
|
|
|
|
+ getSystemEntityInfo "passwd" "${user}" >/dev/null
|
|
|
|
|
+ local returnCode=$?
|
|
|
|
|
+
|
|
|
|
|
+ if [ ${returnCode} -ne 2 ]; then
|
|
|
|
|
+ return ${returnCode}
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ toLogInfo "Trying to determine user existence using 'id' command"
|
|
|
|
|
+ id "${user}" >/dev/null 2>&1
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【5】= 查看group
|
|
|
|
|
+groupExistsInSystem() {
|
|
|
|
|
+ local group="${1}"
|
|
|
|
|
+
|
|
|
|
|
+ getSystemEntityInfo "group" "${group}" >/dev/null
|
|
|
|
|
+ local returnCode=$?
|
|
|
|
|
+
|
|
|
|
|
+ if [ ${returnCode} -ne 2 ]; then
|
|
|
|
|
+ return ${returnCode}
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ toLogInfo "Installer will not be able to determine group existence"
|
|
|
|
|
+ return 1
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【3】=用户是否存在
|
|
|
|
|
+validateUserExistence() {
|
|
|
|
|
+ local user="${1}"
|
|
|
|
|
+ if ! userExistsInSystem "${user}"; then
|
|
|
|
|
+ toConsoleError "User named '${user}' configured for ${BRAND_PRODUCT_NAME} does not exist. Installation aborted."
|
|
|
|
|
+ finishInstallation "${EXIT_CODE_INVALID_PARAM}"
|
|
|
|
|
+ fi
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【0】【3】=检查用户/用户组信息
|
|
|
|
|
+checkIfEntityWasNotPassedById() {
|
|
|
|
|
+ local database="${1}"
|
|
|
|
|
+ local valueToCheck="${2}"
|
|
|
|
|
+ local valueTypeToLog="user"
|
|
|
|
|
+
|
|
|
|
|
+ if [ "${database}"x = "group"x ]; then
|
|
|
|
|
+ valueTypeToLog="group"
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ if isEntityPassedById "${database}" "${valueToCheck}"; then
|
|
|
|
|
+ toConsoleError "\"${valueToCheck}\" is not a ${valueTypeToLog} name but its ID. Installation aborted."
|
|
|
|
|
+ finishInstallation "${EXIT_CODE_INVALID_PARAM}"
|
|
|
|
|
+ fi
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【0】【3】=用户权限下用户组ID
|
|
|
|
|
+getUserPrimaryGroupIdForComparison() {
|
|
|
|
|
+ local user="${1}"
|
|
|
|
|
+
|
|
|
|
|
+ local userPrimaryGroupId
|
|
|
|
|
+ userPrimaryGroupId="$(getSystemEntityInfo "passwd" "${user}")"
|
|
|
|
|
+ local returnCode=$?
|
|
|
|
|
+
|
|
|
|
|
+ if [ ${returnCode} -ne 2 ]; then
|
|
|
|
|
+ printf '%s' "${userPrimaryGroupId}" | cut -d: -f4
|
|
|
|
|
+ return ${returnCode}
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ toLogInfo "Returning user primary group name instead of its id"
|
|
|
|
|
+ id -gn "${user}"
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【0】【3】=获取用户组信息
|
|
|
|
|
+getGroupIdForComparison() {
|
|
|
|
|
+ local group="${1}"
|
|
|
|
|
+
|
|
|
|
|
+ local groupId
|
|
|
|
|
+ groupId="$(getSystemEntityInfo "group" "${group}")"
|
|
|
|
|
+ local returnCode=$?
|
|
|
|
|
+
|
|
|
|
|
+ if [ ${returnCode} -ne 2 ]; then
|
|
|
|
|
+ printf '%s' "${groupId}" | cut -d: -f3
|
|
|
|
|
+ return ${returnCode}
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ toLogInfo "Returning group name instead of its id"
|
|
|
|
|
+ printf '%s' "${group}"
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【0】【3】=校验用户/用户组信息
|
|
|
|
|
+validateUserPrimaryGroup() {
|
|
|
|
|
+ local user="${1}"
|
|
|
|
|
+ local group="${2}"
|
|
|
|
|
+
|
|
|
|
|
+ if ! userExistsInSystem "${user}"; then
|
|
|
|
|
+ return
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ checkIfEntityWasNotPassedById "passwd" "${user}"
|
|
|
|
|
+ checkIfEntityWasNotPassedById "group" "${group}"
|
|
|
|
|
+
|
|
|
|
|
+ #== 获取用户组ID
|
|
|
|
|
+ local groupId
|
|
|
|
|
+ groupId="$(getGroupIdForComparison "${group}")"
|
|
|
|
|
+ #== 获取用户下用户组ID
|
|
|
|
|
+ local userPrimaryGroupId
|
|
|
|
|
+ userPrimaryGroupId="$(getUserPrimaryGroupIdForComparison "${user}")"
|
|
|
|
|
+
|
|
|
|
|
+ toConsoleInfo "#DEBUG== group \"${group}\" id: \"${groupId}\", user \"${user}\" primaryGroupId: \"${userPrimaryGroupId}\""
|
|
|
|
|
+ if [ "${userPrimaryGroupId}"x != "${groupId}"x ]; then
|
|
|
|
|
+ toConsoleError "User named \"${user}\" does not have group named \"${group}\" as its primary group. Installation aborted."
|
|
|
|
|
+ finishInstallation "${EXIT_CODE_INVALID_PARAM}"
|
|
|
|
|
+ fi
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【3】=检查用户/用户组是否存在和匹配
|
|
|
|
|
+checkUserAndGroupFromConfig() {
|
|
|
|
|
+ local configUser
|
|
|
|
|
+ local configGroup
|
|
|
|
|
+ configUser="$(getValueFromConfigFile "${CONF_FIELD_NM_USER}" "${LEGACY_AGENT_CONF_FILE}" "${BRAND_AGENT_DEFAULT_USER_AND_GROUP_NAME}")"
|
|
|
|
|
+ configGroup="$(getValueFromConfigFile "${CONF_FIELD_NM_GROUP}" "${LEGACY_AGENT_CONF_FILE}" "${BRAND_AGENT_DEFAULT_USER_AND_GROUP_NAME}")"
|
|
|
|
|
+
|
|
|
|
|
+ toLogInfo "Checking validity of user account '${configUser}:${configGroup}'"
|
|
|
|
|
+
|
|
|
|
|
+ if [ "${PARAM_UPGRADE}"x = "yes"x ]; then
|
|
|
|
|
+ validateUserExistence "${configUser}"
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ #== 校验用户/用户组信息
|
|
|
|
|
+ validateUserPrimaryGroup "${configUser}" "${configGroup}"
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【0】=解析命令行中参数
|
|
|
|
|
+parseCommandLineParameters() {
|
|
|
|
|
+ local dataServerIsEmpty=true
|
|
|
|
|
+ local configServerIsEmpty=true
|
|
|
|
|
+ while [ $# -gt 0 ]; do
|
|
|
|
|
+ local param="${1}"
|
|
|
|
|
+ local value=
|
|
|
|
|
+
|
|
|
|
|
+ if value=$(getParamValue DATA_SERVER "${param}"); then
|
|
|
|
|
+ PARAM_DATA_SERVER="${value}"
|
|
|
|
|
+ dataServerIsEmpty=false
|
|
|
|
|
+ printParamMessage "DATA_SERVER" "${value}"
|
|
|
|
|
+ shift
|
|
|
|
|
+ continue
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ if value=$(getParamValue CONFIG_SERVER "${param}"); then
|
|
|
|
|
+ PARAM_CONFIG_SERVER="${value}"
|
|
|
|
|
+ configServerIsEmpty=false
|
|
|
|
|
+ printParamMessage "CONFIG_SERVER" "${value}"
|
|
|
|
|
+ shift
|
|
|
|
|
+ continue
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ if value=$(getParamValue LICENSE "${param}"); then
|
|
|
|
|
+ PARAM_LICENSE="${value}"
|
|
|
|
|
+ printParamMessage "LICENSE" "${value}"
|
|
|
|
|
+ shift
|
|
|
|
|
+ continue
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ if value=$(getParamValue JSON_CONF "${param}"); then
|
|
|
|
|
+ PARAM_JSON_CONF="${value}"
|
|
|
|
|
+ printParamMessage "JSON_CONF" "${value}"
|
|
|
|
|
+ shift
|
|
|
|
|
+ continue
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ if value=$(getParamValue INSTALL_DIR "${param}"); then
|
|
|
|
|
+ PARAM_INSTALL_DIR="${value}"
|
|
|
|
|
+ printParamMessage "INSTALL_DIR" "${value}"
|
|
|
|
|
+ shift
|
|
|
|
|
+ continue
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ if value=$(getParamValue DATA_STORAGE "${param}"); then
|
|
|
|
|
+ PARAM_DATA_STORAGE="${value}"
|
|
|
|
|
+ printParamMessage "DATA_STORAGE" "${value}"
|
|
|
|
|
+ shift
|
|
|
|
|
+ continue
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ if value=$(readBoolParam DISABLE_SYSTEM_LOGS_ACCESS "${param}"); then
|
|
|
|
|
+ PARAM_DISABLE_SYSTEM_LOGS_ACCESS="${value}"
|
|
|
|
|
+ printParamMessage "DISABLE_SYSTEM_LOGS_ACCESS" "${value}"
|
|
|
|
|
+ shift
|
|
|
|
|
+ continue
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ if value=$(getParamValue INTERNAL_OVERRIDE_CHECKS "${param}"); then
|
|
|
|
|
+ if printf '%s' "${value}" | grep -wq "privileges"; then
|
|
|
|
|
+ PARAM_INTERNAL_NON_ROOT_MODE_SKIP_PRIVILEGES_CHECK=true
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ if printf '%s' "${value}" | grep -wq "downgrade"; then
|
|
|
|
|
+ SKIP_DOWNGRADE_CHECK=true
|
|
|
|
|
+ fi
|
|
|
|
|
+ printParamMessage "INTERNAL_OVERRIDE_CHECKS" "${value}"
|
|
|
|
|
+
|
|
|
|
|
+ shift
|
|
|
|
|
+ continue
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ if value=$(readBoolParam INTERNAL_USE_UNPACK_CACHE "${param}"); then
|
|
|
|
|
+ PARAM_INTERNAL_USE_UNPACK_CACHE="${value}"
|
|
|
|
|
+ printParamMessage "INTERNAL_USE_UNPACK_CACHE" "${value}"
|
|
|
|
|
+ shift
|
|
|
|
|
+ continue
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ if [ "${ARCH_ARCH}"x != "AIX"x ]; then
|
|
|
|
|
+ if value=$(getParamValue USER "${param}"); then
|
|
|
|
|
+ PARAM_USER="${value}"
|
|
|
|
|
+ printParamMessage "USER" "${value}"
|
|
|
|
|
+ shift
|
|
|
|
|
+ continue
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ if value=$(getParamValue GROUP "${param}"); then
|
|
|
|
|
+ PARAM_GROUP="${value}"
|
|
|
|
|
+ printParamMessage "GROUP" "${value}"
|
|
|
|
|
+ shift
|
|
|
|
|
+ continue
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ if value=$(readBoolParam NON_ROOT_MODE "${param}"); then
|
|
|
|
|
+ PARAM_NON_ROOT_MODE="${value}"
|
|
|
|
|
+ printParamMessage "NON_ROOT_MODE" "${value}"
|
|
|
|
|
+ shift
|
|
|
|
|
+ continue
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ if value=$(readBoolParam USER_LOGIN "${param}"); then
|
|
|
|
|
+ PARAM_USER_LOGIN="${value}"
|
|
|
|
|
+ printParamMessage "USER_LOGIN" "${value}"
|
|
|
|
|
+ shift
|
|
|
|
|
+ continue
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ #== 自定义参数获取
|
|
|
|
|
+ if value=$(getParamValue TEST "${param}"); then
|
|
|
|
|
+ PARAM_TEST="${value}"
|
|
|
|
|
+ printParamMessage "TEST" "${value}"
|
|
|
|
|
+ shift
|
|
|
|
|
+ continue
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ #== 自定义bool参数
|
|
|
|
|
+ if value=$(readBoolParam BOOL "${param}"); then
|
|
|
|
|
+ PARAM_BOOL="${value}"
|
|
|
|
|
+ printParamMessage "BOOL" "${value}"
|
|
|
|
|
+ shift
|
|
|
|
|
+ continue
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ if value=$(readBoolParam DISABLE_ROOT_FALLBACK "${param}"); then
|
|
|
|
|
+ PARAM_DISABLE_ROOT_FALLBACK="${value}"
|
|
|
|
|
+ printParamMessage "DISABLE_ROOT_FALLBACK" "${value}"
|
|
|
|
|
+ shift
|
|
|
|
|
+ continue
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ if value=$(readBoolParam NON_ROOT_MODE_SKIP_PRIVILEGES_CHECK "${param}"); then
|
|
|
|
|
+ PARAM_INTERNAL_NON_ROOT_MODE_SKIP_PRIVILEGES_CHECK="${value}"
|
|
|
|
|
+ printParamMessage "NON_ROOT_MODE_SKIP_PRIVILEGES_CHECK" "${value}"
|
|
|
|
|
+ shift
|
|
|
|
|
+ continue
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ if value=$(readBoolParam INTERNAL_SKIP_SELINUX_POLICY_INSTALLER "${param}"); then
|
|
|
|
|
+ #== PARAM_INTERNAL_SKIP_SELINUX_POLICY_INSTALLER="${value}"
|
|
|
|
|
+ printParamMessage "INTERNAL_SKIP_SELINUX_POLICY_INSTALLER" "${value}"
|
|
|
|
|
+ shift
|
|
|
|
|
+ continue
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ if value=$(readBoolParam DOCKER_ENABLED "${param}"); then
|
|
|
|
|
+ #== PARAM_INTERNAL_DEPLOYED_VIA_CONTAINER="${value}"
|
|
|
|
|
+ printParamMessage "DOCKER_ENABLED" "${value}"
|
|
|
|
|
+ shift
|
|
|
|
|
+ continue
|
|
|
|
|
+ fi
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ if [ "${ARCH_ARCH}"x != "AIX"x ] && [ "${ARCH_ARCH}"x != "S390"x ]; then
|
|
|
|
|
+ if value=$(readBoolParam INTERNAL_DISABLE_DUMPPROC "${param}"); then
|
|
|
|
|
+ #== PARAM_INTERNAL_DISABLE_DUMPPROC="${value}"
|
|
|
|
|
+ printParamMessage "INTERNAL_DISABLE_DUMPPROC" "${value}"
|
|
|
|
|
+ shift
|
|
|
|
|
+ continue
|
|
|
|
|
+ fi
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ if [ "${param}"x = "-h"x ] || [ "${param}"x = "--help"x ]; then
|
|
|
|
|
+ displayHelp
|
|
|
|
|
+ finishInstallation "${EXIT_CODE_OK}"
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ if [ "${param}"x = "-v"x ] || [ "${param}"x = "--version"x ]; then
|
|
|
|
|
+ printf "%s\n" "${AGENT_INSTALLER_VERSION}"
|
|
|
|
|
+ finishInstallation "${EXIT_CODE_OK}"
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ printOtherParamMessage ${param}
|
|
|
|
|
+ shift
|
|
|
|
|
+ done
|
|
|
|
|
+
|
|
|
|
|
+ if [ "${configServerIsEmpty}"x = "true"x ] && [ "${dataServerIsEmpty}"x != "true"x ]; then
|
|
|
|
|
+ PARAM_CONFIG_SERVER="${PARAM_DATA_SERVER}"
|
|
|
|
|
+ fi
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【0】=校验PARAM_INSTALL_DIR是否规范【1、不能包含空格,2、不能在根目录,3、安装路径必须是绝对的】
|
|
|
|
|
+validateInstallPathParameter() {
|
|
|
|
|
+ if printf '%s' "${PARAM_INSTALL_DIR}" | grep -q "[[:space:]]"; then
|
|
|
|
|
+ toConsoleError "Installation path must not contain spaces."
|
|
|
|
|
+ finishInstallation "${EXIT_CODE_INVALID_PARAM}"
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ if [ "${PARAM_INSTALL_DIR}"x = "/"x ]; then
|
|
|
|
|
+ toConsoleError "Installation path must not point to the filesystem root directory."
|
|
|
|
|
+ finishInstallation "${EXIT_CODE_INVALID_PARAM}"
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ if [ "$(printf '%s' "${PARAM_INSTALL_DIR}" | cut -c 1)"x != "/"x ]; then
|
|
|
|
|
+ toConsoleError "Installation path must be absolute."
|
|
|
|
|
+ finishInstallation "${EXIT_CODE_INVALID_PARAM}"
|
|
|
|
|
+ fi
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【0】=校验PARAM_DATA_STORAGE是否规范【1、不能包含空格,2、不能在根目录,3、安装路径必须是绝对的,4、数据目录不能放在安装目录下】
|
|
|
|
|
+validateDataStorageParameter() {
|
|
|
|
|
+ if printf '%s' "${PARAM_DATA_STORAGE}" | grep -q "[[:space:]]"; then
|
|
|
|
|
+ toConsoleError "Data storage path must not contain spaces."
|
|
|
|
|
+ finishInstallation "${EXIT_CODE_INVALID_PARAM}"
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ if [ "${PARAM_DATA_STORAGE}"x = "/"x ]; then
|
|
|
|
|
+ toConsoleError "Data storage path must not point to the filesystem root directory."
|
|
|
|
|
+ finishInstallation "${EXIT_CODE_INVALID_PARAM}"
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ if [ "$(printf '%s' "${PARAM_DATA_STORAGE}" | cut -c 1)"x != "/"x ]; then
|
|
|
|
|
+ toConsoleError "Data storage path must be absolute."
|
|
|
|
|
+ finishInstallation "${EXIT_CODE_INVALID_PARAM}"
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ if printf '%s' "${PARAM_DATA_STORAGE}" | grep -q "^${INSTALL_DIR}"; then
|
|
|
|
|
+ toConsoleError "Data storage path must not be located within ${INSTALL_DIR}."
|
|
|
|
|
+ finishInstallation "${EXIT_CODE_INVALID_PARAM}"
|
|
|
|
|
+ fi
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+#**********************************************************
|
|
|
|
|
+# Config files
|
|
|
|
|
+#**********************************************************
|
|
|
|
|
+
|
|
|
|
|
+#== 【3】【5】=格式化空间大小(将 1024KiB 格式化成 1MiB, 将 1024MiB 格式化成 1GiB,...)
|
|
|
|
|
+formatSize() {
|
|
|
|
|
+ local sizeInKiB="${1}"
|
|
|
|
|
+ local formattedSize
|
|
|
|
|
+
|
|
|
|
|
+ for symbol in "KiB" "MiB" "GiB" "TiB"; do
|
|
|
|
|
+ if printf '%s' "${sizeInKiB}" | awk '$1 >= 1024 { exit 1; }'; then
|
|
|
|
|
+ formattedSize="${sizeInKiB} ${symbol}"
|
|
|
|
|
+ break
|
|
|
|
|
+ fi
|
|
|
|
|
+ sizeInKiB="$(printf '%s' "${sizeInKiB}" | awk '{ print $1 / 1024 }')"
|
|
|
|
|
+ done
|
|
|
|
|
+
|
|
|
|
|
+ printf '%s' "${formattedSize}"
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【3】【5】=
|
|
|
|
|
+cropSizeValue() {
|
|
|
|
|
+ local size="${1}"
|
|
|
|
|
+ local value
|
|
|
|
|
+ local unit
|
|
|
|
|
+ value="$(printf '%s' "${size}" | cut -d' ' -f1)"
|
|
|
|
|
+ unit="$(printf '%s' "${size}" | cut -d' ' -f2)"
|
|
|
|
|
+ printf '%.2f %s' "${value}" "${unit}"
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【3】【5】=检查目录可用空间(单位:k)
|
|
|
|
|
+checkFreeSpace() {
|
|
|
|
|
+ local path="${1}"
|
|
|
|
|
+ local requiredSpaceInKiB="${2}"
|
|
|
|
|
+ local dfOutput
|
|
|
|
|
+ local baseFilesystem
|
|
|
|
|
+ local freeSpace
|
|
|
|
|
+ local formattedRequiredSpace
|
|
|
|
|
+ local formattedFreeSpace
|
|
|
|
|
+
|
|
|
|
|
+ #== shellcheck disable=SC2086
|
|
|
|
|
+ dfOutput="$(df -P ${AIX_DF_SPECIFIC_FLAG} "${path}" | tail -n +2)"
|
|
|
|
|
+ #== 文件系统目录
|
|
|
|
|
+ baseFilesystem="$(printf "%s" "${dfOutput}" | awk '{ print $NF }')"
|
|
|
|
|
+ #== 剩余空间(单位:k)
|
|
|
|
|
+ freeSpace="$(printf "%s" "${dfOutput}" | awk '{ print $4 }')"
|
|
|
|
|
+
|
|
|
|
|
+ #== 格式化空间大小(将 1024KiB 格式化成 1MiB, 将 1024MiB 格式化成 1GiB,...)
|
|
|
|
|
+ formattedRequiredSpace="$(formatSize "${requiredSpaceInKiB}")"
|
|
|
|
|
+ toLogInfo "Filesystem with ${path} is mounted under ${baseFilesystem}. Space required: ${formattedRequiredSpace}."
|
|
|
|
|
+
|
|
|
|
|
+ if [ ! "${freeSpace}" ]; then
|
|
|
|
|
+ printf 'Cannot determine amount of free space on %s (filesystem mounted under %s)' "${path}" "${baseFilesystem}"
|
|
|
|
|
+ return 1
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ #== 格式化空间大小(将 1024KiB 格式化成 1MiB, 将 1024MiB 格式化成 1GiB,...)
|
|
|
|
|
+ formattedFreeSpace="$(formatSize "${freeSpace}")"
|
|
|
|
|
+ toLogInfo "Available free space: ${formattedFreeSpace}"
|
|
|
|
|
+
|
|
|
|
|
+ if [ "${freeSpace}" -lt "${requiredSpaceInKiB}" ]; then
|
|
|
|
|
+ printf 'Not enough free space on %s (filesystem mounted under %s). ' "${path}" "${baseFilesystem}"
|
|
|
|
|
+ printf 'Required: %s, available: %s' "$(cropSizeValue "${formattedRequiredSpace}")" "$(cropSizeValue "${formattedFreeSpace}")"
|
|
|
|
|
+ return 2
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ printf 'Free space is sufficient'
|
|
|
|
|
+ return 0
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【3】=检查文件系统类型
|
|
|
|
|
+
|
|
|
|
|
+#== 【3】=检查安装目录空间
|
|
|
|
|
+checkInstallPathFreeSpace() {
|
|
|
|
|
+ local externalTarSize=${EXTERNAL_TAR_SIZE}
|
|
|
|
|
+ local artifactsSize=${ARTIFACTS_SIZE}
|
|
|
|
|
+ #== use 10% additional margin
|
|
|
|
|
+ local requiredSpace=$((externalTarSize + artifactsSize * 11 / 10))
|
|
|
|
|
+ #== convert to kibibytes
|
|
|
|
|
+ requiredSpace=$((requiredSpace / 1024))
|
|
|
|
|
+
|
|
|
|
|
+ toConsoleInfo "Checking free space in ${INSTALL_DIR}"
|
|
|
|
|
+
|
|
|
|
|
+ local message
|
|
|
|
|
+ #== 检查目录可用空间(单位:k)
|
|
|
|
|
+ message="$(checkFreeSpace "${INSTALL_DIR}" "${requiredSpace}")"
|
|
|
|
|
+ case $? in
|
|
|
|
|
+ 0) toLogInfo "${message}" ;;
|
|
|
|
|
+ 1) toConsoleWarn "${message}. Installation may be incomplete." ;;
|
|
|
|
|
+ 2)
|
|
|
|
|
+ toConsoleError "${message}"
|
|
|
|
|
+ finishInstallation "${EXIT_CODE_NOT_ENOUGH_SPACE}"
|
|
|
|
|
+ ;;
|
|
|
|
|
+ esac
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【3】=获取指定路径的文件系统信息
|
|
|
|
|
+getFilesystemInfo() {
|
|
|
|
|
+ if [ "${ARCH_ARCH}"x = "AIX"x ]; then
|
|
|
|
|
+ mount | grep " ${1} "
|
|
|
|
|
+ else
|
|
|
|
|
+ grep " ${1} " /proc/self/mounts
|
|
|
|
|
+ fi
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【3】=检查目录指定权限信息
|
|
|
|
|
+checkAccessRightsTo() {
|
|
|
|
|
+ local dir="${1}"
|
|
|
|
|
+ toLogInfo "Checking access to ${dir}..."
|
|
|
|
|
+ #== 获取文件权限信息
|
|
|
|
|
+ local accessRights
|
|
|
|
|
+ accessRights="$(arch_getAccessRights "${dir}" | cut -c 2-4)"
|
|
|
|
|
+ if ! printf '%s' "${accessRights}" | grep -q rwx; then
|
|
|
|
|
+ toConsoleError "Insufficient permissions on ${dir}: '${accessRights}'."
|
|
|
|
|
+ toLogInfo "$(ls -dl "${dir}" 2>&1)"
|
|
|
|
|
+ finishInstallation "${EXIT_CODE_INSUFFICIENT_PERMISSIONS}"
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ local dfResult
|
|
|
|
|
+ local filesystem
|
|
|
|
|
+ local filesystemInfo
|
|
|
|
|
+ dfResult="$(df -P "${dir}")"
|
|
|
|
|
+ #== 获取目录文件系统路径
|
|
|
|
|
+ filesystem="$(printf '%s' "${dfResult}" | tail -1 | awk '{ print $NF }')"
|
|
|
|
|
+ #== 获取指定路径的文件系统信息
|
|
|
|
|
+ filesystemInfo="$(getFilesystemInfo "${filesystem}")"
|
|
|
|
|
+ if ! printf '%s' "${filesystemInfo}" | grep -qw rw; then
|
|
|
|
|
+ toLogWarn "df-based check determined filesystem mounted under ${filesystem} as readonly, trying fallback."
|
|
|
|
|
+ toLogWarn "Filesystem access rights: '${filesystemInfo}'"
|
|
|
|
|
+ toLogWarn "df returned: ${dfResult}"
|
|
|
|
|
+
|
|
|
|
|
+ if ! testWriteAccessToDir "${dir}"; then
|
|
|
|
|
+ toConsoleError "readonly filesystem mounted under ${filesystem}"
|
|
|
|
|
+ finishInstallation "${EXIT_CODE_INSUFFICIENT_PERMISSIONS}"
|
|
|
|
|
+ fi
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ toLogInfo "Rights on directory ${dir} are sufficient"
|
|
|
|
|
+} 2>>"${LOG_FILE}"
|
|
|
|
|
+
|
|
|
|
|
+#== 【3】=目录是否写权限
|
|
|
|
|
+checkIfInstallationPathIsWriteable() {
|
|
|
|
|
+ for dir in "${@}"; do
|
|
|
|
|
+ if [ -d "${dir}" ]; then
|
|
|
|
|
+ checkAccessRightsTo "${dir}"
|
|
|
|
|
+ break
|
|
|
|
|
+ fi
|
|
|
|
|
+ done
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【3】=检查目录权限
|
|
|
|
|
+checkAccessRightsToDirs() {
|
|
|
|
|
+ checkIfInstallationPathIsWriteable "${INSTALL_DIR}" "${BASE_INSTALL_DIR}" "${INSTALL_BASE}" /
|
|
|
|
|
+
|
|
|
|
|
+ if [ "${INIT_SYSTEM}"x = "${INIT_SYSTEM_SYSV}"x ]; then
|
|
|
|
|
+ checkAccessRightsTo "${INIT_DIR}"
|
|
|
|
|
+ fi
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+#== 【0】=检查系统是 LINUX、AIX及指令集(X86_64\IA64\X86)
|
|
|
|
|
+checkSystemCompatibility() {
|
|
|
|
|
+ local expectedPlatform="LINUX"
|
|
|
|
|
+ if [ "${ARCH_ARCH}"x = "AIX"x ]; then
|
|
|
|
|
+ expectedPlatform="AIX"
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ #== 获取系统名称
|
|
|
|
|
+ local platform
|
|
|
|
|
+ platform="$(uname | sed -e 's/_.*//' | sed -e 's/\///' | tr '[:lower:]' '[:upper:]')"
|
|
|
|
|
+ if [ "${platform}"x != "${expectedPlatform}"x ]; then
|
|
|
|
|
+ printf "Cannot determine platform or platform not supported: <%s>" "${platform}"
|
|
|
|
|
+ return 1
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ #== 检查系统指令集(X86_64\IA64\X86)
|
|
|
|
|
+ local detectedArchitecture
|
|
|
|
|
+ if ! detectedArchitecture="$(arch_checkArchitectureCompatibility)"; then
|
|
|
|
|
+ printf "Cannot determine architecture or architecture not supported: <%s>" "${detectedArchitecture}"
|
|
|
|
|
+ return 1
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ printf 'Detected platform: %s' "${platform}"
|
|
|
|
|
+ if [ "${detectedArchitecture}" ]; then
|
|
|
|
|
+ printf ' arch: %s' "${detectedArchitecture}"
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ return 0
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【4】=从sh文件读取压缩文件 tarfile_$$.base64
|
|
|
|
|
+separateExternalTar() {
|
|
|
|
|
+ toLogInfo "Determining begin of tar archive..."
|
|
|
|
|
+ local tarBegin
|
|
|
|
|
+ local tarEnd
|
|
|
|
|
+ #== 压缩文件开始行数,占位符为【#################ENDOFSCRIPTMARK############】
|
|
|
|
|
+ tarBegin="$(locateDelimiter "#################ENDOFSCRIPTMARK############" "")"
|
|
|
|
|
+ tarBegin=$((tarBegin + 1))
|
|
|
|
|
+ #== 压缩文件结束行数,占位符为【----SIGNED-INSTALLER】
|
|
|
|
|
+ tarEnd="$(locateDelimiter "----SIGNED-INSTALLER" ${LINES_TO_SEARCH_FOR_SIGNATURE_AND_PARAMS})"
|
|
|
|
|
+ toLogInfo "tarBegin=${tarBegin} tarEnd=${tarEnd}"
|
|
|
|
|
+
|
|
|
|
|
+ if [ ! "${tarEnd}" ]; then
|
|
|
|
|
+ toConsoleError "S/MIME signature is missing, installation package is corrupted."
|
|
|
|
|
+ finishInstallation "${EXIT_CODE_CORRUPTED_PACKAGE}"
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ local tarLength=$((tarEnd - tarBegin))
|
|
|
|
|
+ toLogInfo "tarLength=${tarLength}"
|
|
|
|
|
+ #== 从sh文件读取压缩文件 tarfile_$$.base64
|
|
|
|
|
+ tail -n +"${tarBegin}" "${INSTALLER_FILE}" 2>/dev/null | head -${tarLength} >"${EXTERNAL_TAR_FILE}"
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【4】【5】=进入目录
|
|
|
|
|
+changeWorkingDir() {
|
|
|
|
|
+ if ! cd "${1}"; then
|
|
|
|
|
+ toLogError "Failed to change working directory to ${1}"
|
|
|
|
|
+ finishInstallation "${EXIT_CODE_GENERIC_ERROR}"
|
|
|
|
|
+ fi
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== shellcheck disable=SC2181
|
|
|
|
|
+#== 【4】=解压文件(1、通过base64转码后,执行tar解压;2、通过xzdec解压xz文件后在执行tar解压)
|
|
|
|
|
+unpackArchiveWithoutCache() {
|
|
|
|
|
+ #== 解压文件编码
|
|
|
|
|
+ local base64Binary="${UNPACK_BINARY}"
|
|
|
|
|
+ #== 解压文件编码参数
|
|
|
|
|
+ local base64BinaryArgs="${UNPACK_BINARY_ARGS}"
|
|
|
|
|
+ #== 使用xzdec命令可以进行liblzma为基础的xz文件解压缩
|
|
|
|
|
+ local xzBinary="${INSTALL_DIR}/xzdec"
|
|
|
|
|
+ #== 进入目录
|
|
|
|
|
+ changeWorkingDir "${INSTALL_DIR}"
|
|
|
|
|
+
|
|
|
|
|
+ if ! isAvailable tar; then
|
|
|
|
|
+ toConsoleError "tar binary not found. Setup can't continue"
|
|
|
|
|
+ finishInstallation "${EXIT_CODE_MISCONFIGURED_ENVIRONMENT}"
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ local totalLines
|
|
|
|
|
+ if ! isAvailable "${base64Binary}"; then
|
|
|
|
|
+ toLogInfo "${base64Binary} not found. Falling back to openssl decode"
|
|
|
|
|
+ if ! isAvailable openssl; then
|
|
|
|
|
+ toConsoleError "Neither ${base64Binary} nor openssl can be found. Setup can't continue"
|
|
|
|
|
+ finishInstallation "${EXIT_CODE_MISCONFIGURED_ENVIRONMENT}"
|
|
|
|
|
+ fi
|
|
|
|
|
+ #== 如果没有 base64 命令,则使用 openssl 解压文件
|
|
|
|
|
+ base64Binary="openssl"
|
|
|
|
|
+ base64BinaryArgs="enc -base64 -d -in"
|
|
|
|
|
+
|
|
|
|
|
+ if [ "${ARCH_ARCH}"x = "AIX"x ]; then
|
|
|
|
|
+ #truncate the first and the last one line due to specific format of uuencode on aix
|
|
|
|
|
+ totalLines="$(wc -l "${EXTERNAL_TAR_FILE}" | awk '{print $1}')"
|
|
|
|
|
+ head -$((totalLines - 1)) "${EXTERNAL_TAR_FILE}" 2>/dev/null | tail +2 >"${EXTERNAL_TAR_FILE}.$$"
|
|
|
|
|
+ mv -f "${EXTERNAL_TAR_FILE}.$$" "${EXTERNAL_TAR_FILE}"
|
|
|
|
|
+ fi
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ {
|
|
|
|
|
+ #== base64 转编码后,执行 tar 解压
|
|
|
|
|
+ "${base64Binary}" "${base64BinaryArgs}" "${EXTERNAL_TAR_FILE}" | tar -x -p -f -
|
|
|
|
|
+ } 2>>"${LOG_FILE}"
|
|
|
|
|
+
|
|
|
|
|
+ #== base64 转编码 或 tar解压失败
|
|
|
|
|
+ if [ $? -gt 0 ]; then
|
|
|
|
|
+ toConsoleError "Archive is corrupted or memory allocation failed. Installation aborted."
|
|
|
|
|
+ finishInstallation "${EXIT_CODE_NOT_ENOUGH_MEMORY}"
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ #== 进入目录
|
|
|
|
|
+ changeWorkingDir "${TMP_DIR}"
|
|
|
|
|
+ {
|
|
|
|
|
+ #== 使用xzdec命令解压后,执行 tar 解压
|
|
|
|
|
+ "${xzBinary}" "${INTERNAL_TAR_FILE}" | tar -x -p -f -
|
|
|
|
|
+ } 2>>"${LOG_FILE}"
|
|
|
|
|
+
|
|
|
|
|
+ if [ $? -gt 0 ]; then
|
|
|
|
|
+ toConsoleError "XZ compressed archive is corrupted or memory allocation failed. Installation aborted."
|
|
|
|
|
+ finishInstallation "${EXIT_CODE_NOT_ENOUGH_MEMORY}"
|
|
|
|
|
+ fi
|
|
|
|
|
+ #== 进入目录
|
|
|
|
|
+ changeWorkingDir "${INSTALL_DIR}"
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【4】=解压文件(1、通过base64转码后,执行tar解压;2、通过xzdec解压xz文件后在执行tar解压)
|
|
|
|
|
+unpackArchive() {
|
|
|
|
|
+ toConsoleInfo "Unpacking. This may take a while..."
|
|
|
|
|
+
|
|
|
|
|
+ #== 【参数】是否使用解压缓存
|
|
|
|
|
+ if [ "${PARAM_INTERNAL_USE_UNPACK_CACHE}"x = "true"x ]; then
|
|
|
|
|
+ if [ -d "${UNPACK_CACHE}" ]; then
|
|
|
|
|
+ toLogInfo "Unpack cache will be used."
|
|
|
|
|
+ cp -Rp "${UNPACK_CACHE}"/* "${TMP_DIR}"
|
|
|
|
|
+ else
|
|
|
|
|
+ toLogInfo "Unpack cache does not exist."
|
|
|
|
|
+ mkdir -p "${UNPACK_CACHE}"
|
|
|
|
|
+ #== 解压文件(1、通过base64转码后,执行tar解压;2、通过xzdec解压xz文件后在执行tar解压)
|
|
|
|
|
+ unpackArchiveWithoutCache
|
|
|
|
|
+ cp -Rp "${TMP_DIR}"/* "${UNPACK_CACHE}"
|
|
|
|
|
+ fi
|
|
|
|
|
+ else
|
|
|
|
|
+ toLogInfo "Unpacking without cache"
|
|
|
|
|
+ #== 解压文件(1、通过base64转码后,执行tar解压;2、通过xzdec解压xz文件后在执行tar解压)
|
|
|
|
|
+ unpackArchiveWithoutCache
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ toConsoleInfo "Unpacking complete."
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【3】=检查容器部署、运行情况、配置参数
|
|
|
|
|
+#isDeployedInsideOpenVZContainer
|
|
|
|
|
+#isProcessRunningInContainer
|
|
|
|
|
+#isDeployedViaContainer
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+#== Checking if libc is new enough
|
|
|
|
|
+#== 【3】=格式化version
|
|
|
|
|
+format_version() {
|
|
|
|
|
+ printf '%s' "$@" | awk -F. '{ printf("%03d%03d%03d\n", $1,$2,$3); }'
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【3】=格式化路径
|
|
|
|
|
+format_patch() {
|
|
|
|
|
+ printf '%s' "$@" | tail -n 1 | awk -F- '{ printf("%d\n", $3); }'
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【3】=检查是否降级安装
|
|
|
|
|
+checkIfDowngrade() {
|
|
|
|
|
+ if [ "${SKIP_DOWNGRADE_CHECK}"x = "true"x ]; then
|
|
|
|
|
+ toConsoleInfo "Skipped downgrade check"
|
|
|
|
|
+ return
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ local installVersionFile="${INSTALL_DIR}/installer.version"
|
|
|
|
|
+ if [ ! -f "${installVersionFile}" ]; then
|
|
|
|
|
+ toLogWarn "Could not perform downgrade check, ${installVersionFile} file is missing"
|
|
|
|
|
+ return
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ local oldVersion
|
|
|
|
|
+ oldVersion="$(cat "${installVersionFile}")"
|
|
|
|
|
+ if [ "$(format_version "${AGENT_INSTALLER_VERSION}")" -eq "$(format_version "${oldVersion}")" ]; then
|
|
|
|
|
+ toConsoleError "${BRAND_PRODUCT_NAME} is already installed, please uninstall the old version using [${INSTALL_DIR}/uninstall.sh]."
|
|
|
|
|
+# toLogError "Attempted downgrade from ${oldVersion} to ${AGENT_INSTALLER_VERSION}"
|
|
|
|
|
+ finishInstallation "${EXIT_CODE_UNSUPPORTED_DOWNGRADE}"
|
|
|
|
|
+ fi
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【3】=检查是否已经安装
|
|
|
|
|
+checkIfAlreadyInstalled() {
|
|
|
|
|
+ if [ -f "${INSTALL_DIR}/uninstall.sh" ] && [ -f "${AGENT_BIN_DIR}/${AGENT_PROC}" ] ; then
|
|
|
|
|
+# toConsoleError "Agent already installed. Uninstalling previous version."
|
|
|
|
|
+# finishInstallation "${EXIT_CODE_GENERIC_ERROR}"
|
|
|
|
|
+
|
|
|
|
|
+ checkIfDowngrade
|
|
|
|
|
+ PARAM_UPGRADE="yes"
|
|
|
|
|
+ else
|
|
|
|
|
+# if [ -f "${SIF_AGENT_INSTALL_PATH}/lib64/${AGENT_BIN}" ]; then
|
|
|
|
|
+# sif_toConsoleError "Upgrade is not possible because uninstall script is missing"
|
|
|
|
|
+# finishInstallation "${EXIT_CODE_GENERIC_ERROR}"
|
|
|
|
|
+# fi
|
|
|
|
|
+ local fileNum
|
|
|
|
|
+ fileNum=`ls ${INSTALL_DIR} | wc -l`
|
|
|
|
|
+ if [ "${fileNum}" -gt 1 ];then
|
|
|
|
|
+ toConsoleError "${INSTALL_DIR} is not empty. Please clean or change the installation directory manually."
|
|
|
|
|
+ finishInstallation "${EXIT_CODE_GENERIC_ERROR}"
|
|
|
|
|
+ fi
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#**********************************************************
|
|
|
|
|
+# Init related functions
|
|
|
|
|
+#**********************************************************
|
|
|
|
|
+
|
|
|
|
|
+#== clears dependencies in LSB init script
|
|
|
|
|
+#== 【5】=清除LSB init脚本中的依赖项
|
|
|
|
|
+clearDependenciesInLSBInit() {
|
|
|
|
|
+ local file="${1}"
|
|
|
|
|
+ toConsoleInfo "Clearing dependencies in file ${file}"
|
|
|
|
|
+ awk '
|
|
|
|
|
+ BEGIN {
|
|
|
|
|
+ req_start_found=0;
|
|
|
|
|
+ req_stop_found=0;
|
|
|
|
|
+ REQ_START="# Required-Start:";
|
|
|
|
|
+ REQ_STOP="# Required-Stop:";
|
|
|
|
|
+ PATTERN_REQ_START="^" REQ_START;
|
|
|
|
|
+ PATTERN_REQ_STOP="^" REQ_STOP;
|
|
|
|
|
+ }
|
|
|
|
|
+ {
|
|
|
|
|
+ if ($0 ~ PATTERN_REQ_START && req_start_found == 0) {
|
|
|
|
|
+ print REQ_START;
|
|
|
|
|
+ req_start_found++;
|
|
|
|
|
+ } else if ($0 ~ PATTERN_REQ_STOP && req_stop_found == 0) {
|
|
|
|
|
+ print REQ_STOP;
|
|
|
|
|
+ req_stop_found++;
|
|
|
|
|
+ } else
|
|
|
|
|
+ print $0
|
|
|
|
|
+ }' "${file}" >"${file}.tmp" && mv -f "${file}.tmp" "${file}"
|
|
|
|
|
+
|
|
|
|
|
+ chmod +x "${file}"
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【5】=指定目录添加自动启动脚本
|
|
|
|
|
+addScriptToSystemvAutostart() {
|
|
|
|
|
+ local prefix="${1}"
|
|
|
|
|
+ local file="${2}"
|
|
|
|
|
+ local suffix="${3}"
|
|
|
|
|
+
|
|
|
|
|
+ toLogInfo "Adding ${file} to autostart"
|
|
|
|
|
+ #== 自动启动工具
|
|
|
|
|
+ if ! runAutostartAddingTool "${prefix}" "${file}" "${suffix}"; then
|
|
|
|
|
+ toLogWarn "Failed to add ${file} script to autostart. Trying without dependencies..."
|
|
|
|
|
+ #== 清除LSB init脚本中的依赖项
|
|
|
|
|
+ clearDependenciesInLSBInit "${INIT_DIR}/${file}"
|
|
|
|
|
+ if ! runAutostartAddingTool "${prefix}" "${file}" "${suffix}"; then
|
|
|
|
|
+ toConsoleError "Cannot add ${file} to autostart. For details, see: ${LOG_FILE}"
|
|
|
|
|
+ fi
|
|
|
|
|
+ fi
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【5】=指定目录添加自动启动脚本
|
|
|
|
|
+addScriptsToAutostart() {
|
|
|
|
|
+ local prefix="${1}"
|
|
|
|
|
+ local suffix="${2}"
|
|
|
|
|
+ #== 指定目录添加自动启动脚本
|
|
|
|
|
+ addScriptToSystemvAutostart "${prefix}" "${SERVICE_SCRIPT_FILE}" "${suffix}"
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【5】=设置自动启动
|
|
|
|
|
+#setupSystemvAutostart() {
|
|
|
|
|
+# toLogInfo "Adding ${BRAND_AGENT_PRODUCT_NAME} to autostart..."
|
|
|
|
|
+#
|
|
|
|
|
+# if [ -x /usr/bin/update-rc.d ]; then #Ubuntu
|
|
|
|
|
+# #== 指定目录添加自动启动脚本
|
|
|
|
|
+# addScriptsToAutostart "/usr/bin/update-rc.d " "defaults"
|
|
|
|
|
+# elif [ -x /usr/sbin/update-rc.d ]; then #Ubuntu
|
|
|
|
|
+# addScriptsToAutostart "/usr/sbin/update-rc.d " "defaults"
|
|
|
|
|
+# elif [ -x /sbin/chkconfig ]; then #RedHat
|
|
|
|
|
+# addScriptsToAutostart "/sbin/chkconfig --add "
|
|
|
|
|
+# elif [ -x /usr/lib/lsb/install_initd ]; then #Suse
|
|
|
|
|
+# addScriptsToAutostart "/usr/lib/lsb/install_initd ${INIT_DIR}/"
|
|
|
|
|
+# elif [ "${ARCH_ARCH}"x = "AIX"x ]; then
|
|
|
|
|
+# #== 【不存在】
|
|
|
|
|
+# arch_setAutostart
|
|
|
|
|
+# else
|
|
|
|
|
+# toConsoleError "Couldn't add ${BRAND_AGENT_PRODUCT_NAME} to autostart. Please adjust and add it manually."
|
|
|
|
|
+# fi
|
|
|
|
|
+#}
|
|
|
|
|
+
|
|
|
|
|
+#== 【5】=设置 cwserveragent.service 中用户
|
|
|
|
|
+setServiceScriptUser() {
|
|
|
|
|
+ if ! isNonRootModeEnabled; then
|
|
|
|
|
+ return
|
|
|
|
|
+ fi
|
|
|
|
|
+ #== 读取用户名(调用 agent 64位数lib路径(lib64/installaction)执行指令 --get-user)
|
|
|
|
|
+ local user
|
|
|
|
|
+ user="$(getValueFromConfigFile "${CONF_FIELD_NM_USER}" "${LEGACY_AGENT_CONF_FILE}" "${BRAND_AGENT_DEFAULT_USER_AND_GROUP_NAME}")"
|
|
|
|
|
+ #== 修改 cwserveragent.service 中用户信息
|
|
|
|
|
+ sed -i "s/User=.*/User=${user}/g" "${SYSTEMD_UNIT_FILES_DIR}/${SYSTEMD_UNIT_FILE_AGENT}"
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【5】=配置自动启动 cwserveragent.service
|
|
|
|
|
+setupSystemdAutostart() {
|
|
|
|
|
+ mv -f "${AGENT_SCRIPTS_DIR}/${SYSTEMD_UNIT_FILE_AGENT}" "${SYSTEMD_UNIT_FILES_DIR}/"
|
|
|
|
|
+ setRightsForFiles "${SYSTEMD_UNIT_FILES_DIR}/${SYSTEMD_UNIT_FILE_AGENT}" 644
|
|
|
|
|
+
|
|
|
|
|
+ #== 设置 cwserveragent.service 中用户
|
|
|
|
|
+ setServiceScriptUser
|
|
|
|
|
+
|
|
|
|
|
+ if isAvailable restorecon; then
|
|
|
|
|
+ restorecon "${SYSTEMD_UNIT_FILES_DIR}/${SYSTEMD_UNIT_FILE_AGENT}"
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ #== 执行 systemctl 命令配置允许开机启动 cwserveragent.service
|
|
|
|
|
+ executeSystemctlCommand enable "${SYSTEMD_UNIT_FILE_AGENT}"
|
|
|
|
|
+ #== 执行 systemctl 命令重新加载模块
|
|
|
|
|
+ executeSystemctlCommand daemon-reload ""
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【6】=运行service 脚本
|
|
|
|
|
+execIntoServiceScript() {
|
|
|
|
|
+ toConsoleInfo "${SERVICE_SCRIPT_FILE} will be started via exec()"
|
|
|
|
|
+ #== 清除安装临时文件
|
|
|
|
|
+ cleanInstallationTemporaryFiles
|
|
|
|
|
+ toLogInfo "Installation finished, PID $$."
|
|
|
|
|
+
|
|
|
|
|
+ local command="exec ${AGENT_SCRIPTS_DIR}/${SERVICE_SCRIPT_FILE} exec"
|
|
|
|
|
+ toLogInfo "Executing: ${command}"
|
|
|
|
|
+ #== 执行 cwserveragent exec
|
|
|
|
|
+ ${command}
|
|
|
|
|
+
|
|
|
|
|
+ toLogError "Could not execute: ${command}"
|
|
|
|
|
+ finishInstallation "${EXIT_CODE_GENERIC_ERROR}"
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【6】=运行agent
|
|
|
|
|
+runAgents() {
|
|
|
|
|
+ toConsoleInfo "Starting agents..."
|
|
|
|
|
+
|
|
|
|
|
+ toLogInfo "Using ${INIT_SYSTEM} to start the agent"
|
|
|
|
|
+ if [ "${INIT_SYSTEM}"x = "${INIT_SYSTEM_SYSV}"x ]; then
|
|
|
|
|
+ #== 运行初始化命令(通过 service start 方式 或 直接运行可执行命令)
|
|
|
|
|
+ executeInitScriptCommand start "true"
|
|
|
|
|
+ else
|
|
|
|
|
+ #== 执行 systemctl start 命令
|
|
|
|
|
+ executeSystemctlCommand start "${SYSTEMD_UNIT_FILE_AGENT}"
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ if [ $? -eq 0 ]; then
|
|
|
|
|
+ toConsoleInfo "${SERVICE_SCRIPT_FILE} service started"
|
|
|
|
|
+ else
|
|
|
|
|
+ toConsoleError "Failed to start service: ${SERVICE_SCRIPT_FILE}, it is possible that your init system is not functioning properly. For details, see: ${LOG_FILE}"
|
|
|
|
|
+ fi
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【5】=配置自动启动
|
|
|
|
|
+#setupAutostart() {
|
|
|
|
|
+# if [ "${INIT_SYSTEM}"x = "${INIT_SYSTEM_SYSV}"x ]; then
|
|
|
|
|
+# #== 设置自动启动
|
|
|
|
|
+# setupSystemvAutostart
|
|
|
|
|
+# else
|
|
|
|
|
+# #== 配置自动启动 cwserveragent.service
|
|
|
|
|
+# setupSystemdAutostart
|
|
|
|
|
+# fi
|
|
|
|
|
+#}
|
|
|
|
|
+
|
|
|
|
|
+#**********************************************************
|
|
|
|
|
+# Process agent related functions
|
|
|
|
|
+#**********************************************************
|
|
|
|
|
+
|
|
|
|
|
+#== 【5】=创建 agent 状态文件
|
|
|
|
|
+createAgentStateFile() {
|
|
|
|
|
+ local path="${1}"
|
|
|
|
|
+ local agentStateContents="RUNNING"
|
|
|
|
|
+
|
|
|
|
|
+ toLogInfo "Writing ${agentStateContents} to ${path} file"
|
|
|
|
|
+ {
|
|
|
|
|
+ printf "%s" "${agentStateContents}" >"${path}.tmp"
|
|
|
|
|
+ mv -f "${path}.tmp" "${path}"
|
|
|
|
|
+ } 2>>"${LOG_FILE}"
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【0】=检查全路径是否可读权限(目录最深100层)
|
|
|
|
|
+checkIfPathIsGloballyReadable() {
|
|
|
|
|
+ local path="${1}"
|
|
|
|
|
+ local sourcePath="${path}"
|
|
|
|
|
+ local maxDepth=100
|
|
|
|
|
+ while [ "${path}"x != "/"x ]; do
|
|
|
|
|
+ #== 【0】=获取文件权限信息
|
|
|
|
|
+ local accessRights
|
|
|
|
|
+ accessRights="$(arch_getAccessRights "${path}")"
|
|
|
|
|
+ if ! printf '%s' "${accessRights}" | cut -c 8-10 | grep -qE "r.[xt]"; then
|
|
|
|
|
+ toConsoleError "Insufficient access rights (${accessRights}) on: ${path}"
|
|
|
|
|
+ toConsoleError "${sourcePath} path must be globally readable (r-x permissions for others)."
|
|
|
|
|
+ toConsoleError "Please adjust the permissions and then retry the installation."
|
|
|
|
|
+ finishInstallation "${EXIT_CODE_INSUFFICIENT_PERMISSIONS}"
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ path="$(dirname "${path}")"
|
|
|
|
|
+
|
|
|
|
|
+ maxDepth=$((maxDepth - 1))
|
|
|
|
|
+ if [ "${maxDepth}" -eq 0 ]; then
|
|
|
|
|
+ toLogWarn "Unable to verify access rights on ${path}"
|
|
|
|
|
+ return
|
|
|
|
|
+ fi
|
|
|
|
|
+ done
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【0】=创建 PARAM_INSTALL_DIR -> INSTALL_DIR 软连接
|
|
|
|
|
+createSymlinkToInstallLocation() {
|
|
|
|
|
+ #== INSTALL_DIR 不能是软链接地址
|
|
|
|
|
+ if [ -L "${INSTALL_DIR}" ] && [ ! -e "${INSTALL_DIR}" ]; then
|
|
|
|
|
+ toConsoleError "Detected that ${INSTALL_DIR} is a dangling symlink, please remove it and then retry the installation"
|
|
|
|
|
+ finishInstallation "${EXIT_CODE_GENERIC_ERROR}"
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ #== PARAM_INSTALL_DIR 和 INSTALL_DIR 都不能是空地址
|
|
|
|
|
+ if [ "${PARAM_INSTALL_DIR}"x = "${INSTALL_DIR}"x ] || [ -z "${PARAM_INSTALL_DIR}" ]; then
|
|
|
|
|
+ return
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ #== INSTALL_DIR 是软连接,并获取 PARAM_INSTALL_DIR 和 INSTALL_DIR 的真实地址
|
|
|
|
|
+ if [ -L "${INSTALL_DIR}" ] && [ "$(readLink -m "${PARAM_INSTALL_DIR}")"x = "$(readLink -m "${INSTALL_DIR}")"x ]; then
|
|
|
|
|
+ return
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ #== 目录存在,表示未卸载
|
|
|
|
|
+ if [ -e "${INSTALL_DIR}" ]; then
|
|
|
|
|
+ toConsoleError "Leftovers from previous agent installation detected"
|
|
|
|
|
+ toConsoleError "If you wish to use INSTALL_DIR parameter then perform a cleanup by following these steps:"
|
|
|
|
|
+ toConsoleError "1. Uninstall the agent"
|
|
|
|
|
+ toConsoleError "2. Restart all applications that have Deep Monitoring enabled (host restart is fine as well)"
|
|
|
|
|
+ toConsoleError "3. Remove ${INSTALL_DIR}"
|
|
|
|
|
+ toConsoleError "and then retry the installation."
|
|
|
|
|
+ toConsoleError "#DEBUG==For further information please visit ${HELP_URL}/command-line-install"
|
|
|
|
|
+ finishInstallation "${EXIT_CODE_GENERIC_ERROR}"
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ #== 创建不存在的目录
|
|
|
|
|
+ createDirIfNotExistAndSetRights "${PARAM_INSTALL_DIR}" 1775
|
|
|
|
|
+ #== 检查全路径是否可读权限(目录最深100层)
|
|
|
|
|
+ checkIfPathIsGloballyReadable "${PARAM_INSTALL_DIR}"
|
|
|
|
|
+ #== 创建不存在的目录 /opt/cloudwise
|
|
|
|
|
+ createDirIfNotExistAndSetRights "${BASE_INSTALL_DIR}" 755
|
|
|
|
|
+
|
|
|
|
|
+ #== 创建 PARAM_INSTALL_DIR -> INSTALL_DIR
|
|
|
|
|
+ local lnOutput
|
|
|
|
|
+ if lnOutput="$(ln -fs "${PARAM_INSTALL_DIR}" "${INSTALL_DIR}" 2>&1)"; then
|
|
|
|
|
+ toConsoleInfo "Symlink ${INSTALL_DIR} -> ${PARAM_INSTALL_DIR} created"
|
|
|
|
|
+ else
|
|
|
|
|
+ toConsoleError "Failed to create symlink ${INSTALL_DIR} -> ${PARAM_INSTALL_DIR}, aborting installation: ${lnOutput}"
|
|
|
|
|
+ finishInstallation "${EXIT_CODE_GENERIC_ERROR}"
|
|
|
|
|
+ fi
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【5】=修改文件系统用户和用户组
|
|
|
|
|
+changeFilesOwnership() {
|
|
|
|
|
+ local user
|
|
|
|
|
+ local group
|
|
|
|
|
+ user="$(getValueFromConfigFile "${CONF_FIELD_NM_USER}" "${LEGACY_AGENT_CONF_FILE}" "${BRAND_AGENT_DEFAULT_USER_AND_GROUP_NAME}")"
|
|
|
|
|
+ group="$(getValueFromConfigFile "${CONF_FIELD_NM_GROUP}" "${LEGACY_AGENT_CONF_FILE}" "${BRAND_AGENT_DEFAULT_USER_AND_GROUP_NAME}")"
|
|
|
|
|
+
|
|
|
|
|
+ toLogInfo "Changing ownership of files to root:${group}"
|
|
|
|
|
+ #== /opt/cloudwise/cwserveragent 目录下用户和用户组
|
|
|
|
|
+ commandErrorWrapper chown "${user}:${group}" "${AGENT_BASE_DIR}"
|
|
|
|
|
+ commandErrorWrapper chown -R "${user}:${group}" "${INSTALL_DIR}"
|
|
|
|
|
+ toLogInfo "Recursively changing group ownership of ${AGENT_CONF_DIR} to ${group}"
|
|
|
|
|
+
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【5】=文件用户权限检查
|
|
|
|
|
+fileCapabilitiesCompatibilityCheck() {
|
|
|
|
|
+ #== 获取配置用户
|
|
|
|
|
+ local user
|
|
|
|
|
+ user="$(getValueFromConfigFile "${CONF_FIELD_NM_USER}" "${LEGACY_AGENT_CONF_FILE}" "${BRAND_AGENT_DEFAULT_USER_AND_GROUP_NAME}")"
|
|
|
|
|
+ #== 获取OS bin配置路径 /opt/cloudwise/cwserveragent/lib64/cloudwiseosconfig
|
|
|
|
|
+ if output="$("$(getOsConfigBinPath)" file-capabilities-compatibility-check "${user}" 2>&1)"; then
|
|
|
|
|
+ return 0
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ if [ "${PARAM_NON_ROOT_MODE}" ]; then
|
|
|
|
|
+ toConsoleWarn "Failed to enable non-privileged mode, kernel does not support file capabilities. For details, see: ${LOG_FILE}"
|
|
|
|
|
+ toLogWarn "Capabilities test output: ${output}"
|
|
|
|
|
+ else
|
|
|
|
|
+ toConsoleInfo "Non-privileged mode was not enabled, kernel does not support file capabilities. For details, see: ${LOG_FILE}"
|
|
|
|
|
+ toLogInfo "Capabilities test output: ${output}"
|
|
|
|
|
+ fi
|
|
|
|
|
+ #== 设置删除root权限
|
|
|
|
|
+ "$(getAgentInstallActionPath)" "--set-drop-root-privileges" "false" >>"${LOG_FILE}" 2>&1
|
|
|
|
|
+ return 1
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+#**********************************************************
|
|
|
|
|
+# User and group related functions
|
|
|
|
|
+#**********************************************************
|
|
|
|
|
+
|
|
|
|
|
+#== 【5】=添加用户组
|
|
|
|
|
+addGroup() {
|
|
|
|
|
+ local group="${1}"
|
|
|
|
|
+
|
|
|
|
|
+ if groupExistsInSystem "${group}"; then
|
|
|
|
|
+ toLogInfo "Group '${group}' already exists"
|
|
|
|
|
+ return 0
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ local errorMessage
|
|
|
|
|
+ errorMessage="$(groupadd "${group}" 2>&1)"
|
|
|
|
|
+ local returnCode=$?
|
|
|
|
|
+
|
|
|
|
|
+ case ${returnCode} in
|
|
|
|
|
+ 0) toLogInfo "Group '${group}' successfully created" ;;
|
|
|
|
|
+ 9) toLogInfo "Group '${group}' already exists" ;;
|
|
|
|
|
+ *)
|
|
|
|
|
+ toLogError "Error occured while adding '${group}' group, return code: ${returnCode}, message ${errorMessage}"
|
|
|
|
|
+ return 1
|
|
|
|
|
+ ;;
|
|
|
|
|
+ esac
|
|
|
|
|
+ return 0
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【5】=添加用户
|
|
|
|
|
+addUser() {
|
|
|
|
|
+ local user="${1}"
|
|
|
|
|
+ local group="${2}"
|
|
|
|
|
+ local groupCreated="${3}"
|
|
|
|
|
+ local errorMessage
|
|
|
|
|
+ local mod="/bin/false"
|
|
|
|
|
+ if [ "${PARAM_USER_LOGIN}"x == "true"x ]; then
|
|
|
|
|
+ mod="/bin/bash"
|
|
|
|
|
+ fi
|
|
|
|
|
+ if userExistsInSystem "${user}"; then
|
|
|
|
|
+ toLogInfo "User '${user}' already exists."
|
|
|
|
|
+ #-- 权限更新
|
|
|
|
|
+# errorMessage="$(usermod -s "${mod}" "${user}" 2>&1)"
|
|
|
|
|
+ return 0
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ if [ "${groupCreated}" -eq 0 ]; then
|
|
|
|
|
+ errorMessage="$(useradd -r --shell "${mod}" -g "${group}" "${user}" 2>&1)"
|
|
|
|
|
+ else
|
|
|
|
|
+ errorMessage="$(useradd -r --shell "${mod}" "${user}" 2>&1)"
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ local returnCode=$?
|
|
|
|
|
+ if [ ${returnCode} -ne 0 ]; then
|
|
|
|
|
+ toConsoleError "Failed to create user '${user}'"
|
|
|
|
|
+ toLogError "Error occured while adding '${user}' user, return value: ${returnCode}, error message: ${errorMessage}."
|
|
|
|
|
+ return 1
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ toConsoleInfo "User '${user}' added successfully."
|
|
|
|
|
+ return 0
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【5】=添加用户和用户组信息
|
|
|
|
|
+addUserAndGroup() {
|
|
|
|
|
+ local user="${1}"
|
|
|
|
|
+ local group="${2}"
|
|
|
|
|
+ #== 添加用户组
|
|
|
|
|
+ addGroup "${group}"
|
|
|
|
|
+ #== 添加用户
|
|
|
|
|
+ addUser "${user}" "${group}" $?
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【5】=配置用户和用户组
|
|
|
|
|
+handleUser() {
|
|
|
|
|
+ toLogInfo "Processing user and group..."
|
|
|
|
|
+ local user
|
|
|
|
|
+ local group
|
|
|
|
|
+ #== 读取用户名(调用 agent 64位数lib路径(lib64/installaction)执行指令 --get-user)
|
|
|
|
|
+ user="$(getValueFromConfigFile "${CONF_FIELD_NM_USER}" "${LEGACY_AGENT_CONF_FILE}" "${BRAND_AGENT_DEFAULT_USER_AND_GROUP_NAME}")"
|
|
|
|
|
+ #== 读取用户组(调用 agent 64位数lib路径(lib64/installaction)执行指令 --get-group)
|
|
|
|
|
+ group="$(getValueFromConfigFile "${CONF_FIELD_NM_GROUP}" "${LEGACY_AGENT_CONF_FILE}" "${BRAND_AGENT_DEFAULT_USER_AND_GROUP_NAME}")"
|
|
|
|
|
+ #== 添加用户和用户组信息
|
|
|
|
|
+ addUserAndGroup "${user}" "${group}"
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【4】=获取agent preLoad 安装路径,并校验是否可执行
|
|
|
|
|
+checkCompatibilityWithInstallActionBinary() {
|
|
|
|
|
+ local output
|
|
|
|
|
+ #== 获取agent preLoad 安装路径,并校验是否可执行
|
|
|
|
|
+ output="$("$(getAgentInstallActionPathPreInstallation)" "--sanity-check" 2>&1)"
|
|
|
|
|
+ local exitCode=$?
|
|
|
|
|
+ toLogAdaptive ${exitCode} "Compatibility check exit code = ${exitCode}, output = ${output}"
|
|
|
|
|
+ if [ ${exitCode} -ne 0 ] || [ "${output}"x != "SUCCESS"x ]; then
|
|
|
|
|
+ toConsoleError "System compatibility check failed, this may be caused by a problem with glibc, dynamic loader or incompatible operating system version."
|
|
|
|
|
+ toConsoleError "Detected version: $(detectLinuxDistribution)"
|
|
|
|
|
+ toConsoleError "For a list of supported distributions and versions, see: ${HELP_URL}"
|
|
|
|
|
+ finishInstallation "${EXIT_CODE_GENERIC_ERROR}"
|
|
|
|
|
+ fi
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【4】=【部署】解压文件
|
|
|
|
|
+extractFiles() {
|
|
|
|
|
+ umask 000
|
|
|
|
|
+ toConsoleInfo "Extracting..."
|
|
|
|
|
+ #== 从sh文件读取压缩文件 tarfile_$$.base64
|
|
|
|
|
+ separateExternalTar
|
|
|
|
|
+ #== 解压文件(1、通过base64转码后,执行tar解压;2、通过xzdec解压xz文件后在执行tar解压)
|
|
|
|
|
+ unpackArchive
|
|
|
|
|
+ umask 022
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【3】=检查发现初始化系统信息(INIT_SYSTEM、INIT_SYSTEM_VERSION、INIT_DIR)
|
|
|
|
|
+detectInitSystem() {
|
|
|
|
|
+ #== 获取初始化系统信息 (INIT_SYSTEM、INIT_SYSTEM_VERSION)
|
|
|
|
|
+ checkInitSystem
|
|
|
|
|
+ toLogInfo "Detected init system: ${INIT_SYSTEM}, version: ${INIT_SYSTEM_VERSION}"
|
|
|
|
|
+ #== 设置系统初始化脚本目录
|
|
|
|
|
+ if ! setLocationOfScripts; then
|
|
|
|
|
+ toConsoleError "Cannot determine location of init scripts."
|
|
|
|
|
+ finishInstallation "${EXIT_CODE_GENERIC_ERROR}"
|
|
|
|
|
+ fi
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【4】=【旧配置】读取旧配置参数
|
|
|
|
|
+readLegacySetting() {
|
|
|
|
|
+ local paramName="${1}"
|
|
|
|
|
+ local value
|
|
|
|
|
+ value="$(sed -n "s|^${paramName}=||p" "${LEGACY_AGENT_CONF_FILE}" | tr -d '\r' 2>/dev/null)"
|
|
|
|
|
+ if [ "${value}" ]; then
|
|
|
|
|
+ local valueToPrint="${value}"
|
|
|
|
|
+ if [ "${paramName}"x = "${CONF_FIELD_NM_LICENSE}"x ]; then
|
|
|
|
|
+ valueToPrint="***"
|
|
|
|
|
+ fi
|
|
|
|
|
+ toLogInfo "Read legacy value: ${paramName} = ${valueToPrint}"
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ printf '%s' "${value}"
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【4】=【旧配置】迁移旧配置文件
|
|
|
|
|
+migrateLegacySettingsFromAgentConf() {
|
|
|
|
|
+ toLogInfo "Looking for legacy config to migrate."
|
|
|
|
|
+ #== 旧配置文件
|
|
|
|
|
+ if [ ! -f "${LEGACY_AGENT_CONF_FILE}" ]; then
|
|
|
|
|
+ toLogInfo "Unable to read agent config file, skipping legacy config migration"
|
|
|
|
|
+ return
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ if [ ! "${PARAM_CONFIG_SERVER}" ]; then
|
|
|
|
|
+ local configServerValue
|
|
|
|
|
+ configServerValue="$(readLegacySetting ${CONF_FIELD_NM_CONFIG_SERVER})"
|
|
|
|
|
+ toConsoleInfo "#DEBUG== legacy config: ${CONF_FIELD_NM_CONFIG_SERVER}: ${PARAM_CONFIG_SERVER}"
|
|
|
|
|
+ if [ "${configServerValue}"x = "http://localhost:8020"x ]; then
|
|
|
|
|
+ toLogInfo "Param 'server' has default value set, skipping it"
|
|
|
|
|
+ else
|
|
|
|
|
+ PARAM_CONFIG_SERVER="${configServerValue}"
|
|
|
|
|
+ fi
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ if [ ! "${PARAM_DATA_SERVER}" ]; then
|
|
|
|
|
+ PARAM_DATA_SERVER="$(readLegacySetting ${CONF_FIELD_NM_DATA_SERVER})"
|
|
|
|
|
+ toConsoleInfo "#DEBUG== legacy config: ${CONF_FIELD_NM_DATA_SERVER}: ${PARAM_DATA_SERVER}"
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ if [ ! "${PARAM_LICENSE}" ]; then
|
|
|
|
|
+ PARAM_LICENSE="$(readLegacySetting ${CONF_FIELD_NM_LICENSE})"
|
|
|
|
|
+ toConsoleInfo "#DEBUG== legacy config: ${CONF_FIELD_NM_LICENSE}: ${PARAM_LICENSE}"
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ if [ ! "${PARAM_JSON_CONF}" ]; then
|
|
|
|
|
+ PARAM_JSON_CONF="$(readLegacySetting ${CONF_FIELD_NM_JSON_CONF})"
|
|
|
|
|
+ toConsoleInfo "#DEBUG== legacy config: ${CONF_FIELD_NM_JSON_CONF}: ${PARAM_JSON_CONF}"
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ if [ ! "${PARAM_USER}" ]; then
|
|
|
|
|
+ PARAM_USER="$(readLegacySetting ${CONF_FIELD_NM_USER})"
|
|
|
|
|
+ toConsoleInfo "#DEBUG== legacy config: ${CONF_FIELD_NM_USER}: ${PARAM_USER}"
|
|
|
|
|
+
|
|
|
|
|
+ if [ ! "${PARAM_GROUP}" ]; then
|
|
|
|
|
+ PARAM_GROUP="$(readLegacySetting ${CONF_FIELD_NM_GROUP})"
|
|
|
|
|
+ toConsoleInfo "#DEBUG== legacy config: ${CONF_FIELD_NM_GROUP}: ${PARAM_GROUP}"
|
|
|
|
|
+ fi
|
|
|
|
|
+ fi
|
|
|
|
|
+}
|
|
|
|
|
+listProcesses() {
|
|
|
|
|
+ local errorMessage="${1}"
|
|
|
|
|
+ local includeRegex="${2}"
|
|
|
|
|
+
|
|
|
|
|
+ local excludeRegex=" grep"
|
|
|
|
|
+ if [ "${3}" ]; then
|
|
|
|
|
+ excludeRegex="grep|${3}"
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ toLogInfo "#DEBUG== listProcesses command: ps -e -o \"pid,args\" 2>&1 | grep -E \"${includeRegex}\" | awk '{{ print \$1,\$2 }}' | grep -vE \"${excludeRegex}\""
|
|
|
|
|
+ local output
|
|
|
|
|
+ if ! output="$(pgrep -f "pid,args" 2>&1 | grep -E "${includeRegex}" | awk '{{ print $1,$2 }}')"; then
|
|
|
|
|
+ toLogError "Failed to get ${errorMessage}, output: ${output}"
|
|
|
|
|
+ return 1
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ local foundProcesses
|
|
|
|
|
+ foundProcesses="$(printf '%s' "${output}" | grep -vE "${excludeRegex}")"
|
|
|
|
|
+ if [ ! "${foundProcesses}" ]; then
|
|
|
|
|
+ return 1
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ printf '%s' "${foundProcesses}" | awk '{{ print $1 }}'
|
|
|
|
|
+ return 0
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 版本&帮助信息
|
|
|
|
|
+preParams() {
|
|
|
|
|
+ if [ $# -gt 0 ]; then
|
|
|
|
|
+ if [ "${1}"x = "-h"x ] || [ "${1}"x = "--help"x ]; then
|
|
|
|
|
+ displayHelp
|
|
|
|
|
+ exit "${EXIT_CODE_OK}"
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ if [ "${1}"x = "-v"x ] || [ "${1}"x = "--version"x ]; then
|
|
|
|
|
+ pad=20
|
|
|
|
|
+ printf "%-${pad}s%s\n" "Version:" "${AGENT_INSTALLER_VERSION}"
|
|
|
|
|
+ printf "%-${pad}s%s\n" "Commit:" "${AGENT_BUILD_TAG}"
|
|
|
|
|
+ printf "%-${pad}s%s\n" "Build At(UTC):" "${AGENT_BUILD_DATE_INFO}"
|
|
|
|
|
+ printf "%-${pad}s%s\n" "Uploader:" "${AGENT_BUILD_UPLOADER}"
|
|
|
|
|
+ exit "${EXIT_CODE_OK}"
|
|
|
|
|
+ fi
|
|
|
|
|
+ fi
|
|
|
|
|
+}
|
|
|
|
|
+#**********************************************************
|
|
|
|
|
+# Main script functions
|
|
|
|
|
+#**********************************************************
|
|
|
|
|
+
|
|
|
|
|
+#== 【0】=初始化安装环境
|
|
|
|
|
+initializeInstallation() {
|
|
|
|
|
+ preParams "$@"
|
|
|
|
|
+ #== 设置PATH
|
|
|
|
|
+ setPATH
|
|
|
|
|
+ #== 配置umask权限
|
|
|
|
|
+ local initialUmask
|
|
|
|
|
+ initialUmask="$(umask)"
|
|
|
|
|
+ umask 022
|
|
|
|
|
+
|
|
|
|
|
+ #== 读取配置参数
|
|
|
|
|
+# readParamsSection
|
|
|
|
|
+ #== 解析命令行参数
|
|
|
|
|
+ parseCommandLineParameters "$@"
|
|
|
|
|
+ #== 校验配置参数
|
|
|
|
|
+
|
|
|
|
|
+ #== 是否存在多个同时安装操作【通过判断 INSTALLER_LOCK_FILE 】
|
|
|
|
|
+ if isAnotherInstallationRunning; then
|
|
|
|
|
+ #== 结束安装操作
|
|
|
|
|
+ finishInstallation "${EXIT_CODE_ANOTHER_INSTALLER_RUNNING}" "keep_lock_file"
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ #== 创建安装标示文件 /tmp/${BRAND_PRODUCT_NAME_LOWER}.lock
|
|
|
|
|
+ createInstallationLockFile
|
|
|
|
|
+ #== 配置是否更新
|
|
|
|
|
+ PARAM_UPGRADE="no"
|
|
|
|
|
+
|
|
|
|
|
+ #== 获取并校验系统兼容性【LINUX/AIX X86_64/IA64】
|
|
|
|
|
+ local platformDetectionString
|
|
|
|
|
+ if ! platformDetectionString="$(checkSystemCompatibility)"; then
|
|
|
|
|
+ toConsoleError "${platformDetectionString}"
|
|
|
|
|
+ finishInstallation "${EXIT_CODE_OS_NOT_SUPPORTED}"
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ #== 创建 PARAM_INSTALL_DIR -> INSTALL_DIR 软连接
|
|
|
|
|
+ createSymlinkToInstallLocation
|
|
|
|
|
+ #== 创建日志目录及日志文件installation_$$.log
|
|
|
|
|
+ createLogDirsIfMissing
|
|
|
|
|
+ #== 配置信号捕获,执行清空安装临时目录
|
|
|
|
|
+ configureSignalHandling "cleanInstallationTemporaryFiles"
|
|
|
|
|
+ #== 常规日志
|
|
|
|
|
+ initializeLog "${@}"
|
|
|
|
|
+
|
|
|
|
|
+ toLogInfo "Initial umask: ${initialUmask}"
|
|
|
|
|
+ toConsoleInfo "${platformDetectionString}"
|
|
|
|
|
+ toLogInfo "Distribution: $(detectLinuxDistribution)"
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【3】=安装前检查
|
|
|
|
|
+preInstallationChecks() {
|
|
|
|
|
+ #== 检查发现初始化系统信息(INIT_SYSTEM、INIT_SYSTEM_VERSION、INIT_DIR)
|
|
|
|
|
+ detectInitSystem
|
|
|
|
|
+
|
|
|
|
|
+ #== 检查目录权限
|
|
|
|
|
+ checkAccessRightsToDirs
|
|
|
|
|
+ #== 创建临时目录
|
|
|
|
|
+ prepareTempFolder
|
|
|
|
|
+ #== 检查是否已经安装
|
|
|
|
|
+ checkIfAlreadyInstalled
|
|
|
|
|
+
|
|
|
|
|
+ if [ ! "${PARAM_USER}" ] && [ "${ARCH_ARCH}"x != "AIX"x ] ; then
|
|
|
|
|
+ #== 配置文件中配置用户和用户组是否存在
|
|
|
|
|
+ checkUserAndGroupFromConfig
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ #== 检查安装目录空间
|
|
|
|
|
+ checkInstallPathFreeSpace
|
|
|
|
|
+
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+uninstallAgent() {
|
|
|
|
|
+ toConsoleInfo "Agent already installed. Uninstalling previous version."
|
|
|
|
|
+# printf '%s' "upgrade" >"${UNINSTALL_INFO_FILE_LEGACY_PATH}"
|
|
|
|
|
+
|
|
|
|
|
+ #shellcheck disable=SC2086
|
|
|
|
|
+ "${INSTALL_DIR}/uninstall.sh" $$ ${SKIP_PRIVILEGES_CHECK} 2>>"${LOG_FILE}"
|
|
|
|
|
+
|
|
|
|
|
+ local uninstallExitCode=$?
|
|
|
|
|
+ if [ ${uninstallExitCode} -gt 0 ]; then
|
|
|
|
|
+ toConsoleError "Error during uninstalling, code: ${uninstallExitCode}. Installation aborted."
|
|
|
|
|
+ finishInstallation "${EXIT_CODE_GENERIC_ERROR}"
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ toConsoleInfo "Agent uninstalled."
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【4】=部署文件
|
|
|
|
|
+deployFiles() {
|
|
|
|
|
+ if [ "${PARAM_UPGRADE}" = "yes" ]; then
|
|
|
|
|
+ uninstallAgent
|
|
|
|
|
+ fi
|
|
|
|
|
+ #== 【部署】解压文件
|
|
|
|
|
+ extractFiles
|
|
|
|
|
+ setupAll
|
|
|
|
|
+ createCurrentVersionSymlink
|
|
|
|
|
+}
|
|
|
|
|
+enableRootDropping() {
|
|
|
|
|
+ local output=
|
|
|
|
|
+ if ! isAvailable setcap; then
|
|
|
|
|
+ toConsoleWarn "Failed to enable non-privileged mode, kernel does not support file capabilities. Set NON_ROOT_MODE=false."
|
|
|
|
|
+ #== writeParamToConfigFile "${CONF_FIELD_NM_NON_ROOT_MODE}" "false" "${LEGACY_AGENT_CONF_FILE}"
|
|
|
|
|
+ #== writeParamToConfigFile "${CONF_FIELD_NM_NON_ROOT_MODE}" "false" "${INSTALLER_CONF_FILE}"
|
|
|
|
|
+ #== editScriptFileParam "readonly PARAM_NON_ROOT_MODE" "false" "${AGENT_SCRIPTS_DIR}/${SERVICE_SCRIPT_FILE}"
|
|
|
|
|
+ return
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ #== 设置文件权限 (https://www.cnblogs.com/xzongblogs/p/14106481.html)
|
|
|
|
|
+ #== CAP_DAC_OVERRIDE:绕过文件的读,写,和执行权限检查。
|
|
|
|
|
+ #== CAP_FOWNER:对于通常要求进程的文件系统 UID 与文件的 UID 匹配的操作,绕过权限检查 (比如,chmod(2),utime(2)),除了那些包含在 CAP_DAC_OVERRIDE 和 CAP_DAC_READ_SEARCH 中的操作
|
|
|
|
|
+ #== CAP_IPC_LOCK:允许锁定共享内存片段
|
|
|
|
|
+ #== CAP_SYS_PTRACE:允许跟踪任何进程
|
|
|
|
|
+ #== CAP_SYS_ADMIN:访问特权 perf 事件信息
|
|
|
|
|
+ #== CAP_SYS_RESOURCE:忽略资源限制
|
|
|
|
|
+ #== CAP_NET_ADMIN:允许执行多种网络有关的操作
|
|
|
|
|
+ commandErrorWrapper setcap cap_setgid,cap_setuid,cap_dac_override,cap_fowner,cap_chown,cap_ipc_lock,cap_sys_ptrace,cap_sys_admin,cap_sys_resource,cap_net_admin+ep "${AGENT_BIN_DIR}/${AGENT_PROC}"
|
|
|
|
|
+ local setCapCwServerAgentExitCode=$?
|
|
|
|
|
+ if [ ${setCapCwServerAgentExitCode} -eq 0 ] ; then
|
|
|
|
|
+ toConsoleInfo "Set file capabilities [${AGENT_PROC}]"
|
|
|
|
|
+ else
|
|
|
|
|
+ toConsoleWarn "Failed to enable non-privileged mode. Exit Code : ${setCapCwServerAgentExitCode} . For details, see: ${LOG_FILE}"
|
|
|
|
|
+ toLogWarn "Set file capabilities output: ${output}"
|
|
|
|
|
+ fi
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【5】=配置安装
|
|
|
|
|
+configureInstallation() {
|
|
|
|
|
+ #== 配置参数(param、installation.conf)
|
|
|
|
|
+ #== 自定义修改配置, sed ,echo ... 参考 applyAgentSettings
|
|
|
|
|
+ if [ "${PARAM_TEST}" ]; then
|
|
|
|
|
+ toConsoleOnly "Applying test value is: ${PARAM_TEST}"
|
|
|
|
|
+ fi
|
|
|
|
|
+ #== 获取bool值参数
|
|
|
|
|
+ if [ "${PARAM_BOOL}" ]; then
|
|
|
|
|
+ toConsoleOnly "Applying bool value is: ${PARAM_BOOL}"
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ if [ "${ARCH_ARCH}"x != "AIX"x ]; then
|
|
|
|
|
+ #== 配置用户和用户组
|
|
|
|
|
+ if handleUser; then
|
|
|
|
|
+ #== 修改文件系统用户和用户组
|
|
|
|
|
+ changeFilesOwnership
|
|
|
|
|
+ fi
|
|
|
|
|
+ #== 设置root权限
|
|
|
|
|
+ enableRootDropping
|
|
|
|
|
+ fi
|
|
|
|
|
+ #== 系统配置(策略配置、dump proc、agent 进程配置、自动启动)
|
|
|
|
|
+# setupAutostart
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#== 【6】=验证安装状态、运行启动脚本
|
|
|
|
|
+postInstallationSteps() {
|
|
|
|
|
+ #== 运行agent
|
|
|
|
|
+# runAgents
|
|
|
|
|
+ finishInstallation "${EXIT_CODE_OK}"
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+readonly CURR_PATH="$(pwd)"
|
|
|
|
|
+main() {
|
|
|
|
|
+ #== 【0】=初始化安装环境
|
|
|
|
|
+ initializeInstallation "$@"
|
|
|
|
|
+ #== 【3】=安装前检查
|
|
|
|
|
+ preInstallationChecks
|
|
|
|
|
+ #== 【4】=部署文件
|
|
|
|
|
+ deployFiles
|
|
|
|
|
+ #== 【5】=配置安装
|
|
|
|
|
+ configureInstallation
|
|
|
|
|
+ #== 【6】=验证安装状态、运行启动脚本
|
|
|
|
|
+ postInstallationSteps
|
|
|
|
|
+
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#**********************************************************
|
|
|
|
|
+# Script start
|
|
|
|
|
+#**********************************************************
|
|
|
|
|
+main "$@"
|
|
|
|
|
+
|
|
|
|
|
+################################################
|
|
|
|
|
+############# DO NOT REMOVE THIS ###############
|
|
|
|
|
+#### DO NOT ADD ANYTHING BELOW THIS COMMENT ####
|
|
|
|
|
+################################################
|
|
|
|
|
+#################ENDOFSCRIPTMARK################
|
|
|
|
|
+
|
|
|
|
|
+----SIGNED-INSTALLER
|