install_temp.sh 91 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926
  1. #!/bin/bash
  2. #== AIX(Advanced Interactive eXecutive)是IBM基于AT&T Unix System V开发的一套类UNIX操作系统,运行在IBM专有的Power系列芯片设计的小型机硬件系统之上
  3. #== 以【#== 】开头的注释会在打包时删除
  4. #DEBUG== 以【#DEBUG== 】开头的注释会在调试打包时保留,正式打包时删除
  5. #==脚本执行中遇到不存在的变量就报错
  6. set -o nounset
  7. #==脚本执行中报错即刻退出
  8. set -o errexit
  9. #==脚本执行只要一个子命令失败,整个管道命令就失败
  10. set -o pipefail
  11. readonly BRAND_FORMAL_NAME="Cloudwise"
  12. readonly BRAND_PRODUCT_NAME="euspace"
  13. readonly BRAND_PARENT_PRODUCT_NAME="omniagent"
  14. readonly BRAND_AGENT_PRODUCT_NAME="${BRAND_FORMAL_NAME} ${BRAND_PRODUCT_NAME}"
  15. readonly BRAND_FORMAL_NAME_LOWER="cloudwise"
  16. readonly BRAND_PRODUCT_NAME_LOWER="euspace"
  17. readonly BRAND_AGENT_DEFAULT_USER_AND_GROUP_NAME_CLOUDWISE="cloudwise"
  18. readonly AIX_DF_SPECIFIC_FLAG=
  19. readonly CONF_LD_PRELOAD=
  20. PARAM_DISABLE_SYSTEM_LOGS_ACCESS=
  21. #== 安装包版本项
  22. readonly AGENT_BUILD_DATE=25.09.2020
  23. readonly AGENT_INSTALLER_VERSION=1.2.0
  24. readonly AGENT_BUILD_DATE_INFO=""
  25. readonly AGENT_BUILD_TAG=""
  26. readonly AGENT_BUILD_UPLOADER=""
  27. #== 安装包版本项
  28. #== **********************************************************
  29. #== 配置重要文件名称
  30. #== **********************************************************
  31. #== CW-ServerAgent
  32. readonly AGENT_PROC="euspace"
  33. #== **********************************************************
  34. #== 配置目录
  35. #== **********************************************************
  36. readonly INSTALL_BASE=/opt
  37. #== /opt/cloudwise/oneagent/agents 目录
  38. readonly BASE_INSTALL_DIR=${INSTALL_BASE}/${BRAND_FORMAL_NAME_LOWER}/${BRAND_PARENT_PRODUCT_NAME}/agents
  39. #== cloudwise/oneagent/agents/chaosd
  40. readonly INSTALL_FOLDER=${BRAND_FORMAL_NAME_LOWER}/${BRAND_PARENT_PRODUCT_NAME}/agents/${BRAND_PRODUCT_NAME_LOWER}
  41. #== cloudwise/oneagent/agents/chaosd/version
  42. readonly INSTALL_VERSION_FOLDER=${INSTALL_FOLDER}/${AGENT_INSTALLER_VERSION}
  43. #== /opt/cloudwise/oneagent/agents/chaosd/version
  44. readonly INSTALL_DIR=${INSTALL_BASE}/${INSTALL_VERSION_FOLDER}
  45. #== /opt/cloudwise/oneagent/agents/chaosd
  46. readonly AGENT_BASE_DIR=${INSTALL_BASE}/${INSTALL_FOLDER}
  47. #== /opt/cloudwise/cwserveragent/conf
  48. readonly AGENT_CONF_DIR="${INSTALL_DIR}/conf"
  49. #== agent 初始化脚本目录 /opt/cloudwise/cwserveragent/scripts
  50. readonly AGENT_SCRIPTS_DIR="${INSTALL_DIR}/scripts"
  51. #== agent 初始化脚本目录 /opt/cloudwise/cwserveragent/runtime
  52. readonly AGENT_RUNTIME_DIR="${INSTALL_DIR}/runtime"
  53. #== agent 初始化脚本目录 /opt/cloudwise/cwserveragent/bin
  54. readonly AGENT_BIN_DIR="${INSTALL_DIR}/bin"
  55. #== agent 初始化脚本目录 /opt/cloudwise/cwserveragent/lib
  56. #== readonly AGENT_LIB_DIR="${INSTALL_DIR}/lib"
  57. readonly AGENTS_BASE_DIR="${INSTALL_DIR}/agents"
  58. readonly META_BASE_DIR="${INSTALL_DIR}/meta"
  59. readonly LOG_DIR_NAME="logs"
  60. #== /opt/cloudwise/cwserveragent/logs
  61. readonly LOG_DIR=${INSTALL_DIR}/${LOG_DIR_NAME}
  62. #== /var/log/cloudwise/cwserveragent/
  63. readonly INSTALLER_LOG_DIR="/var/log/${INSTALL_FOLDER}"
  64. #== server-agent.ini
  65. #== hostId文件
  66. readonly INSTALLER_CONF_FILE_NAME="installation.conf"
  67. #== 部署在容器内的状态信息
  68. readonly INSTALLER_CONF_FILE="${AGENT_CONF_DIR}/${INSTALLER_CONF_FILE_NAME}"
  69. #== 【0】=
  70. readonly INSTALLER_LOCK_FILE="/tmp/${BRAND_FORMAL_NAME_LOWER}_${BRAND_PRODUCT_NAME_LOWER}.lock"
  71. readonly INIT_SYSTEM_SYSV="SysV"
  72. #== 系统 systemd
  73. readonly INIT_SYSTEM_SYSTEMD="systemd"
  74. #== cw-serveragent
  75. readonly SERVICE_SCRIPT_FILE="cw-oneagent"
  76. #== cw-serveragent.service
  77. readonly SYSTEMD_UNIT_FILE_AGENT="${SERVICE_SCRIPT_FILE}.service"
  78. #== 系统文件目录
  79. readonly SYSTEMD_UNIT_FILES_DIR="/etc/systemd/system/"
  80. #== 【0】=【退出码】执行成功
  81. readonly EXIT_CODE_OK=0
  82. readonly EXIT_CODE_GENERIC_ERROR=1
  83. readonly EXIT_CODE_NOT_ENOUGH_SPACE=6
  84. readonly EXIT_CODE_NOT_ENOUGH_MEMORY=7
  85. #== 【0】=无效参数
  86. readonly EXIT_CODE_INVALID_PARAM=8
  87. readonly EXIT_CODE_INSUFFICIENT_PERMISSIONS=9
  88. #== 【退出码】接收信号
  89. readonly EXIT_CODE_SIGNAL_RECEIVED=12
  90. readonly EXIT_CODE_ANOTHER_INSTALLER_RUNNING=13
  91. readonly EXIT_CODE_CORRUPTED_PACKAGE=16
  92. #== 【退出码】管理系统环境变量配置
  93. readonly EXIT_CODE_MISCONFIGURED_ENVIRONMENT=17
  94. readonly EXIT_CODE_UNSUPPORTED_DOWNGRADE=18
  95. readonly EXIT_CODE_OS_NOT_SUPPORTED=19
  96. readonly EXTERNAL_TAR_SIZE=233820160
  97. readonly ARTIFACTS_SIZE=953271934
  98. #**********************************************************
  99. # Logs
  100. #**********************************************************
  101. toLogFile() {
  102. if [ -e "${LOG_FILE}" ]; then
  103. printf '%s UTC %s\n' "$(date -u +"%Y-%m-%d %H:%M:%S")" "$*" >>"${LOG_FILE}" 2>/dev/null
  104. fi
  105. }
  106. toConsoleOnly() {
  107. printf '%s %s\n' "$(date +"%H:%M:%S")" "$*" 2>/dev/null
  108. }
  109. toLogInfo() {
  110. toLogFile "[INFO]" "$@"
  111. }
  112. toLogWarn() {
  113. toLogFile "[WARN]" "$@"
  114. }
  115. toLogError() {
  116. toLogFile "[ERROR]" "$@"
  117. }
  118. toLogAdaptive() {
  119. local success="${1}"
  120. shift
  121. if [ "${success}" -eq 0 ]; then
  122. toLogInfo "$@"
  123. else
  124. toLogError "$@"
  125. fi
  126. }
  127. toConsoleInfo() {
  128. toConsoleOnly "$@"
  129. toLogInfo "$@"
  130. }
  131. toConsoleWarn() {
  132. toConsoleOnly "Warn:" "$@"
  133. toLogWarn "$@"
  134. } >&2
  135. toConsoleError() {
  136. toConsoleOnly "Error:" "$@"
  137. toLogError "$@"
  138. } >&2
  139. #== 【0】【3】【4】=创建不存在的目录,并设置权限
  140. createDirIfNotExistAndSetRights() {
  141. local dir="${1}"
  142. local rights="${2}"
  143. toConsoleInfo "#DEBUG== createDirIfNotExistAndSetRights --- ${rights} --- ${dir}"
  144. if [ ! -d "${dir}" ]; then
  145. toLogInfo "Creating directory ${dir} with rights ${rights}"
  146. local message
  147. if ! message="$(mkdir -p "${dir}" 2>&1)"; then
  148. toConsoleWarn "Cannot create ${dir} directory."
  149. toLogWarn "Error message: ${message}"
  150. return 1
  151. fi
  152. fi
  153. if ! message="$(chmod "${rights}" "${dir}" 2>&1)"; then
  154. toConsoleWarn "Cannot change permisions of ${dir} directory to ${rights}."
  155. toLogWarn "Error message: ${message}"
  156. return 1
  157. fi
  158. return 0
  159. }
  160. createCurrentVersionSymlink() {
  161. toLogInfo "Creating symlink to current version..."
  162. local currentVersionLink="${AGENT_BASE_DIR}/current"
  163. local tempLink="${currentVersionLink}.tmp"
  164. if ! commandErrorWrapper ln -s "${AGENT_INSTALLER_VERSION}" "${tempLink}"; then
  165. toLogError "Failed to create current version link"
  166. return
  167. fi
  168. if ! commandErrorWrapper arch_moveReplaceTarget "${tempLink}" "${currentVersionLink}"; then
  169. toLogError "Failed to set up current version link"
  170. commandErrorWrapper rm -f "${tempLink}"
  171. return
  172. fi
  173. toLogInfo "Current version link created: ${currentVersionLink} -> ${AGENT_INSTALLER_VERSION}"
  174. }
  175. #== 【0】=创建日志目录及日志文件installation_$$.log
  176. createLogDirsIfMissing() {
  177. createDirIfNotExistAndSetRights "${INSTALL_BASE}" u+rwx,g+rx,o+rx
  178. createDirIfNotExistAndSetRights "${BASE_INSTALL_DIR}" u+rwx,g+rx,o+rx
  179. #== agents根目录
  180. createDirIfNotExistAndSetRights "${AGENT_BASE_DIR}" 1775
  181. createDirIfNotExistAndSetRights "${INSTALL_DIR}" 1775
  182. # createDirIfNotExistAndSetRights "${LOG_DIR}" 1777
  183. createDirIfNotExistAndSetRights "${INSTALLER_LOG_DIR}" 1777
  184. # for agentLog in ${PLUGIN_LOG_NAMES}; do
  185. # createDirIfNotExistAndSetRights "${LOG_DIR}/${agentLog}" 1777
  186. # done
  187. touch "${LOG_FILE}"
  188. setRightsForFiles "${LOG_FILE}" 766
  189. }
  190. #**********************************************************
  191. # Platform characteristics detection
  192. #**********************************************************
  193. #== 【5】=获取系统发型版本
  194. getOsReleasePath() {
  195. local osReleasePath="/etc/os-release"
  196. if [ ! -f "${osReleasePath}" ]; then
  197. osReleasePath="/usr/lib/os-release"
  198. fi
  199. printf '%s' "${osReleasePath}"
  200. }
  201. parseOsReleaseFile() {
  202. local osReleasePath="$(getOsReleasePath)"
  203. #shellcheck disable=SC1090
  204. . "${osReleasePath}"
  205. local distrib="${NAME-}"
  206. if [ -z "${distrib}" ]; then
  207. distrib="${ID-}"
  208. fi
  209. local version="${VERSION_ID-}"
  210. if printf '%s' "${distrib}" | grep -iq "debian"; then
  211. version="$(cat /etc/debian_version)"
  212. elif printf '%s' "${distrib}" | grep -iq "fedora" && [ "${VARIANT_ID-}" = "coreos" ]; then
  213. distrib="${distrib} CoreOS"
  214. fi
  215. printf '%s %s' "${distrib}" "${version}"
  216. }
  217. #== 【5】=获取系统发型版本
  218. detectLinuxDistribution() {
  219. if [ -f /etc/oracle-release ]; then
  220. cat /etc/oracle-release
  221. elif [ -f /etc/fedora-release ]; then
  222. if [ -f "$(getOsReleasePath)" ]; then
  223. (
  224. parseOsReleaseFile
  225. )
  226. else
  227. cat /etc/fedora-release
  228. fi
  229. elif [ -f /etc/redhat-release ]; then
  230. cat /etc/redhat-release
  231. elif [ -f "$(getOsReleasePath)" ]; then
  232. (
  233. parseOsReleaseFile
  234. )
  235. elif [ -f /etc/SuSE-release ]; then
  236. head -1 /etc/SuSE-release
  237. elif [ -f /etc/lsb-release ]; then
  238. (
  239. . /etc/lsb-release
  240. printf "%s %s" "${DISTRIB_ID-}" "${DISTRIB_RELEASE-}"
  241. )
  242. elif ls /etc/*release* >/dev/null 2>&1; then
  243. # Generic fallback
  244. cat /etc/*release*
  245. else
  246. printf "AIX %s" "$(oslevel -s 2>&1)"
  247. fi
  248. }
  249. #== 【3】=检查系统init (INIT_SYSTEM、INIT_SYSTEM_VERSION)
  250. checkInitSystem() {
  251. local version
  252. if version="$(systemctl --version 2>&1)"; then
  253. if [ -d "${SYSTEMD_UNIT_FILES_DIR}" ]; then
  254. readonly INIT_SYSTEM=${INIT_SYSTEM_SYSTEMD}
  255. else
  256. readonly INIT_SYSTEM=${INIT_SYSTEM_SYSV}
  257. toLogWarn "${INIT_SYSTEM_SYSTEMD} was detected but ${SYSTEMD_UNIT_FILES_DIR} does not exist, using ${INIT_SYSTEM_SYSV} handling as a fallback"
  258. fi
  259. else
  260. readonly INIT_SYSTEM=${INIT_SYSTEM_SYSV}
  261. if ! version="$(init --version 2>&1)"; then
  262. if ! version="$(chkconfig --version 2>&1)"; then
  263. version="$(head -n1 /etc/inittab 2>&1)"
  264. fi
  265. fi
  266. fi
  267. readonly INIT_SYSTEM_VERSION="$(printf '%s' "${version}" 2>/dev/null | head -n1)"
  268. }
  269. #== 【3】=设置系统初始化脚本目录
  270. setLocationOfScripts() {
  271. toLogInfo "Determining location of scripts..."
  272. if [ "${INIT_SYSTEM}"x = "${INIT_SYSTEM_SYSTEMD}"x ] || [ "${ARCH_ARCH}"x = "AIX"x ]; then
  273. #== /opt/cloudwise/cwserveragent/scripts
  274. readonly INIT_DIR="${AGENT_SCRIPTS_DIR}"
  275. else
  276. if [ -d "/etc/init.d" ]; then
  277. readonly INIT_DIR="/etc/init.d"
  278. elif [ -d "/sbin/init.d" ]; then
  279. readonly INIT_DIR="/sbin/init.d"
  280. elif [ -d "/etc/rc.d" ]; then
  281. readonly INIT_DIR="/etc/rc.d"
  282. else
  283. return 1
  284. fi
  285. fi
  286. toLogInfo "Location of scripts ${INIT_DIR}"
  287. return 0
  288. }
  289. #== 【0】=检查系统结构(X86_64\IA64\X86)
  290. detectArchitecture() {
  291. local detected_arch=
  292. if isAvailable arch; then
  293. #== arch指令主要用于显示当前主机的硬件结构类型,查询结果与uname一致,我们可以看到它输出的结果有:i386、i486、mips、alpha等
  294. detected_arch="$(arch | tr '[:lower:]' '[:upper:]')"
  295. fi
  296. if [ -z "${detected_arch}" ]; then
  297. detected_arch="$(uname -m | tr '[:lower:]' '[:upper:]')"
  298. fi
  299. printf '%s' "${detected_arch}"
  300. }
  301. #**********************************************************
  302. # Misc functions
  303. #**********************************************************
  304. #== 【1】【4】【5】【6】=获取 agent (64\32)位数lib目录(""或lib64)
  305. getBinariesFolderByBitness() {
  306. local bitness="${1}"
  307. if [ "${bitness}" -eq 32 ]; then
  308. bitness=""
  309. fi
  310. printf 'lib%s' "${bitness}"
  311. }
  312. #== 【1】【2】【5】【6】=获取 agent tools/lib64/smartagentctl 路径
  313. #== getAgentCtlBinPath
  314. #== 【1】【4】【5】【6】=获取 agent 64位数lib路径(lib64/installaction)
  315. #== getAgentInstallActionPath
  316. #== 【5】【6】=获取OS bin配置路径 /opt/cloudwise/cwserveragent/lib64/cloudwiseosconfig
  317. getOsConfigBinPath() {
  318. printf "%s" "${INSTALL_DIR}/lib64/${AGENT_OS_CONFIG_BIN}"
  319. }
  320. #== 【5】=设置agent进程可用
  321. setProcessAgentEnabled() {
  322. local enabled="${1}"
  323. toLogInfo "Setting process agent enabled: ${enabled}..."
  324. local changeStatus=
  325. #== 调用 agent 64位数lib路径(lib64/installaction)执行指令 --set-process-agent-enabled
  326. changeStatus=$("$(getAgentInstallActionPath)" --set-process-agent-enabled "${enabled}" 2>&1)
  327. toLogAdaptive $? "Process agent enable(${enabled}) status: ${changeStatus}"
  328. }
  329. #== 【1】【4】【5】【6】=获取命令执行错误信息,并写日志
  330. commandErrorWrapper() {
  331. local command="${*}"
  332. local errorFile="/tmp/smartagent_commanderror_$$"
  333. ${command} 2>"${errorFile}"
  334. local returnCode=$?
  335. if [ ${returnCode} -ne 0 ]; then
  336. toLogWarn "Command '${command}' failed, return code: ${returnCode}, message: $(cat "${errorFile}")"
  337. fi
  338. rm -f "${errorFile}"
  339. return ${returnCode}
  340. }
  341. #== 【3】=是否独立的namespace
  342. isNamespaceIsolated() {
  343. local pid="${1}"
  344. local namespace="${2}"
  345. local initNamespaceId
  346. local processNamespaceId
  347. initNamespaceId="$(readlink "/proc/1/ns/${namespace}" 2>/dev/null | tr -dc '0-9')"
  348. processNamespaceId="$(readlink "/proc/${pid}/ns/${namespace}" 2>/dev/null | tr -dc '0-9')"
  349. if [ ! "${initNamespaceId}" ] || [ ! "${processNamespaceId}" ]; then
  350. toLogInfo "Link to /proc/*/ns/${namespace} does not exist"
  351. printf 'error'
  352. return
  353. fi
  354. if [ "${initNamespaceId}"x != "${processNamespaceId}"x ]; then
  355. printf 'true'
  356. else
  357. printf 'false'
  358. fi
  359. }
  360. #== 【0】=检查是否root
  361. checkRootAccess() {
  362. toConsoleInfo "Checking root privileges..."
  363. if [ "$(id -u)"x != "0"x ]; then
  364. toConsoleError "NOT OK"
  365. return 1
  366. fi
  367. toConsoleInfo "OK"
  368. return 0
  369. }
  370. #== 【3】=删除存在的路径
  371. removeIfExists() {
  372. local pathToRemove="${1}"
  373. if [ ! -e "${pathToRemove}" ]; then
  374. toLogInfo "${pathToRemove} does not exist, skipping removal"
  375. return
  376. fi
  377. local output
  378. if ! output="$(rm -rf "${pathToRemove}" 2>&1)"; then
  379. toLogWarn "Failed to remove ${pathToRemove}: ${output}"
  380. fi
  381. }
  382. #**********************************************************
  383. # SELinux related functions
  384. #**********************************************************
  385. #== 【5】【6】=执行 systemctl 命令
  386. executeSystemctlCommand() {
  387. local command="${1}"
  388. local unit="${2}"
  389. if [ "$(id -u)" != 0 ]; then
  390. #== 执行使用 os config bin
  391. executeUsingOsConfigBin "${command}" "${unit}"
  392. return $?
  393. fi
  394. local output=
  395. #== shellcheck disable=SC2086
  396. #== 执行 systemctl 命令
  397. output="$(systemctl "${command}" ${unit} 2>&1)"
  398. local exitCode=$?
  399. if [ ${exitCode} -eq 0 ]; then
  400. toLogInfo "Successfully executed: systemctl ${command} ${unit}"
  401. else
  402. toLogError "Failed to execute: systemctl ${command} ${unit}"
  403. toLogError "Command output: ${output}"
  404. if [ -n "${unit}" ]; then
  405. local reachBackNumSeconds=360
  406. toLogError "journalctl output: $(journalctl -u "${unit}" --since=-${reachBackNumSeconds} 2>&1)"
  407. fi
  408. fi
  409. return ${exitCode}
  410. } 2>>"${LOG_FILE}"
  411. #== 【6】=运行初始化命令(通过 service 方式 或 直接运行可执行命令)
  412. executeInitScriptCommand() {
  413. local command=
  414. local parameters="$*"
  415. local output=
  416. local exitCode=
  417. if isAvailable service; then
  418. command="service"
  419. parameters="${SERVICE_SCRIPT_FILE} ${parameters}"
  420. else
  421. command="${INIT_DIR}/${SERVICE_SCRIPT_FILE}"
  422. fi
  423. output="$("${command}" "${parameters}" 2>&1)"
  424. exitCode=$?
  425. toLogAdaptive ${exitCode} "Executed ${command} ${parameters}, exitCode = ${exitCode}, output: ${output}"
  426. return ${exitCode}
  427. }
  428. #== 【0】=信号捕获,并执行回调函数
  429. signalHandler() {
  430. local signal="${1}"
  431. local callback="${2}"
  432. toLogWarn "process received signal: ${signal}"
  433. ${callback}
  434. exit ${EXIT_CODE_SIGNAL_RECEIVED}
  435. }
  436. #== 【0】=配置信号捕获和回调
  437. configureSignalHandling() {
  438. local callback="${1}"
  439. for signal in HUP INT QUIT ABRT ALRM TERM; do
  440. # shellcheck disable=SC2064
  441. trap "signalHandler '${signal}' '${callback}'" ${signal}
  442. done
  443. trap "" PIPE
  444. }
  445. #== 【0】删除权限
  446. removeSecretsFromString() {
  447. printf "%s" "$*" | sed 's#\(LICENSE=\)[[:alnum:]]\{16\}#\1***#'
  448. }
  449. #== 【3】【5】=检查目录写权限
  450. testWriteAccessToDir() {
  451. local errorFile="/tmp/smartagent_commandError_$$"
  452. local dir="${1}"
  453. local tmpfilename
  454. if [ "${ARCH_ARCH}"x = "AIX"x ]; then
  455. tmpfilename="${dir}/.tmp_${BRAND_PRODUCT_NAME_LOWER}.$$${RANDOM}"
  456. touch "${tmpfilename}" 2>"${errorFile}"
  457. else
  458. tmpfilename="$(mktemp -p "${dir}" ".tmp_${BRAND_PRODUCT_NAME_LOWER}.XXXXXXXXXXXXXX" 2>"${errorFile}")"
  459. fi
  460. #== shellcheck disable=SC2181
  461. if [ $? -ne 0 ]; then
  462. toLogInfo "$(cat "${errorFile}")"
  463. rm -f "${errorFile}"
  464. return 1
  465. fi
  466. rm -f "${tmpfilename}" "${errorFile}"
  467. return 0
  468. }
  469. #== 【0】=设置PATH
  470. setPATH() {
  471. local prependToPATH="/usr/sbin:/usr/bin:/sbin:/bin"
  472. if [ "${PATH}" ]; then
  473. PATH=${prependToPATH}:${PATH}
  474. else
  475. PATH=${prependToPATH}
  476. fi
  477. }
  478. #== 【5】【6】=是否非root权限
  479. isNonRootModeEnabled() {
  480. #== 调用 agent 64位数lib路径(lib64/installaction)执行指令 --get-drop-root-privileges
  481. local output
  482. output="$(getValueFromConfigFile "${CONF_FIELD_NM_NON_ROOT_MODE}" "${LEGACY_AGENT_CONF_FILE}" "${PARAM_NON_ROOT_MODE}")"
  483. printf '%s' "${output}" | grep -qE "(true|no_ambient)"
  484. }
  485. #== 【5】=自动启动工具
  486. runAutostartAddingTool() {
  487. local prefix="${1}"
  488. local file="${2}"
  489. local suffix="${3}"
  490. local output
  491. local command="${prefix} ${file} ${suffix}"
  492. toLogInfo "Executing ${command}"
  493. output="$(${command} 2>&1)"
  494. local status=$?
  495. if [ "${output}" ]; then
  496. toLogAdaptive ${status} "${output}"
  497. fi
  498. return ${status}
  499. }
  500. #== 【0】【5】=查找软链接真实地址(通过ls命令)
  501. readLinkFromLs() {
  502. local path="${1}"
  503. local result="${path}"
  504. local lsOutput
  505. local parsedLinkTarget
  506. lsOutput="$(ls -dl "${path}" 2>/dev/null)"
  507. if printf '%s' "${lsOutput}" | grep -q " -> "; then
  508. parsedLinkTarget="$(printf '%s' "${lsOutput}" | sed 's|^.* -> ||')"
  509. if [ "${parsedLinkTarget}" ]; then
  510. result="${parsedLinkTarget}"
  511. else
  512. toLogWarn "Failed to parse ls output '${lsOutput}'"
  513. fi
  514. fi
  515. printf '%s' "${result}"
  516. }
  517. #== 【0】【5】=查找软链接真实地址(通过readlink 或 ls 命令)
  518. readLink() {
  519. local args=-e
  520. local path="${1}"
  521. if [ "${2}" ]; then
  522. args="${1}"
  523. path="${2}"
  524. fi
  525. (
  526. if [ "${ARCH_ARCH}"x = "AIX"x ]; then
  527. path="${PATH}:/opt/freeware/bin"
  528. fi
  529. #== 通过 readlink 命令查找地址
  530. if isAvailable readlink; then
  531. #shellcheck disable=SC2086
  532. readlink ${args} "${path}"
  533. else
  534. toLogInfo "readlink command not found, falling back to parsing ls output"
  535. readLinkFromLs "${path}"
  536. fi
  537. )
  538. }
  539. #== 【0】【3】【4】【5】【6】=检查命令是否有效/是否存在
  540. isAvailable() {
  541. command -v "${1}" >/dev/null 2>&1
  542. }
  543. #== 【0】【1】【3】【5】=读取配置文件配置参数信息
  544. getValueFromConfigFile() {
  545. local key="${1}"
  546. local configFile="${2}"
  547. local defaultValue="${3}"
  548. local value
  549. value="$(sed -n "s|^${key}=||p" "${configFile}" 2>/dev/null)"
  550. if [ "${value}" ]; then
  551. printf '%s' "${value}"
  552. else
  553. printf '%s' "${defaultValue}"
  554. fi
  555. }
  556. #== 【1】【5】=删除配置文件中配置
  557. removeValueFromConfigFile() {
  558. local key="${1}"
  559. local configFile="${2}"
  560. local output
  561. if ! output="$(cp -p "${configFile}" "${configFile}.tmp" 2>&1)"; then
  562. toLogWarn "Unable to initialize ${configFile}.tmp file using source file, privileges and ownership will not be preserved: ${output}"
  563. fi
  564. if sed "/^${key}/d" "${configFile}" >"${configFile}.tmp"; then
  565. mv -f "${configFile}.tmp" "${configFile}"
  566. else
  567. toLogWarn "Failed to remove ${key} from ${configFile}"
  568. rm -f "${configFile}.tmp"
  569. fi
  570. }
  571. #== 写配置到配置文件信息
  572. writeParamToConfigFile() {
  573. local key="${1}"
  574. local newValue="${2}"
  575. local configFile="${3}"
  576. local value
  577. value="$(sed -n "s|^${key}=||p" "${configFile}" 2>/dev/null)"
  578. toConsoleInfo "#DEBUG== writeParamToConfigFile --> edit ${key}=${value} to ${key}=${newValue}, configFile: ${configFile}"
  579. if [ "${value}" ]; then
  580. sed -i "s|^${key}=.*|${key}=${newValue}|" "${configFile}" 2>/dev/null
  581. else
  582. echo "${key}=${newValue}" >>"${configFile}" 2>/dev/null
  583. fi
  584. }
  585. writeContentToConfigFile() {
  586. local newValue="${1}"
  587. local configFile="${2}"
  588. toConsoleInfo "#DEBUG== writeContentToConfigFile --> edit ${newValue}, configFile: ${configFile}"
  589. echo "${newValue}" > "${configFile}" 2>/dev/null
  590. }
  591. #== 修改scripts/smartagent脚本配置信息
  592. editScriptFileParam() {
  593. local key="${1}"
  594. local newValue="${2}"
  595. local file="${3}"
  596. local value
  597. value="$(sed -n "s|^${key}=||p" "${file}" 2>/dev/null)"
  598. toConsoleInfo "#DEBUG== editScriptFileParam --> edit ${key}=${value} to ${key}=${newValue}, configFile: ${file}"
  599. if [ "${value}" ]; then
  600. sed -i "s|^${key}=.*|${key}=${newValue}|" "${file}" 2>/dev/null
  601. fi
  602. }
  603. #== 【0】=是否存在多个同时安装操作【通过判断 INSTALLER_LOCK_FILE 】
  604. isAnotherInstallationRunning() {
  605. if [ ! -f "${INSTALLER_LOCK_FILE}" ]; then
  606. return 1
  607. fi
  608. local pidFromLockFile
  609. local nameFromLockFile
  610. pidFromLockFile="$(head -n 1 "${INSTALLER_LOCK_FILE}")"
  611. nameFromLockFile="$(tail -n 1 "${INSTALLER_LOCK_FILE}")"
  612. if [ "$(wc -l <"${INSTALLER_LOCK_FILE}")" -ne 2 ] || [ -z "${pidFromLockFile}" ] || [ -z "${nameFromLockFile}" ]; then
  613. toConsoleWarn "Installation lock file ${INSTALLER_LOCK_FILE} is damaged, skipping uniqueness check."
  614. toConsoleWarn "Lock file contents: '$(cat ${INSTALLER_LOCK_FILE})'"
  615. return 1
  616. fi
  617. #== shellcheck disable=SC2009
  618. #== 获取正在执行安装的进程信息
  619. local foundProcesses
  620. foundProcesses="$(pgrep -f "pid,args" 2>&1 | grep -w "${nameFromLockFile}" | grep -v " grep ")"
  621. if printf '%s' "${foundProcesses}" | awk '{ print $1 }' | grep -wq "${pidFromLockFile}"; then
  622. local errorMessage="Another ${BRAND_PRODUCT_NAME} installer or uninstaller is already running"
  623. if printf '%s' "${foundProcesses}" | grep -q "${DOWNLOADS_DIR}"; then
  624. errorMessage="${errorMessage} (AutoUpdate is in progress)"
  625. fi
  626. toConsoleError "${errorMessage}, PID ${pidFromLockFile}. Exiting."
  627. return 0
  628. fi
  629. toConsoleInfo "Lock file exists but corresponding installation process does not run, contents of lock file: ${pidFromLockFile}, ${nameFromLockFile}."
  630. return 1
  631. }
  632. #== 【0】=创建安装标示文件 /tmp/${BRAND_PRODUCT_NAME_LOWER}.lock
  633. createInstallationLockFile() {
  634. printf '%s\n%s\n' "$$" "$0" >"${INSTALLER_LOCK_FILE}" 2>/dev/null
  635. }
  636. #== 【0】【6】删除安装标示文件 /tmp/${BRAND_PRODUCT_NAME_LOWER}.lock
  637. removeInstallationLockFile() {
  638. toLogInfo "Removing installation lock file."
  639. rm -f "${INSTALLER_LOCK_FILE}"
  640. }
  641. #== 【0】基础启动日志信息
  642. logBasicStartupInformation() {
  643. toLogInfo "Command line: $(removeSecretsFromString "${@}")"
  644. toLogInfo "Shell options: $-"
  645. toLogInfo "Working dir: $(pwd)"
  646. toLogInfo "PID: $$"
  647. toLogInfo "Parent process: $(
  648. printf '\n'
  649. ps -o user,pid,ppid,comm -p ${PPID} 2>&1
  650. )"
  651. toLogInfo "User id: $(id -u)"
  652. }
  653. #== 解压文件编码
  654. readonly UNPACK_BINARY=base64
  655. #== 解压文件编码参数
  656. readonly UNPACK_BINARY_ARGS="-di"
  657. readonly ARCH_ARCH="X86"
  658. #== 【0】=检查系统指令集(X86_64\IA64\X86)
  659. arch_checkArchitectureCompatibility() {
  660. #== 【0】=检查系统结构(X86_64)
  661. local arch
  662. arch="$(detectArchitecture)"
  663. if [ "${arch}"x = "X86_64"x ] || [ "${arch}"x = "IA64"x ]; then
  664. arch="X86_64"
  665. else
  666. arch="$(uname -m | sed -e 's/i.86/x86/' | sed -e 's/i86pc/x86/' | tr '[:lower:]' '[:upper:]')"
  667. fi
  668. printf '%s' "${arch}"
  669. [ "${arch}"x = "X86_64"x ] || [ "${arch}"x = "AARCH64"x ]
  670. }
  671. #== 【5】=获取 lib 目录
  672. arch_getLibMacro() {
  673. local libMacro=""
  674. if [ "${SYSTEM_LIB32}" ]; then
  675. #== shellcheck disable=SC2016
  676. libMacro="/${LIB}"
  677. fi
  678. printf "%s" "${libMacro}"
  679. }
  680. #== 'timeout' requires gnu-coreutils8, i.e. it is not available on RHEL5, that's why we need this utility function
  681. #== 【3】【5】=执行命令超时配置
  682. #== 【0】【3】=获取文件权限信息
  683. arch_getAccessRights() {
  684. stat --format='%A' "${1}"
  685. }
  686. #== 【4】=替换目录
  687. arch_moveReplaceTarget() {
  688. local source="${1}"
  689. local target="${2}"
  690. mv -fT "${source}" "${target}"
  691. }
  692. #== xz 压缩包文件名 Cloudwise-SmartAgent
  693. readonly INTERNAL_TAR_FILE_NAME=${BRAND_FORMAL_NAME}-${BRAND_PRODUCT_NAME}.tar.xz
  694. #== -安装日志: installation-{timestamp}.log,如,installation-20220601110912.log
  695. readonly LOG_FILE="${INSTALLER_LOG_DIR}/installation-$(date -u +"%Y%m%d%H%M%S").log"
  696. #readonly LOG_FILE="${INSTALLER_LOG_DIR}/installation_$$.log"
  697. #== 【临时目录】安装临时目录
  698. readonly TMP_DIR=${INSTALL_DIR}_install_$$
  699. #== 【临时目录】解压缓存目录
  700. readonly UNPACK_CACHE=${BASE_INSTALL_DIR}/unpack_cache
  701. #== 【临时目录】从sh文件读取压缩文件 tarfile_$$.base64
  702. readonly EXTERNAL_TAR_FILE=${BASE_INSTALL_DIR}/tarfile_$$.base64
  703. #== 【临时目录】xz 压缩包文件
  704. readonly INTERNAL_TAR_FILE=${INSTALL_DIR}/${INTERNAL_TAR_FILE_NAME}
  705. #== 【0】=
  706. readonly INSTALLER_FILE=${0}
  707. #== 旧配置文件
  708. readonly LEGACY_AGENT_CONF_FILE="${AGENT_CONF_DIR}/${BRAND_PRODUCT_NAME_LOWER}.conf"
  709. #== 【0】=
  710. readonly LINES_TO_SEARCH_FOR_SIGNATURE_AND_PARAMS=50
  711. #== 【0】=
  712. readonly HELP_URL=""
  713. readonly CONF_FIELD_NM_DATA_SERVER="DataServer"
  714. readonly CONF_FIELD_NM_CONFIG_SERVER="ConfigServer"
  715. readonly CONF_FIELD_NM_LICENSE="License"
  716. readonly CONF_FIELD_NM_JSON_CONF="JSON_CONF"
  717. readonly CONF_FIELD_NM_USER="User"
  718. readonly CONF_FIELD_NM_GROUP="Group"
  719. readonly CONF_FIELD_NM_DATA_STORAGE="DataStorage"
  720. readonly CONF_FIELD_NM_NON_ROOT_MODE="NonRootMode"
  721. #== 配置默认用户权限
  722. readonly BASE_OMNI_INSTALL_DIR=${INSTALL_BASE}/${BRAND_FORMAL_NAME_LOWER}/${BRAND_PARENT_PRODUCT_NAME}
  723. readonly BASE_OMNI_INSTALL_CONF_DIR=${BASE_OMNI_INSTALL_DIR}/conf/installation.conf
  724. 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}")"
  725. #== Those are read from params section appended to installer by the server
  726. #== 【0】=【参数】数据服务地址
  727. PARAM_DATA_SERVER=
  728. #== 【0】=【参数】配置服务地址
  729. PARAM_CONFIG_SERVER=
  730. #== 【0】=【参数】license
  731. PARAM_LICENSE=
  732. PARAM_JSON_CONF=
  733. #== 【0】=【参数】安装路径
  734. PARAM_INSTALL_DIR=${INSTALL_DIR}
  735. #== 【0】=【参数】用户
  736. PARAM_USER=
  737. #== 【0】=【参数】用户组
  738. PARAM_GROUP=
  739. #== 【0】=【参数】非root模式
  740. PARAM_NON_ROOT_MODE=true
  741. PARAM_USER_LOGIN=false
  742. #== 【0】=【参数】不允许root回退
  743. PARAM_DISABLE_ROOT_FALLBACK=false
  744. #== 【0】=【参数】数据存储目录
  745. PARAM_DATA_STORAGE=
  746. #== 【0】=【参数】通过容器部署
  747. #== PARAM_INTERNAL_DEPLOYED_VIA_CONTAINER=false
  748. #== 【0】=【参数】跳过SELinux策略安装
  749. #== PARAM_INTERNAL_SKIP_SELINUX_POLICY_INSTALLER=false
  750. #== 【0】=【参数】是否使用解压缓存
  751. PARAM_INTERNAL_USE_UNPACK_CACHE=false
  752. #== 【0】=【参数】是否不使用 dump
  753. #== PARAM_INTERNAL_DISABLE_DUMPPROC=
  754. #== 【0】=【参数】是否跳过非root检查
  755. PARAM_INTERNAL_NON_ROOT_MODE_SKIP_PRIVILEGES_CHECK=false
  756. #== 【0】【1】=【参数】额外的配置
  757. #== PARAM_INTERNAL_PASS_THROUGH_SETTERS=
  758. #== 【0】=检查是否降级安装
  759. SKIP_DOWNGRADE_CHECK=false
  760. SKIP_PRIVILEGES_CHECK=false
  761. #== 自定义字符串参数
  762. PARAM_TEST=
  763. #== 自定义字BOOL参数
  764. PARAM_BOOL=
  765. #== 【0】=常规日志
  766. initializeLog() {
  767. toConsoleInfo "Installation started, version ${AGENT_INSTALLER_VERSION}, build date: ${AGENT_BUILD_DATE}, PID $$."
  768. toLogInfo "Started from: ${INSTALLER_FILE}"
  769. if [ -f /proc/version ]; then
  770. toLogInfo "System version: $(cat /proc/version)"
  771. else
  772. toLogInfo "System version: $(uname -a)"
  773. fi
  774. toLogInfo "Path: ${PATH}"
  775. toLogInfo "INSTALL_DIR: ${INSTALL_DIR}"
  776. toLogInfo "Resolved installation path: $(readLink -e "${INSTALL_DIR}" 2>/dev/null)"
  777. logBasicStartupInformation "${@}"
  778. }
  779. #**********************************************************
  780. # Signing related stuff
  781. #**********************************************************
  782. #== 【0】【4】=通过占位分割读取位置
  783. locateDelimiter() {
  784. #== 占位符
  785. local delimiter="${1}"
  786. #== 从文件结尾读取行数
  787. local linesToReadFromEnd="${2}"
  788. local linesCount
  789. local offset
  790. if [ "${linesToReadFromEnd}" ]; then
  791. #== 文件总行数n(实际行数=n+1)
  792. linesCount="$(wc -l "${INSTALLER_FILE}" | awk '{print $1}')"
  793. #== 从后往前读取【linesToReadFromEnd】行
  794. offset="$(tail -n"${linesToReadFromEnd}" "${INSTALLER_FILE}" 2>/dev/null | awk '/^'"${delimiter}"'/ { print NR; exit }')"
  795. if [ -n "${offset}" ]; then
  796. printf "%d" "$((linesCount - linesToReadFromEnd + offset))"
  797. fi
  798. else
  799. #== 读取占位符所在行(实际行数=n+1)
  800. awk '/^'"${delimiter}"'/ { print NR; exit }' "${INSTALLER_FILE}"
  801. fi
  802. }
  803. #== 【0】=从指定行范围读取配置参数
  804. readParam() {
  805. local paramName="${1}"
  806. local paramsSectionBeggining="${2}"
  807. local paramsSectionEnd="${3}"
  808. sed -n "${paramsSectionBeggining},${paramsSectionEnd} s/^${paramName}=//p" "${INSTALLER_FILE}"
  809. }
  810. #== 【0】=读取以【----PARAMETERS】开始到 【----PARAMETERS--】之间的参数
  811. readParamsSection() {
  812. local sectionName="----PARAMETERS"
  813. local begin
  814. local end
  815. begin=$(locateDelimiter "${sectionName}" ${LINES_TO_SEARCH_FOR_SIGNATURE_AND_PARAMS})
  816. end=$(locateDelimiter "${sectionName}--" ${LINES_TO_SEARCH_FOR_SIGNATURE_AND_PARAMS})
  817. if [ -z "${begin}" ] || [ -z "${end}" ]; then
  818. return
  819. fi
  820. #== 从指定行范围读取配置参数
  821. local value
  822. if value="$(readParam PARAM_DATA_SERVER "${begin}" "${end}")"; then
  823. PARAM_DATA_SERVER="${value}"
  824. fi
  825. if value="$(readParam PARAM_CONFIG_SERVER "${begin}" "${end}")"; then
  826. PARAM_CONFIG_SERVER="${value}"
  827. fi
  828. if value="$(readParam PARAM_LICENSE "${begin}" "${end}")"; then
  829. PARAM_LICENSE="${value}"
  830. fi
  831. if value="$(readParam PARAM_JSON_CONF "${begin}" "${end}")"; then
  832. PARAM_JSON_CONF="${value}"
  833. fi
  834. if value="$(readParam PARAM_USER "${begin}" "${end}")"; then
  835. PARAM_USER="${value}"
  836. fi
  837. if value="$(readParam PARAM_GROUP "${begin}" "${end}")"; then
  838. PARAM_GROUP="${value}"
  839. fi
  840. if value="$(readParam PARAM_NON_ROOT_MODE "${begin}" "${end}")"; then
  841. if value="$(getBoolParam "${value}")"; then
  842. PARAM_NON_ROOT_MODE="${value}"
  843. fi
  844. fi
  845. if value="$(readParam PARAM_USER_LOGIN "${begin}" "${end}")"; then
  846. if value="$(getBoolParam "${value}")"; then
  847. PARAM_USER_LOGIN="${value}"
  848. fi
  849. fi
  850. toConsoleInfo "#DEBUG== install sh params, DATA_SERVER: ${PARAM_DATA_SERVER}, PARAM_CONFIG_SERVER: ${PARAM_CONFIG_SERVER}, PARAM_LICENSE:${PARAM_LICENSE}"
  851. 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}"
  852. }
  853. #== 【0】【6】=清空安装临时文件
  854. #== ${INSTALL_DIR}_install_$$
  855. #== EXTERNAL_TAR_FILE=${INSTALL_DIR}/tarfile_$$.base64
  856. #== ${INSTALL_DIR}/Dynatrace-OneAgent.tar.xz
  857. #== ${INSTALL_DIR}/xzdec
  858. #== /tmp/${BRAND_PRODUCT_NAME_LOWER}.lock
  859. cleanInstallationTemporaryFiles() {
  860. toLogInfo "Cleaning installation temporary files"
  861. rm -f "${EXTERNAL_TAR_FILE}" "${INTERNAL_TAR_FILE}" "${INSTALL_DIR}/xzdec"
  862. rm -Rf "${TMP_DIR}"
  863. local keepInstallationLockFile="${1}"
  864. if [ -z "${keepInstallationLockFile}" ]; then
  865. removeInstallationLockFile
  866. fi
  867. }
  868. #== 完成安装后清理临时目录
  869. finishInstallation() {
  870. if [ $# -eq 2 ]; then
  871. cleanInstallationTemporaryFiles "${2}"
  872. else
  873. cleanInstallationTemporaryFiles ""
  874. fi
  875. toLogInfo "Installation finished, PID $$, exit code: ${1}."
  876. changeWorkingDir "${CURR_PATH}"
  877. if [ "${CONF_LD_PRELOAD}"x = "true"x ]; then
  878. exec /bin/bash && exit 0
  879. fi
  880. exit "${1}"
  881. }
  882. #**********************************************************
  883. # Create folders, copy files, set rights
  884. #**********************************************************
  885. #== 【3】=创建临时目录
  886. prepareTempFolder() {
  887. #== 删除存在的路径
  888. removeIfExists "${TMP_DIR}"
  889. toLogInfo "Creating temporary folder $TMP_DIR"
  890. createDirIfNotExistAndSetRights "${TMP_DIR}" 755
  891. }
  892. #== 【4】=设置文件可执行权限
  893. setRightsForFiles() {
  894. local file="${1}"
  895. local perms="${2}"
  896. if [ -e "${file}" ]; then
  897. chmod "${perms}" "${file}"
  898. fi
  899. }
  900. setRightsForDir() {
  901. local dir="${1}"
  902. local perms="${2}"
  903. if [ -d "${dir}" ]; then
  904. chmod -R "${perms}" "${dir}"
  905. fi
  906. }
  907. #== 【4】=安装类型(f:文件,d:目录)递归设置权限
  908. chmod4FilesRecursively() {
  909. local dir="${1}"
  910. local type="${2}"
  911. local mask="${3}"
  912. find "${dir}" -type "${type}" -exec chmod "${mask}" {} \;
  913. }
  914. #== 【4】=移动目录到指定位置
  915. moveFolderToDestination() {
  916. local source="${1}"
  917. local destination="${2}"
  918. local fullDestination
  919. fullDestination="${destination}/$(basename "${source}")"
  920. local output
  921. toLogInfo "Moving ${source} to ${destination}"
  922. if [ ! -e "${fullDestination}" ]; then
  923. if output="$(mv -f "${source}" "${destination}" 2>&1)"; then
  924. toLogInfo "Moving Successfully."
  925. return
  926. fi
  927. toLogWarn "Failed to move ${source} to ${destination}: ${output}, attempting to copy"
  928. else
  929. toLogInfo "${fullDestination} already exists, attempting to copy"
  930. fi
  931. if ! output="$(cp -Rfp "${source}" "${destination}" 2>&1)"; then
  932. toLogError "Failed to copy ${source} to ${destination}: ${output}"
  933. fi
  934. }
  935. #== 【4】=将 bin 下版本内容移动到安装目录
  936. installVersionedContent() {
  937. toLogInfo "Installing versioned content..."
  938. createDirIfNotExistAndSetRights "${AGENT_BIN_DIR}" 755
  939. local sourceDir="${TMP_DIR}/bin"
  940. if [ ! -d "${AGENT_BIN_DIR}" ]; then
  941. moveFolderToDestination "${sourceDir}" "${AGENT_BIN_DIR}"
  942. return
  943. fi
  944. toLogInfo "Directory ${AGENT_BIN_DIR} already exist, repairing the directory"
  945. rm -rf "${AGENT_BIN_DIR}"
  946. moveFolderToDestination "${sourceDir}" "${AGENT_BIN_DIR}"
  947. }
  948. #== 【4】=创建当前版本软连接
  949. #== 【4】=删除存在的目录
  950. listAndRemoveDirectoryIfExists() {
  951. local directory="${1}"
  952. if [ -d "${directory}" ]; then
  953. toLogInfo "${directory} exists, removing it."
  954. toLogInfo "Contents: $(ls -lR "${directory}")"
  955. rm -rf "${directory}"
  956. fi
  957. }
  958. #== 【4】=临时目录中conf 移动到 agent 安装目录中
  959. setupConfFolder() {
  960. toLogInfo "Setup conf folder..."
  961. #== 移动目录到指定位置
  962. moveFolderToDestination "${TMP_DIR}/conf" "${INSTALL_DIR}"
  963. chmod 755 "${AGENT_CONF_DIR}"
  964. toLogInfo "Setup conf done."
  965. }
  966. #== 【4】=给距离当前目录至少 ${mindepth} 个子目录的所有文件设置权限
  967. chmodFilesWithMindepth() {
  968. local dir="${1}"
  969. local mindepth="${2}"
  970. local mask="${3}"
  971. if [ "${ARCH_ARCH}"x = "AIX"x ]; then
  972. #== 安装类型(f:文件,d:目录)递归设置权限
  973. chmod4FilesRecursively "${1}" f "${3}"
  974. else
  975. #== 查找深度距离当前目录至少 ${mindepth} 个子目录的所有文件
  976. find "${dir}" -mindepth "${mindepth}" -print0 | xargs -r -0 chmod "${mask}"
  977. fi
  978. }
  979. #== 【4】=配置其他文件(cwserveragent.service、installer.version)
  980. setupMiscFiles() {
  981. toLogInfo "Setup misc files..."
  982. #== 创建 cwserveragent.service
  983. createSystemdUnitFile
  984. #== echo "${AGENT_INSTALLER_VERSION}" >"${INSTALL_DIR}/installer.version"
  985. mv -f "${TMP_DIR}/installer.version" "${INSTALL_DIR}/"
  986. toLogInfo "Setup misc done."
  987. }
  988. #== 【4】=创建 cwserveragent.service
  989. createSystemdUnitFile() {
  990. toLogInfo "creating init scripts ${AGENT_SCRIPTS_DIR}"
  991. if [ "${INIT_SYSTEM}"x = "${INIT_SYSTEM_SYSV}"x ]; then
  992. return
  993. fi
  994. createDirIfNotExistAndSetRights "${AGENT_SCRIPTS_DIR}" 755
  995. cat <<EOF >${AGENT_SCRIPTS_DIR}/${SYSTEMD_UNIT_FILE_AGENT}
  996. [Unit]
  997. Description=${BRAND_AGENT_PRODUCT_NAME}
  998. After=network-online.target
  999. Wants=network-online.target
  1000. [Service]
  1001. User=root
  1002. ExecStart=${AGENT_SCRIPTS_DIR}/${SERVICE_SCRIPT_FILE} start
  1003. ExecStop=${AGENT_SCRIPTS_DIR}/${SERVICE_SCRIPT_FILE} stop
  1004. Type=forking
  1005. #Restart=always
  1006. KillMode=process
  1007. TimeoutSec=240
  1008. [Install]
  1009. WantedBy=multi-user.target
  1010. EOF
  1011. setRightsForFiles "${AGENT_SCRIPTS_DIR}/${SYSTEMD_UNIT_FILE_AGENT}" 755
  1012. if [ "${INIT_DIR}"x != "${AGENT_SCRIPTS_DIR}"x ]; then
  1013. cp -f "${AGENT_SCRIPTS_DIR}/${SYSTEMD_UNIT_FILE_AGENT}" ${INIT_DIR}
  1014. toLogInfo "Copy scripts ${AGENT_SCRIPTS_DIR}/${SYSTEMD_UNIT_FILE_AGENT} to ${INIT_DIR} done."
  1015. fi
  1016. toLogInfo "creating init scripts ${AGENT_SCRIPTS_DIR} done."
  1017. }
  1018. setupAll() {
  1019. # moveFolderToDestination "${TMP_DIR}/package_dir/*" "${INSTALL_DIR}"
  1020. #ls ${TMP_DIR}/package_dir/*
  1021. #== 移动所有文件到目录
  1022. cp -Rfp ${TMP_DIR}/package_dir/* "${INSTALL_DIR}"
  1023. local installVersionFile="${INSTALL_DIR}/installer.version"
  1024. echo ${AGENT_INSTALLER_VERSION} > ${installVersionFile}
  1025. # mv ${INSTALL_DIR}/package_dir/* ${INSTALL_DIR}
  1026. # echo "${TMP_DIR}/*" "${INSTALL_DIR}/"
  1027. }
  1028. #== 【4】=配置 lib、conf、bin、cwserveragent.service、installer.version、plugins
  1029. setupOptDir() {
  1030. createDirIfNotExistAndSetRights "${INSTALL_DIR}" 1775
  1031. #== 临时目录中conf 移动到 agent 安装目录中
  1032. setupConfFolder
  1033. #== 将 bin 下版本内容移动到安装目录
  1034. installVersionedContent
  1035. #== 配置其他文件(cwserveragent.service、installer.version)
  1036. setupMiscFiles
  1037. }
  1038. #== 【4】=复制临时目录 scripts/cwserveragent 到指定目录下
  1039. copyScriptsToDirectory() {
  1040. local scriptLocation="${1}"
  1041. #== scripts/cwserveragent
  1042. local scriptFile="${TMP_DIR}/scripts/${SERVICE_SCRIPT_FILE}"
  1043. toLogInfo "Copy scripts ${scriptFile} to ${scriptLocation} begin."
  1044. local output
  1045. if ! output="$(cp "${scriptFile}" "${scriptLocation}/" 2>&1)"; then
  1046. toLogError "Failed to copy ${scriptFile} to ${scriptLocation}, output: ${output}"
  1047. return
  1048. fi
  1049. setRightsForFiles "${scriptLocation}/${SERVICE_SCRIPT_FILE}" 755
  1050. toLogInfo "Copy scripts ${scriptFile} to ${scriptLocation} done."
  1051. #== scripts/uninstall.sh
  1052. # local scriptLocation="${1}"
  1053. # #== scripts/cwserveragent
  1054. # local scriptFile="${TMP_DIR}/scripts/uninstall.sh"
  1055. #
  1056. # toLogInfo "Copy scripts ${scriptFile} to ${scriptLocation} begin."
  1057. #
  1058. # local output
  1059. # if ! output="$(cp "${scriptFile}" "${scriptLocation}/" 2>&1)"; then
  1060. # toLogError "Failed to copy ${scriptFile} to ${scriptLocation}, output: ${output}"
  1061. # return
  1062. # fi
  1063. # setRightsForFiles "${scriptLocation}/uninstall.sh" 755
  1064. # toLogInfo "Copy scripts ${scriptFile} to ${scriptLocation} done."
  1065. }
  1066. #== 【4】=复制临时目录 scripts/cwserveragent 到指定目录下
  1067. copyScripts() {
  1068. toLogInfo "Copy scripts..."
  1069. #== 创建目录 /opt/cloudwise/cwserveragent/scripts
  1070. createDirIfNotExistAndSetRights "${AGENT_SCRIPTS_DIR}" 755
  1071. #== 创建目录 /opt/cloudwise/{product}/agents
  1072. createDirIfNotExistAndSetRights "${AGENTS_BASE_DIR}" 775
  1073. #== 创建目录 /opt/cloudwise/{product}/meta
  1074. createDirIfNotExistAndSetRights "${META_BASE_DIR}" 775
  1075. #== 创建目录 /opt/cloudwise/{product}/runtime
  1076. createDirIfNotExistAndSetRights "${AGENT_RUNTIME_DIR}" 775
  1077. #== scripts/uninstall.sh
  1078. local uninstallScript="${TMP_DIR}/scripts/uninstall.sh"
  1079. toLogInfo "Copy scripts ${uninstallScript} to ${INSTALL_DIR} begin."
  1080. local output
  1081. if ! output="$(cp "${uninstallScript}" "${INSTALL_DIR}/uninstall.sh" 2>&1)"; then
  1082. toLogError "Failed to copy ${uninstallScript} to ${INSTALL_DIR}/uninstall.sh, output: ${output}"
  1083. else
  1084. setRightsForFiles "${INSTALL_DIR}/uninstall.sh" 755
  1085. fi
  1086. toLogInfo "Copy scripts ${uninstallScript} to ${INSTALL_DIR} done."
  1087. #== 复制临时目录 scripts/ 到安装目录 /opt/cloudwise/cwserveragent/scripts
  1088. copyScriptsToDirectory "${AGENT_SCRIPTS_DIR}"
  1089. if [ "${INIT_DIR}"x != "${AGENT_SCRIPTS_DIR}"x ]; then
  1090. copyScriptsToDirectory "${INIT_DIR}"
  1091. fi
  1092. toLogInfo "Copy scripts done."
  1093. }
  1094. #== 【4】=调用 agent 64位数lib路径(lib64/installaction)执行指令 --create-cluster-timestamp-file
  1095. createFirstClusterTimestampFile() {
  1096. toLogInfo "Creating firstClusterTimestamp file"
  1097. #== 调用 agent 64位数lib路径(lib64/installaction)执行指令 --create-cluster-timestamp-file
  1098. "$(getAgentInstallActionPath)" "--create-cluster-timestamp-file" >>"${LOG_FILE}" 2>&1
  1099. }
  1100. #== 【4】=配置数据存储目录
  1101. setupDataStorageDir() {
  1102. toLogInfo "Setup datastorage dir..."
  1103. local dataStorage
  1104. dataStorage="$(getValueFromConfigFile "${CONF_FIELD_NM_DATA_STORAGE}" "${LEGACY_AGENT_CONF_FILE}" "${DATA_STORAGE_DIR}")"
  1105. if [ "${dataStorage}"x = "${LOG_DIR}"x ]; then
  1106. toLogInfo "Detected legacy data storage setting, changing it to the new default location"
  1107. writeParamToConfigFile "${CONF_FIELD_NM_DATA_STORAGE}" "${DATA_STORAGE_DIR}" "${LEGACY_AGENT_CONF_FILE}"
  1108. writeParamToConfigFile "${CONF_FIELD_NM_DATA_STORAGE}" "${DATA_STORAGE_DIR}" "${INSTALLER_CONF_FILE}"
  1109. fi
  1110. if [ "${PARAM_DATA_STORAGE}" ]; then
  1111. writeParamToConfigFile "${CONF_FIELD_NM_DATA_STORAGE}" "${PARAM_DATA_STORAGE}" "${LEGACY_AGENT_CONF_FILE}"
  1112. writeParamToConfigFile "${CONF_FIELD_NM_DATA_STORAGE}" "${PARAM_DATA_STORAGE}" "${INSTALLER_CONF_FILE}"
  1113. fi
  1114. toLogInfo "Setup datastorage dir done."
  1115. }
  1116. #**********************************************************
  1117. # Processing command line parameters
  1118. #**********************************************************
  1119. #== 【0】=help
  1120. displayHelp() {
  1121. printf '%s\n' "Usage: $(basename "${INSTALLER_FILE}") [-h] [-v] "
  1122. #== 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]"
  1123. local beginStr="Usage: "
  1124. local pad="${#beginStr}"
  1125. printf "\n\n"
  1126. pad=25
  1127. printf "%-${pad}s%s\n" "-h, --help" "Display this help and exit."
  1128. printf "%-${pad}s%s\n" "-v, --version" "Print version and exit."
  1129. }
  1130. printParamMessage() {
  1131. local paramNm="${1}"
  1132. local paramValue="${2}"
  1133. toConsoleInfo "---> Parameter ${paramNm}=${paramValue}."
  1134. }
  1135. printOtherParamMessage() {
  1136. local param="${1}"
  1137. toConsoleInfo "---> Parameter ${param}"
  1138. }
  1139. #== 【0】=大小写转化,并返回判断结果
  1140. istrcmp() {
  1141. local s1
  1142. local s2
  1143. s1="$(printf '%s' "${1}" | tr '[:upper:]' '[:lower:]')"
  1144. s2="$(printf '%s' "${2}" | tr '[:upper:]' '[:lower:]')"
  1145. [ "${s1}"x = "${s2}"x ]
  1146. }
  1147. #== 【0】=
  1148. isParamTrue() {
  1149. [ "${1}"x = "1"x ] || [ "${1}"x = "true"x ] || [ "${1}"x = "enable"x ] || [ "${1}"x = "yes"x ]
  1150. }
  1151. #== 【1】【5】=
  1152. isParamFalse() {
  1153. [ "${1}"x = "0"x ] || [ "${1}"x = "false"x ] || [ "${1}"x = "disable"x ] || [ "${1}"x = "no"x ]
  1154. }
  1155. #== 【1】【5】=
  1156. invertBoolValue() {
  1157. local valueToInvert="${1}"
  1158. if isParamFalse "${valueToInvert}"; then
  1159. printf '%s' "true"
  1160. else
  1161. printf '%s' "false"
  1162. fi
  1163. }
  1164. #== shellcheck disable=SC2003
  1165. #== 【0】=获取参数值
  1166. getParamValue() {
  1167. local paramName="${1}"
  1168. local input="${2}"
  1169. local paramNameLength="${#paramName}"
  1170. paramNameLength=$((paramNameLength + 1))
  1171. local partParam
  1172. partParam="$(expr substr "${input}" 1 ${paramNameLength})"
  1173. # partParam=$(substr "${input}" 1 ${paramNameLength})
  1174. if ! istrcmp "${partParam}" "${paramName}="; then
  1175. return 1
  1176. fi
  1177. local valueSeparator=$((paramNameLength + 1))
  1178. local value
  1179. value="$(expr substr "${input}" ${valueSeparator} 1000)"
  1180. # value=$(substr "${input}" ${valueSeparator} 1000)
  1181. if [ -z "${value}" ]; then
  1182. return 1
  1183. fi
  1184. printf '%s' "${value}"
  1185. return 0
  1186. }
  1187. #== 【0】=获取bool参数
  1188. readBoolParam() {
  1189. local value
  1190. value="$(getParamValue "${1}" "${2}")"
  1191. if value="$(getBoolParam "${value}")"; then
  1192. printf "%s" "${value}"
  1193. return 0
  1194. fi
  1195. return 1
  1196. }
  1197. #== 【0】=获取bool参数
  1198. getBoolParam() {
  1199. local value="${1}"
  1200. if [ "${value}" ]; then
  1201. if isParamFalse "${value}"; then
  1202. printf "false"
  1203. return 0
  1204. fi
  1205. if isParamTrue "${value}"; then
  1206. printf "true"
  1207. return 0
  1208. fi
  1209. fi
  1210. return 1
  1211. }
  1212. #== 【0】=校验格式是否规范[1、大于4个字符且不能"cw."开头,2、不能超过100字符,3、只能包含字母数字字符,连字符,下划线和点。]
  1213. validateParameter() {
  1214. local name="${1}"
  1215. local value="${2}"
  1216. if [ "$(printf '%s' "${value}" | cut -c -3)"x = "cw."x ]; then
  1217. toConsoleError "${name} must not begin with 'cw.'"
  1218. finishInstallation "${EXIT_CODE_INVALID_PARAM}"
  1219. fi
  1220. if [ "${#value}" -gt 100 ]; then
  1221. toConsoleError "Maximum allowed length of ${name} is 100."
  1222. finishInstallation "${EXIT_CODE_INVALID_PARAM}"
  1223. fi
  1224. if printf '%s' "${value}" | grep -q "[^[:alnum:]._-]"; then
  1225. toConsoleError "${name} can only contain alphanumeric characters, hyphen, underscore and dot."
  1226. finishInstallation "${EXIT_CODE_INVALID_PARAM}"
  1227. fi
  1228. }
  1229. #== 【0】=验证用户和用户组是否匹配
  1230. validateUserAndGroupParameters() {
  1231. local user="${1}"
  1232. local group="${2}"
  1233. local permittedNameRegex='^[[:alnum:]._][[:alnum:]._-]{2,31}$'
  1234. if [ ! "${group}" ]; then
  1235. group="${user}"
  1236. fi
  1237. if ! printf '%s' "${user}" | grep -qE "${permittedNameRegex}"; then
  1238. toConsoleError "USER can only contain alphanumeric characters, hyphen, underscore and dot, and must have length from 3 to 32 characters."
  1239. finishInstallation "${EXIT_CODE_INVALID_PARAM}"
  1240. fi
  1241. if ! printf '%s' "${group}" | grep -qE "${permittedNameRegex}"; then
  1242. toConsoleError "GROUP can only contain alphanumeric characters, hyphen, underscore and dot, and must have length from 3 to 32 characters."
  1243. finishInstallation "${EXIT_CODE_INVALID_PARAM}"
  1244. fi
  1245. #== 校验用户/用户组信息
  1246. validateUserPrimaryGroup "${user}" "${group}"
  1247. }
  1248. #== 【0】【3】【5】=获取系统权限信息
  1249. getSystemEntityInfo() {
  1250. local database="${1}"
  1251. local valueToCheck="${2}"
  1252. #== 校验命令getent是否存在
  1253. if ! isAvailable "getent"; then
  1254. toLogInfo "Command getent is not available"
  1255. return 2
  1256. fi
  1257. #== 查看系统权限
  1258. local output
  1259. output="$(getent "${database}" "${valueToCheck}" 2>&1)"
  1260. local returnCode=$?
  1261. if [ "${returnCode}" != 0 ]; then
  1262. if [ "${returnCode}" != 2 ]; then
  1263. toLogWarn "Failed to check ${valueToCheck} in ${database} database, message: ${output}, code: ${returnCode}"
  1264. fi
  1265. return 1
  1266. elif [ ! "${output}" ]; then
  1267. toLogWarn "Failed to get user information: getent returned no output"
  1268. fi
  1269. printf '%s' "${output}"
  1270. return 0
  1271. }
  1272. #== 【0】【3】=查看用户/用户组信息
  1273. isEntityPassedById() {
  1274. local database="${1}"
  1275. local name="${2}"
  1276. local output
  1277. output="$(getSystemEntityInfo "${database}" "${name}")"
  1278. local returnCode=$?
  1279. if [ ${returnCode} -ne 0 ]; then
  1280. if [ ${returnCode} -eq 2 ]; then
  1281. toLogInfo "Installer will not be able to verify whether entity was passed by name or by ID"
  1282. fi
  1283. return 1
  1284. fi
  1285. local nameFromDatabase
  1286. nameFromDatabase="$(printf '%s' "${output}" | cut -d: -f1)"
  1287. if [ "${nameFromDatabase}"x = "${name}"x ]; then
  1288. return 1
  1289. fi
  1290. toLogWarn "Name from config and from ${database} system database do not match"
  1291. toLogWarn "Config: ${name}, database: ${nameFromDatabase}"
  1292. return 0
  1293. }
  1294. #== 【0】【3】【5】=用户是否存在
  1295. userExistsInSystem() {
  1296. local user="${1}"
  1297. getSystemEntityInfo "passwd" "${user}" >/dev/null
  1298. local returnCode=$?
  1299. if [ ${returnCode} -ne 2 ]; then
  1300. return ${returnCode}
  1301. fi
  1302. toLogInfo "Trying to determine user existence using 'id' command"
  1303. id "${user}" >/dev/null 2>&1
  1304. }
  1305. #== 【5】= 查看group
  1306. groupExistsInSystem() {
  1307. local group="${1}"
  1308. getSystemEntityInfo "group" "${group}" >/dev/null
  1309. local returnCode=$?
  1310. if [ ${returnCode} -ne 2 ]; then
  1311. return ${returnCode}
  1312. fi
  1313. toLogInfo "Installer will not be able to determine group existence"
  1314. return 1
  1315. }
  1316. #== 【3】=用户是否存在
  1317. validateUserExistence() {
  1318. local user="${1}"
  1319. if ! userExistsInSystem "${user}"; then
  1320. toConsoleError "User named '${user}' configured for ${BRAND_PRODUCT_NAME} does not exist. Installation aborted."
  1321. finishInstallation "${EXIT_CODE_INVALID_PARAM}"
  1322. fi
  1323. }
  1324. #== 【0】【3】=检查用户/用户组信息
  1325. checkIfEntityWasNotPassedById() {
  1326. local database="${1}"
  1327. local valueToCheck="${2}"
  1328. local valueTypeToLog="user"
  1329. if [ "${database}"x = "group"x ]; then
  1330. valueTypeToLog="group"
  1331. fi
  1332. if isEntityPassedById "${database}" "${valueToCheck}"; then
  1333. toConsoleError "\"${valueToCheck}\" is not a ${valueTypeToLog} name but its ID. Installation aborted."
  1334. finishInstallation "${EXIT_CODE_INVALID_PARAM}"
  1335. fi
  1336. }
  1337. #== 【0】【3】=用户权限下用户组ID
  1338. getUserPrimaryGroupIdForComparison() {
  1339. local user="${1}"
  1340. local userPrimaryGroupId
  1341. userPrimaryGroupId="$(getSystemEntityInfo "passwd" "${user}")"
  1342. local returnCode=$?
  1343. if [ ${returnCode} -ne 2 ]; then
  1344. printf '%s' "${userPrimaryGroupId}" | cut -d: -f4
  1345. return ${returnCode}
  1346. fi
  1347. toLogInfo "Returning user primary group name instead of its id"
  1348. id -gn "${user}"
  1349. }
  1350. #== 【0】【3】=获取用户组信息
  1351. getGroupIdForComparison() {
  1352. local group="${1}"
  1353. local groupId
  1354. groupId="$(getSystemEntityInfo "group" "${group}")"
  1355. local returnCode=$?
  1356. if [ ${returnCode} -ne 2 ]; then
  1357. printf '%s' "${groupId}" | cut -d: -f3
  1358. return ${returnCode}
  1359. fi
  1360. toLogInfo "Returning group name instead of its id"
  1361. printf '%s' "${group}"
  1362. }
  1363. #== 【0】【3】=校验用户/用户组信息
  1364. validateUserPrimaryGroup() {
  1365. local user="${1}"
  1366. local group="${2}"
  1367. if ! userExistsInSystem "${user}"; then
  1368. return
  1369. fi
  1370. checkIfEntityWasNotPassedById "passwd" "${user}"
  1371. checkIfEntityWasNotPassedById "group" "${group}"
  1372. #== 获取用户组ID
  1373. local groupId
  1374. groupId="$(getGroupIdForComparison "${group}")"
  1375. #== 获取用户下用户组ID
  1376. local userPrimaryGroupId
  1377. userPrimaryGroupId="$(getUserPrimaryGroupIdForComparison "${user}")"
  1378. toConsoleInfo "#DEBUG== group \"${group}\" id: \"${groupId}\", user \"${user}\" primaryGroupId: \"${userPrimaryGroupId}\""
  1379. if [ "${userPrimaryGroupId}"x != "${groupId}"x ]; then
  1380. toConsoleError "User named \"${user}\" does not have group named \"${group}\" as its primary group. Installation aborted."
  1381. finishInstallation "${EXIT_CODE_INVALID_PARAM}"
  1382. fi
  1383. }
  1384. #== 【3】=检查用户/用户组是否存在和匹配
  1385. checkUserAndGroupFromConfig() {
  1386. local configUser
  1387. local configGroup
  1388. configUser="$(getValueFromConfigFile "${CONF_FIELD_NM_USER}" "${LEGACY_AGENT_CONF_FILE}" "${BRAND_AGENT_DEFAULT_USER_AND_GROUP_NAME}")"
  1389. configGroup="$(getValueFromConfigFile "${CONF_FIELD_NM_GROUP}" "${LEGACY_AGENT_CONF_FILE}" "${BRAND_AGENT_DEFAULT_USER_AND_GROUP_NAME}")"
  1390. toLogInfo "Checking validity of user account '${configUser}:${configGroup}'"
  1391. if [ "${PARAM_UPGRADE}"x = "yes"x ]; then
  1392. validateUserExistence "${configUser}"
  1393. fi
  1394. #== 校验用户/用户组信息
  1395. validateUserPrimaryGroup "${configUser}" "${configGroup}"
  1396. }
  1397. #== 【0】=解析命令行中参数
  1398. parseCommandLineParameters() {
  1399. local dataServerIsEmpty=true
  1400. local configServerIsEmpty=true
  1401. while [ $# -gt 0 ]; do
  1402. local param="${1}"
  1403. local value=
  1404. if value=$(getParamValue DATA_SERVER "${param}"); then
  1405. PARAM_DATA_SERVER="${value}"
  1406. dataServerIsEmpty=false
  1407. printParamMessage "DATA_SERVER" "${value}"
  1408. shift
  1409. continue
  1410. fi
  1411. if value=$(getParamValue CONFIG_SERVER "${param}"); then
  1412. PARAM_CONFIG_SERVER="${value}"
  1413. configServerIsEmpty=false
  1414. printParamMessage "CONFIG_SERVER" "${value}"
  1415. shift
  1416. continue
  1417. fi
  1418. if value=$(getParamValue LICENSE "${param}"); then
  1419. PARAM_LICENSE="${value}"
  1420. printParamMessage "LICENSE" "${value}"
  1421. shift
  1422. continue
  1423. fi
  1424. if value=$(getParamValue JSON_CONF "${param}"); then
  1425. PARAM_JSON_CONF="${value}"
  1426. printParamMessage "JSON_CONF" "${value}"
  1427. shift
  1428. continue
  1429. fi
  1430. if value=$(getParamValue INSTALL_DIR "${param}"); then
  1431. PARAM_INSTALL_DIR="${value}"
  1432. printParamMessage "INSTALL_DIR" "${value}"
  1433. shift
  1434. continue
  1435. fi
  1436. if value=$(getParamValue DATA_STORAGE "${param}"); then
  1437. PARAM_DATA_STORAGE="${value}"
  1438. printParamMessage "DATA_STORAGE" "${value}"
  1439. shift
  1440. continue
  1441. fi
  1442. if value=$(readBoolParam DISABLE_SYSTEM_LOGS_ACCESS "${param}"); then
  1443. PARAM_DISABLE_SYSTEM_LOGS_ACCESS="${value}"
  1444. printParamMessage "DISABLE_SYSTEM_LOGS_ACCESS" "${value}"
  1445. shift
  1446. continue
  1447. fi
  1448. if value=$(getParamValue INTERNAL_OVERRIDE_CHECKS "${param}"); then
  1449. if printf '%s' "${value}" | grep -wq "privileges"; then
  1450. PARAM_INTERNAL_NON_ROOT_MODE_SKIP_PRIVILEGES_CHECK=true
  1451. fi
  1452. if printf '%s' "${value}" | grep -wq "downgrade"; then
  1453. SKIP_DOWNGRADE_CHECK=true
  1454. fi
  1455. printParamMessage "INTERNAL_OVERRIDE_CHECKS" "${value}"
  1456. shift
  1457. continue
  1458. fi
  1459. if value=$(readBoolParam INTERNAL_USE_UNPACK_CACHE "${param}"); then
  1460. PARAM_INTERNAL_USE_UNPACK_CACHE="${value}"
  1461. printParamMessage "INTERNAL_USE_UNPACK_CACHE" "${value}"
  1462. shift
  1463. continue
  1464. fi
  1465. if [ "${ARCH_ARCH}"x != "AIX"x ]; then
  1466. if value=$(getParamValue USER "${param}"); then
  1467. PARAM_USER="${value}"
  1468. printParamMessage "USER" "${value}"
  1469. shift
  1470. continue
  1471. fi
  1472. if value=$(getParamValue GROUP "${param}"); then
  1473. PARAM_GROUP="${value}"
  1474. printParamMessage "GROUP" "${value}"
  1475. shift
  1476. continue
  1477. fi
  1478. if value=$(readBoolParam NON_ROOT_MODE "${param}"); then
  1479. PARAM_NON_ROOT_MODE="${value}"
  1480. printParamMessage "NON_ROOT_MODE" "${value}"
  1481. shift
  1482. continue
  1483. fi
  1484. if value=$(readBoolParam USER_LOGIN "${param}"); then
  1485. PARAM_USER_LOGIN="${value}"
  1486. printParamMessage "USER_LOGIN" "${value}"
  1487. shift
  1488. continue
  1489. fi
  1490. #== 自定义参数获取
  1491. if value=$(getParamValue TEST "${param}"); then
  1492. PARAM_TEST="${value}"
  1493. printParamMessage "TEST" "${value}"
  1494. shift
  1495. continue
  1496. fi
  1497. #== 自定义bool参数
  1498. if value=$(readBoolParam BOOL "${param}"); then
  1499. PARAM_BOOL="${value}"
  1500. printParamMessage "BOOL" "${value}"
  1501. shift
  1502. continue
  1503. fi
  1504. if value=$(readBoolParam DISABLE_ROOT_FALLBACK "${param}"); then
  1505. PARAM_DISABLE_ROOT_FALLBACK="${value}"
  1506. printParamMessage "DISABLE_ROOT_FALLBACK" "${value}"
  1507. shift
  1508. continue
  1509. fi
  1510. if value=$(readBoolParam NON_ROOT_MODE_SKIP_PRIVILEGES_CHECK "${param}"); then
  1511. PARAM_INTERNAL_NON_ROOT_MODE_SKIP_PRIVILEGES_CHECK="${value}"
  1512. printParamMessage "NON_ROOT_MODE_SKIP_PRIVILEGES_CHECK" "${value}"
  1513. shift
  1514. continue
  1515. fi
  1516. if value=$(readBoolParam INTERNAL_SKIP_SELINUX_POLICY_INSTALLER "${param}"); then
  1517. #== PARAM_INTERNAL_SKIP_SELINUX_POLICY_INSTALLER="${value}"
  1518. printParamMessage "INTERNAL_SKIP_SELINUX_POLICY_INSTALLER" "${value}"
  1519. shift
  1520. continue
  1521. fi
  1522. if value=$(readBoolParam DOCKER_ENABLED "${param}"); then
  1523. #== PARAM_INTERNAL_DEPLOYED_VIA_CONTAINER="${value}"
  1524. printParamMessage "DOCKER_ENABLED" "${value}"
  1525. shift
  1526. continue
  1527. fi
  1528. fi
  1529. if [ "${ARCH_ARCH}"x != "AIX"x ] && [ "${ARCH_ARCH}"x != "S390"x ]; then
  1530. if value=$(readBoolParam INTERNAL_DISABLE_DUMPPROC "${param}"); then
  1531. #== PARAM_INTERNAL_DISABLE_DUMPPROC="${value}"
  1532. printParamMessage "INTERNAL_DISABLE_DUMPPROC" "${value}"
  1533. shift
  1534. continue
  1535. fi
  1536. fi
  1537. if [ "${param}"x = "-h"x ] || [ "${param}"x = "--help"x ]; then
  1538. displayHelp
  1539. finishInstallation "${EXIT_CODE_OK}"
  1540. fi
  1541. if [ "${param}"x = "-v"x ] || [ "${param}"x = "--version"x ]; then
  1542. printf "%s\n" "${AGENT_INSTALLER_VERSION}"
  1543. finishInstallation "${EXIT_CODE_OK}"
  1544. fi
  1545. printOtherParamMessage ${param}
  1546. shift
  1547. done
  1548. if [ "${configServerIsEmpty}"x = "true"x ] && [ "${dataServerIsEmpty}"x != "true"x ]; then
  1549. PARAM_CONFIG_SERVER="${PARAM_DATA_SERVER}"
  1550. fi
  1551. }
  1552. #== 【0】=校验PARAM_INSTALL_DIR是否规范【1、不能包含空格,2、不能在根目录,3、安装路径必须是绝对的】
  1553. validateInstallPathParameter() {
  1554. if printf '%s' "${PARAM_INSTALL_DIR}" | grep -q "[[:space:]]"; then
  1555. toConsoleError "Installation path must not contain spaces."
  1556. finishInstallation "${EXIT_CODE_INVALID_PARAM}"
  1557. fi
  1558. if [ "${PARAM_INSTALL_DIR}"x = "/"x ]; then
  1559. toConsoleError "Installation path must not point to the filesystem root directory."
  1560. finishInstallation "${EXIT_CODE_INVALID_PARAM}"
  1561. fi
  1562. if [ "$(printf '%s' "${PARAM_INSTALL_DIR}" | cut -c 1)"x != "/"x ]; then
  1563. toConsoleError "Installation path must be absolute."
  1564. finishInstallation "${EXIT_CODE_INVALID_PARAM}"
  1565. fi
  1566. }
  1567. #== 【0】=校验PARAM_DATA_STORAGE是否规范【1、不能包含空格,2、不能在根目录,3、安装路径必须是绝对的,4、数据目录不能放在安装目录下】
  1568. validateDataStorageParameter() {
  1569. if printf '%s' "${PARAM_DATA_STORAGE}" | grep -q "[[:space:]]"; then
  1570. toConsoleError "Data storage path must not contain spaces."
  1571. finishInstallation "${EXIT_CODE_INVALID_PARAM}"
  1572. fi
  1573. if [ "${PARAM_DATA_STORAGE}"x = "/"x ]; then
  1574. toConsoleError "Data storage path must not point to the filesystem root directory."
  1575. finishInstallation "${EXIT_CODE_INVALID_PARAM}"
  1576. fi
  1577. if [ "$(printf '%s' "${PARAM_DATA_STORAGE}" | cut -c 1)"x != "/"x ]; then
  1578. toConsoleError "Data storage path must be absolute."
  1579. finishInstallation "${EXIT_CODE_INVALID_PARAM}"
  1580. fi
  1581. if printf '%s' "${PARAM_DATA_STORAGE}" | grep -q "^${INSTALL_DIR}"; then
  1582. toConsoleError "Data storage path must not be located within ${INSTALL_DIR}."
  1583. finishInstallation "${EXIT_CODE_INVALID_PARAM}"
  1584. fi
  1585. }
  1586. #**********************************************************
  1587. # Config files
  1588. #**********************************************************
  1589. #== 【3】【5】=格式化空间大小(将 1024KiB 格式化成 1MiB, 将 1024MiB 格式化成 1GiB,...)
  1590. formatSize() {
  1591. local sizeInKiB="${1}"
  1592. local formattedSize
  1593. for symbol in "KiB" "MiB" "GiB" "TiB"; do
  1594. if printf '%s' "${sizeInKiB}" | awk '$1 >= 1024 { exit 1; }'; then
  1595. formattedSize="${sizeInKiB} ${symbol}"
  1596. break
  1597. fi
  1598. sizeInKiB="$(printf '%s' "${sizeInKiB}" | awk '{ print $1 / 1024 }')"
  1599. done
  1600. printf '%s' "${formattedSize}"
  1601. }
  1602. #== 【3】【5】=
  1603. cropSizeValue() {
  1604. local size="${1}"
  1605. local value
  1606. local unit
  1607. value="$(printf '%s' "${size}" | cut -d' ' -f1)"
  1608. unit="$(printf '%s' "${size}" | cut -d' ' -f2)"
  1609. printf '%.2f %s' "${value}" "${unit}"
  1610. }
  1611. #== 【3】【5】=检查目录可用空间(单位:k)
  1612. checkFreeSpace() {
  1613. local path="${1}"
  1614. local requiredSpaceInKiB="${2}"
  1615. local dfOutput
  1616. local baseFilesystem
  1617. local freeSpace
  1618. local formattedRequiredSpace
  1619. local formattedFreeSpace
  1620. #== shellcheck disable=SC2086
  1621. dfOutput="$(df -P ${AIX_DF_SPECIFIC_FLAG} "${path}" | tail -n +2)"
  1622. #== 文件系统目录
  1623. baseFilesystem="$(printf "%s" "${dfOutput}" | awk '{ print $NF }')"
  1624. #== 剩余空间(单位:k)
  1625. freeSpace="$(printf "%s" "${dfOutput}" | awk '{ print $4 }')"
  1626. #== 格式化空间大小(将 1024KiB 格式化成 1MiB, 将 1024MiB 格式化成 1GiB,...)
  1627. formattedRequiredSpace="$(formatSize "${requiredSpaceInKiB}")"
  1628. toLogInfo "Filesystem with ${path} is mounted under ${baseFilesystem}. Space required: ${formattedRequiredSpace}."
  1629. if [ ! "${freeSpace}" ]; then
  1630. printf 'Cannot determine amount of free space on %s (filesystem mounted under %s)' "${path}" "${baseFilesystem}"
  1631. return 1
  1632. fi
  1633. #== 格式化空间大小(将 1024KiB 格式化成 1MiB, 将 1024MiB 格式化成 1GiB,...)
  1634. formattedFreeSpace="$(formatSize "${freeSpace}")"
  1635. toLogInfo "Available free space: ${formattedFreeSpace}"
  1636. if [ "${freeSpace}" -lt "${requiredSpaceInKiB}" ]; then
  1637. printf 'Not enough free space on %s (filesystem mounted under %s). ' "${path}" "${baseFilesystem}"
  1638. printf 'Required: %s, available: %s' "$(cropSizeValue "${formattedRequiredSpace}")" "$(cropSizeValue "${formattedFreeSpace}")"
  1639. return 2
  1640. fi
  1641. printf 'Free space is sufficient'
  1642. return 0
  1643. }
  1644. #== 【3】=检查文件系统类型
  1645. #== 【3】=检查安装目录空间
  1646. checkInstallPathFreeSpace() {
  1647. local externalTarSize=${EXTERNAL_TAR_SIZE}
  1648. local artifactsSize=${ARTIFACTS_SIZE}
  1649. #== use 10% additional margin
  1650. local requiredSpace=$((externalTarSize + artifactsSize * 11 / 10))
  1651. #== convert to kibibytes
  1652. requiredSpace=$((requiredSpace / 1024))
  1653. toConsoleInfo "Checking free space in ${INSTALL_DIR}"
  1654. local message
  1655. #== 检查目录可用空间(单位:k)
  1656. message="$(checkFreeSpace "${INSTALL_DIR}" "${requiredSpace}")"
  1657. case $? in
  1658. 0) toLogInfo "${message}" ;;
  1659. 1) toConsoleWarn "${message}. Installation may be incomplete." ;;
  1660. 2)
  1661. toConsoleError "${message}"
  1662. finishInstallation "${EXIT_CODE_NOT_ENOUGH_SPACE}"
  1663. ;;
  1664. esac
  1665. }
  1666. #== 【3】=获取指定路径的文件系统信息
  1667. getFilesystemInfo() {
  1668. if [ "${ARCH_ARCH}"x = "AIX"x ]; then
  1669. mount | grep " ${1} "
  1670. else
  1671. grep " ${1} " /proc/self/mounts
  1672. fi
  1673. }
  1674. #== 【3】=检查目录指定权限信息
  1675. checkAccessRightsTo() {
  1676. local dir="${1}"
  1677. toLogInfo "Checking access to ${dir}..."
  1678. #== 获取文件权限信息
  1679. local accessRights
  1680. accessRights="$(arch_getAccessRights "${dir}" | cut -c 2-4)"
  1681. if ! printf '%s' "${accessRights}" | grep -q rwx; then
  1682. toConsoleError "Insufficient permissions on ${dir}: '${accessRights}'."
  1683. toLogInfo "$(ls -dl "${dir}" 2>&1)"
  1684. finishInstallation "${EXIT_CODE_INSUFFICIENT_PERMISSIONS}"
  1685. fi
  1686. local dfResult
  1687. local filesystem
  1688. local filesystemInfo
  1689. dfResult="$(df -P "${dir}")"
  1690. #== 获取目录文件系统路径
  1691. filesystem="$(printf '%s' "${dfResult}" | tail -1 | awk '{ print $NF }')"
  1692. #== 获取指定路径的文件系统信息
  1693. filesystemInfo="$(getFilesystemInfo "${filesystem}")"
  1694. if ! printf '%s' "${filesystemInfo}" | grep -qw rw; then
  1695. toLogWarn "df-based check determined filesystem mounted under ${filesystem} as readonly, trying fallback."
  1696. toLogWarn "Filesystem access rights: '${filesystemInfo}'"
  1697. toLogWarn "df returned: ${dfResult}"
  1698. if ! testWriteAccessToDir "${dir}"; then
  1699. toConsoleError "readonly filesystem mounted under ${filesystem}"
  1700. finishInstallation "${EXIT_CODE_INSUFFICIENT_PERMISSIONS}"
  1701. fi
  1702. fi
  1703. toLogInfo "Rights on directory ${dir} are sufficient"
  1704. } 2>>"${LOG_FILE}"
  1705. #== 【3】=目录是否写权限
  1706. checkIfInstallationPathIsWriteable() {
  1707. for dir in "${@}"; do
  1708. if [ -d "${dir}" ]; then
  1709. checkAccessRightsTo "${dir}"
  1710. break
  1711. fi
  1712. done
  1713. }
  1714. #== 【3】=检查目录权限
  1715. checkAccessRightsToDirs() {
  1716. checkIfInstallationPathIsWriteable "${INSTALL_DIR}" "${BASE_INSTALL_DIR}" "${INSTALL_BASE}" /
  1717. if [ "${INIT_SYSTEM}"x = "${INIT_SYSTEM_SYSV}"x ]; then
  1718. checkAccessRightsTo "${INIT_DIR}"
  1719. fi
  1720. }
  1721. #== 【0】=检查系统是 LINUX、AIX及指令集(X86_64\IA64\X86)
  1722. checkSystemCompatibility() {
  1723. local expectedPlatform="LINUX"
  1724. if [ "${ARCH_ARCH}"x = "AIX"x ]; then
  1725. expectedPlatform="AIX"
  1726. fi
  1727. #== 获取系统名称
  1728. local platform
  1729. platform="$(uname | sed -e 's/_.*//' | sed -e 's/\///' | tr '[:lower:]' '[:upper:]')"
  1730. if [ "${platform}"x != "${expectedPlatform}"x ]; then
  1731. printf "Cannot determine platform or platform not supported: <%s>" "${platform}"
  1732. return 1
  1733. fi
  1734. #== 检查系统指令集(X86_64\IA64\X86)
  1735. local detectedArchitecture
  1736. if ! detectedArchitecture="$(arch_checkArchitectureCompatibility)"; then
  1737. printf "Cannot determine architecture or architecture not supported: <%s>" "${detectedArchitecture}"
  1738. return 1
  1739. fi
  1740. printf 'Detected platform: %s' "${platform}"
  1741. if [ "${detectedArchitecture}" ]; then
  1742. printf ' arch: %s' "${detectedArchitecture}"
  1743. fi
  1744. return 0
  1745. }
  1746. #== 【4】=从sh文件读取压缩文件 tarfile_$$.base64
  1747. separateExternalTar() {
  1748. toLogInfo "Determining begin of tar archive..."
  1749. local tarBegin
  1750. local tarEnd
  1751. #== 压缩文件开始行数,占位符为【#################ENDOFSCRIPTMARK############】
  1752. tarBegin="$(locateDelimiter "#################ENDOFSCRIPTMARK############" "")"
  1753. tarBegin=$((tarBegin + 1))
  1754. #== 压缩文件结束行数,占位符为【----SIGNED-INSTALLER】
  1755. tarEnd="$(locateDelimiter "----SIGNED-INSTALLER" ${LINES_TO_SEARCH_FOR_SIGNATURE_AND_PARAMS})"
  1756. toLogInfo "tarBegin=${tarBegin} tarEnd=${tarEnd}"
  1757. if [ ! "${tarEnd}" ]; then
  1758. toConsoleError "S/MIME signature is missing, installation package is corrupted."
  1759. finishInstallation "${EXIT_CODE_CORRUPTED_PACKAGE}"
  1760. fi
  1761. local tarLength=$((tarEnd - tarBegin))
  1762. toLogInfo "tarLength=${tarLength}"
  1763. #== 从sh文件读取压缩文件 tarfile_$$.base64
  1764. tail -n +"${tarBegin}" "${INSTALLER_FILE}" 2>/dev/null | head -${tarLength} >"${EXTERNAL_TAR_FILE}"
  1765. }
  1766. #== 【4】【5】=进入目录
  1767. changeWorkingDir() {
  1768. if ! cd "${1}"; then
  1769. toLogError "Failed to change working directory to ${1}"
  1770. finishInstallation "${EXIT_CODE_GENERIC_ERROR}"
  1771. fi
  1772. }
  1773. #== shellcheck disable=SC2181
  1774. #== 【4】=解压文件(1、通过base64转码后,执行tar解压;2、通过xzdec解压xz文件后在执行tar解压)
  1775. unpackArchiveWithoutCache() {
  1776. #== 解压文件编码
  1777. local base64Binary="${UNPACK_BINARY}"
  1778. #== 解压文件编码参数
  1779. local base64BinaryArgs="${UNPACK_BINARY_ARGS}"
  1780. #== 使用xzdec命令可以进行liblzma为基础的xz文件解压缩
  1781. local xzBinary="${INSTALL_DIR}/xzdec"
  1782. #== 进入目录
  1783. changeWorkingDir "${INSTALL_DIR}"
  1784. if ! isAvailable tar; then
  1785. toConsoleError "tar binary not found. Setup can't continue"
  1786. finishInstallation "${EXIT_CODE_MISCONFIGURED_ENVIRONMENT}"
  1787. fi
  1788. local totalLines
  1789. if ! isAvailable "${base64Binary}"; then
  1790. toLogInfo "${base64Binary} not found. Falling back to openssl decode"
  1791. if ! isAvailable openssl; then
  1792. toConsoleError "Neither ${base64Binary} nor openssl can be found. Setup can't continue"
  1793. finishInstallation "${EXIT_CODE_MISCONFIGURED_ENVIRONMENT}"
  1794. fi
  1795. #== 如果没有 base64 命令,则使用 openssl 解压文件
  1796. base64Binary="openssl"
  1797. base64BinaryArgs="enc -base64 -d -in"
  1798. if [ "${ARCH_ARCH}"x = "AIX"x ]; then
  1799. #truncate the first and the last one line due to specific format of uuencode on aix
  1800. totalLines="$(wc -l "${EXTERNAL_TAR_FILE}" | awk '{print $1}')"
  1801. head -$((totalLines - 1)) "${EXTERNAL_TAR_FILE}" 2>/dev/null | tail +2 >"${EXTERNAL_TAR_FILE}.$$"
  1802. mv -f "${EXTERNAL_TAR_FILE}.$$" "${EXTERNAL_TAR_FILE}"
  1803. fi
  1804. fi
  1805. {
  1806. #== base64 转编码后,执行 tar 解压
  1807. "${base64Binary}" "${base64BinaryArgs}" "${EXTERNAL_TAR_FILE}" | tar -x -p -f -
  1808. } 2>>"${LOG_FILE}"
  1809. #== base64 转编码 或 tar解压失败
  1810. if [ $? -gt 0 ]; then
  1811. toConsoleError "Archive is corrupted or memory allocation failed. Installation aborted."
  1812. finishInstallation "${EXIT_CODE_NOT_ENOUGH_MEMORY}"
  1813. fi
  1814. #== 进入目录
  1815. changeWorkingDir "${TMP_DIR}"
  1816. {
  1817. #== 使用xzdec命令解压后,执行 tar 解压
  1818. "${xzBinary}" "${INTERNAL_TAR_FILE}" | tar -x -p -f -
  1819. } 2>>"${LOG_FILE}"
  1820. if [ $? -gt 0 ]; then
  1821. toConsoleError "XZ compressed archive is corrupted or memory allocation failed. Installation aborted."
  1822. finishInstallation "${EXIT_CODE_NOT_ENOUGH_MEMORY}"
  1823. fi
  1824. #== 进入目录
  1825. changeWorkingDir "${INSTALL_DIR}"
  1826. }
  1827. #== 【4】=解压文件(1、通过base64转码后,执行tar解压;2、通过xzdec解压xz文件后在执行tar解压)
  1828. unpackArchive() {
  1829. toConsoleInfo "Unpacking. This may take a while..."
  1830. #== 【参数】是否使用解压缓存
  1831. if [ "${PARAM_INTERNAL_USE_UNPACK_CACHE}"x = "true"x ]; then
  1832. if [ -d "${UNPACK_CACHE}" ]; then
  1833. toLogInfo "Unpack cache will be used."
  1834. cp -Rp "${UNPACK_CACHE}"/* "${TMP_DIR}"
  1835. else
  1836. toLogInfo "Unpack cache does not exist."
  1837. mkdir -p "${UNPACK_CACHE}"
  1838. #== 解压文件(1、通过base64转码后,执行tar解压;2、通过xzdec解压xz文件后在执行tar解压)
  1839. unpackArchiveWithoutCache
  1840. cp -Rp "${TMP_DIR}"/* "${UNPACK_CACHE}"
  1841. fi
  1842. else
  1843. toLogInfo "Unpacking without cache"
  1844. #== 解压文件(1、通过base64转码后,执行tar解压;2、通过xzdec解压xz文件后在执行tar解压)
  1845. unpackArchiveWithoutCache
  1846. fi
  1847. toConsoleInfo "Unpacking complete."
  1848. }
  1849. #== 【3】=检查容器部署、运行情况、配置参数
  1850. #isDeployedInsideOpenVZContainer
  1851. #isProcessRunningInContainer
  1852. #isDeployedViaContainer
  1853. #== Checking if libc is new enough
  1854. #== 【3】=格式化version
  1855. format_version() {
  1856. printf '%s' "$@" | awk -F. '{ printf("%03d%03d%03d\n", $1,$2,$3); }'
  1857. }
  1858. #== 【3】=格式化路径
  1859. format_patch() {
  1860. printf '%s' "$@" | tail -n 1 | awk -F- '{ printf("%d\n", $3); }'
  1861. }
  1862. #== 【3】=检查是否降级安装
  1863. checkIfDowngrade() {
  1864. if [ "${SKIP_DOWNGRADE_CHECK}"x = "true"x ]; then
  1865. toConsoleInfo "Skipped downgrade check"
  1866. return
  1867. fi
  1868. local installVersionFile="${INSTALL_DIR}/installer.version"
  1869. if [ ! -f "${installVersionFile}" ]; then
  1870. toLogWarn "Could not perform downgrade check, ${installVersionFile} file is missing"
  1871. return
  1872. fi
  1873. local oldVersion
  1874. oldVersion="$(cat "${installVersionFile}")"
  1875. if [ "$(format_version "${AGENT_INSTALLER_VERSION}")" -eq "$(format_version "${oldVersion}")" ]; then
  1876. toConsoleError "${BRAND_PRODUCT_NAME} is already installed, please uninstall the old version using [${INSTALL_DIR}/uninstall.sh]."
  1877. # toLogError "Attempted downgrade from ${oldVersion} to ${AGENT_INSTALLER_VERSION}"
  1878. finishInstallation "${EXIT_CODE_UNSUPPORTED_DOWNGRADE}"
  1879. fi
  1880. }
  1881. #== 【3】=检查是否已经安装
  1882. checkIfAlreadyInstalled() {
  1883. if [ -f "${INSTALL_DIR}/uninstall.sh" ] && [ -f "${AGENT_BIN_DIR}/${AGENT_PROC}" ] ; then
  1884. # toConsoleError "Agent already installed. Uninstalling previous version."
  1885. # finishInstallation "${EXIT_CODE_GENERIC_ERROR}"
  1886. checkIfDowngrade
  1887. PARAM_UPGRADE="yes"
  1888. else
  1889. # if [ -f "${SIF_AGENT_INSTALL_PATH}/lib64/${AGENT_BIN}" ]; then
  1890. # sif_toConsoleError "Upgrade is not possible because uninstall script is missing"
  1891. # finishInstallation "${EXIT_CODE_GENERIC_ERROR}"
  1892. # fi
  1893. local fileNum
  1894. fileNum=`ls ${INSTALL_DIR} | wc -l`
  1895. if [ "${fileNum}" -gt 1 ];then
  1896. toConsoleError "${INSTALL_DIR} is not empty. Please clean or change the installation directory manually."
  1897. finishInstallation "${EXIT_CODE_GENERIC_ERROR}"
  1898. fi
  1899. fi
  1900. }
  1901. #**********************************************************
  1902. # Init related functions
  1903. #**********************************************************
  1904. #== clears dependencies in LSB init script
  1905. #== 【5】=清除LSB init脚本中的依赖项
  1906. clearDependenciesInLSBInit() {
  1907. local file="${1}"
  1908. toConsoleInfo "Clearing dependencies in file ${file}"
  1909. awk '
  1910. BEGIN {
  1911. req_start_found=0;
  1912. req_stop_found=0;
  1913. REQ_START="# Required-Start:";
  1914. REQ_STOP="# Required-Stop:";
  1915. PATTERN_REQ_START="^" REQ_START;
  1916. PATTERN_REQ_STOP="^" REQ_STOP;
  1917. }
  1918. {
  1919. if ($0 ~ PATTERN_REQ_START && req_start_found == 0) {
  1920. print REQ_START;
  1921. req_start_found++;
  1922. } else if ($0 ~ PATTERN_REQ_STOP && req_stop_found == 0) {
  1923. print REQ_STOP;
  1924. req_stop_found++;
  1925. } else
  1926. print $0
  1927. }' "${file}" >"${file}.tmp" && mv -f "${file}.tmp" "${file}"
  1928. chmod +x "${file}"
  1929. }
  1930. #== 【5】=指定目录添加自动启动脚本
  1931. addScriptToSystemvAutostart() {
  1932. local prefix="${1}"
  1933. local file="${2}"
  1934. local suffix="${3}"
  1935. toLogInfo "Adding ${file} to autostart"
  1936. #== 自动启动工具
  1937. if ! runAutostartAddingTool "${prefix}" "${file}" "${suffix}"; then
  1938. toLogWarn "Failed to add ${file} script to autostart. Trying without dependencies..."
  1939. #== 清除LSB init脚本中的依赖项
  1940. clearDependenciesInLSBInit "${INIT_DIR}/${file}"
  1941. if ! runAutostartAddingTool "${prefix}" "${file}" "${suffix}"; then
  1942. toConsoleError "Cannot add ${file} to autostart. For details, see: ${LOG_FILE}"
  1943. fi
  1944. fi
  1945. }
  1946. #== 【5】=指定目录添加自动启动脚本
  1947. addScriptsToAutostart() {
  1948. local prefix="${1}"
  1949. local suffix="${2}"
  1950. #== 指定目录添加自动启动脚本
  1951. addScriptToSystemvAutostart "${prefix}" "${SERVICE_SCRIPT_FILE}" "${suffix}"
  1952. }
  1953. #== 【5】=设置自动启动
  1954. #setupSystemvAutostart() {
  1955. # toLogInfo "Adding ${BRAND_AGENT_PRODUCT_NAME} to autostart..."
  1956. #
  1957. # if [ -x /usr/bin/update-rc.d ]; then #Ubuntu
  1958. # #== 指定目录添加自动启动脚本
  1959. # addScriptsToAutostart "/usr/bin/update-rc.d " "defaults"
  1960. # elif [ -x /usr/sbin/update-rc.d ]; then #Ubuntu
  1961. # addScriptsToAutostart "/usr/sbin/update-rc.d " "defaults"
  1962. # elif [ -x /sbin/chkconfig ]; then #RedHat
  1963. # addScriptsToAutostart "/sbin/chkconfig --add "
  1964. # elif [ -x /usr/lib/lsb/install_initd ]; then #Suse
  1965. # addScriptsToAutostart "/usr/lib/lsb/install_initd ${INIT_DIR}/"
  1966. # elif [ "${ARCH_ARCH}"x = "AIX"x ]; then
  1967. # #== 【不存在】
  1968. # arch_setAutostart
  1969. # else
  1970. # toConsoleError "Couldn't add ${BRAND_AGENT_PRODUCT_NAME} to autostart. Please adjust and add it manually."
  1971. # fi
  1972. #}
  1973. #== 【5】=设置 cwserveragent.service 中用户
  1974. setServiceScriptUser() {
  1975. if ! isNonRootModeEnabled; then
  1976. return
  1977. fi
  1978. #== 读取用户名(调用 agent 64位数lib路径(lib64/installaction)执行指令 --get-user)
  1979. local user
  1980. user="$(getValueFromConfigFile "${CONF_FIELD_NM_USER}" "${LEGACY_AGENT_CONF_FILE}" "${BRAND_AGENT_DEFAULT_USER_AND_GROUP_NAME}")"
  1981. #== 修改 cwserveragent.service 中用户信息
  1982. sed -i "s/User=.*/User=${user}/g" "${SYSTEMD_UNIT_FILES_DIR}/${SYSTEMD_UNIT_FILE_AGENT}"
  1983. }
  1984. #== 【5】=配置自动启动 cwserveragent.service
  1985. setupSystemdAutostart() {
  1986. mv -f "${AGENT_SCRIPTS_DIR}/${SYSTEMD_UNIT_FILE_AGENT}" "${SYSTEMD_UNIT_FILES_DIR}/"
  1987. setRightsForFiles "${SYSTEMD_UNIT_FILES_DIR}/${SYSTEMD_UNIT_FILE_AGENT}" 644
  1988. #== 设置 cwserveragent.service 中用户
  1989. setServiceScriptUser
  1990. if isAvailable restorecon; then
  1991. restorecon "${SYSTEMD_UNIT_FILES_DIR}/${SYSTEMD_UNIT_FILE_AGENT}"
  1992. fi
  1993. #== 执行 systemctl 命令配置允许开机启动 cwserveragent.service
  1994. executeSystemctlCommand enable "${SYSTEMD_UNIT_FILE_AGENT}"
  1995. #== 执行 systemctl 命令重新加载模块
  1996. executeSystemctlCommand daemon-reload ""
  1997. }
  1998. #== 【6】=运行service 脚本
  1999. execIntoServiceScript() {
  2000. toConsoleInfo "${SERVICE_SCRIPT_FILE} will be started via exec()"
  2001. #== 清除安装临时文件
  2002. cleanInstallationTemporaryFiles
  2003. toLogInfo "Installation finished, PID $$."
  2004. local command="exec ${AGENT_SCRIPTS_DIR}/${SERVICE_SCRIPT_FILE} exec"
  2005. toLogInfo "Executing: ${command}"
  2006. #== 执行 cwserveragent exec
  2007. ${command}
  2008. toLogError "Could not execute: ${command}"
  2009. finishInstallation "${EXIT_CODE_GENERIC_ERROR}"
  2010. }
  2011. #== 【6】=运行agent
  2012. runAgents() {
  2013. toConsoleInfo "Starting agents..."
  2014. toLogInfo "Using ${INIT_SYSTEM} to start the agent"
  2015. if [ "${INIT_SYSTEM}"x = "${INIT_SYSTEM_SYSV}"x ]; then
  2016. #== 运行初始化命令(通过 service start 方式 或 直接运行可执行命令)
  2017. executeInitScriptCommand start "true"
  2018. else
  2019. #== 执行 systemctl start 命令
  2020. executeSystemctlCommand start "${SYSTEMD_UNIT_FILE_AGENT}"
  2021. fi
  2022. if [ $? -eq 0 ]; then
  2023. toConsoleInfo "${SERVICE_SCRIPT_FILE} service started"
  2024. else
  2025. toConsoleError "Failed to start service: ${SERVICE_SCRIPT_FILE}, it is possible that your init system is not functioning properly. For details, see: ${LOG_FILE}"
  2026. fi
  2027. }
  2028. #== 【5】=配置自动启动
  2029. #setupAutostart() {
  2030. # if [ "${INIT_SYSTEM}"x = "${INIT_SYSTEM_SYSV}"x ]; then
  2031. # #== 设置自动启动
  2032. # setupSystemvAutostart
  2033. # else
  2034. # #== 配置自动启动 cwserveragent.service
  2035. # setupSystemdAutostart
  2036. # fi
  2037. #}
  2038. #**********************************************************
  2039. # Process agent related functions
  2040. #**********************************************************
  2041. #== 【5】=创建 agent 状态文件
  2042. createAgentStateFile() {
  2043. local path="${1}"
  2044. local agentStateContents="RUNNING"
  2045. toLogInfo "Writing ${agentStateContents} to ${path} file"
  2046. {
  2047. printf "%s" "${agentStateContents}" >"${path}.tmp"
  2048. mv -f "${path}.tmp" "${path}"
  2049. } 2>>"${LOG_FILE}"
  2050. }
  2051. #== 【0】=检查全路径是否可读权限(目录最深100层)
  2052. checkIfPathIsGloballyReadable() {
  2053. local path="${1}"
  2054. local sourcePath="${path}"
  2055. local maxDepth=100
  2056. while [ "${path}"x != "/"x ]; do
  2057. #== 【0】=获取文件权限信息
  2058. local accessRights
  2059. accessRights="$(arch_getAccessRights "${path}")"
  2060. if ! printf '%s' "${accessRights}" | cut -c 8-10 | grep -qE "r.[xt]"; then
  2061. toConsoleError "Insufficient access rights (${accessRights}) on: ${path}"
  2062. toConsoleError "${sourcePath} path must be globally readable (r-x permissions for others)."
  2063. toConsoleError "Please adjust the permissions and then retry the installation."
  2064. finishInstallation "${EXIT_CODE_INSUFFICIENT_PERMISSIONS}"
  2065. fi
  2066. path="$(dirname "${path}")"
  2067. maxDepth=$((maxDepth - 1))
  2068. if [ "${maxDepth}" -eq 0 ]; then
  2069. toLogWarn "Unable to verify access rights on ${path}"
  2070. return
  2071. fi
  2072. done
  2073. }
  2074. #== 【0】=创建 PARAM_INSTALL_DIR -> INSTALL_DIR 软连接
  2075. createSymlinkToInstallLocation() {
  2076. #== INSTALL_DIR 不能是软链接地址
  2077. if [ -L "${INSTALL_DIR}" ] && [ ! -e "${INSTALL_DIR}" ]; then
  2078. toConsoleError "Detected that ${INSTALL_DIR} is a dangling symlink, please remove it and then retry the installation"
  2079. finishInstallation "${EXIT_CODE_GENERIC_ERROR}"
  2080. fi
  2081. #== PARAM_INSTALL_DIR 和 INSTALL_DIR 都不能是空地址
  2082. if [ "${PARAM_INSTALL_DIR}"x = "${INSTALL_DIR}"x ] || [ -z "${PARAM_INSTALL_DIR}" ]; then
  2083. return
  2084. fi
  2085. #== INSTALL_DIR 是软连接,并获取 PARAM_INSTALL_DIR 和 INSTALL_DIR 的真实地址
  2086. if [ -L "${INSTALL_DIR}" ] && [ "$(readLink -m "${PARAM_INSTALL_DIR}")"x = "$(readLink -m "${INSTALL_DIR}")"x ]; then
  2087. return
  2088. fi
  2089. #== 目录存在,表示未卸载
  2090. if [ -e "${INSTALL_DIR}" ]; then
  2091. toConsoleError "Leftovers from previous agent installation detected"
  2092. toConsoleError "If you wish to use INSTALL_DIR parameter then perform a cleanup by following these steps:"
  2093. toConsoleError "1. Uninstall the agent"
  2094. toConsoleError "2. Restart all applications that have Deep Monitoring enabled (host restart is fine as well)"
  2095. toConsoleError "3. Remove ${INSTALL_DIR}"
  2096. toConsoleError "and then retry the installation."
  2097. toConsoleError "#DEBUG==For further information please visit ${HELP_URL}/command-line-install"
  2098. finishInstallation "${EXIT_CODE_GENERIC_ERROR}"
  2099. fi
  2100. #== 创建不存在的目录
  2101. createDirIfNotExistAndSetRights "${PARAM_INSTALL_DIR}" 1775
  2102. #== 检查全路径是否可读权限(目录最深100层)
  2103. checkIfPathIsGloballyReadable "${PARAM_INSTALL_DIR}"
  2104. #== 创建不存在的目录 /opt/cloudwise
  2105. createDirIfNotExistAndSetRights "${BASE_INSTALL_DIR}" 755
  2106. #== 创建 PARAM_INSTALL_DIR -> INSTALL_DIR
  2107. local lnOutput
  2108. if lnOutput="$(ln -fs "${PARAM_INSTALL_DIR}" "${INSTALL_DIR}" 2>&1)"; then
  2109. toConsoleInfo "Symlink ${INSTALL_DIR} -> ${PARAM_INSTALL_DIR} created"
  2110. else
  2111. toConsoleError "Failed to create symlink ${INSTALL_DIR} -> ${PARAM_INSTALL_DIR}, aborting installation: ${lnOutput}"
  2112. finishInstallation "${EXIT_CODE_GENERIC_ERROR}"
  2113. fi
  2114. }
  2115. #== 【5】=修改文件系统用户和用户组
  2116. changeFilesOwnership() {
  2117. local user
  2118. local group
  2119. user="$(getValueFromConfigFile "${CONF_FIELD_NM_USER}" "${LEGACY_AGENT_CONF_FILE}" "${BRAND_AGENT_DEFAULT_USER_AND_GROUP_NAME}")"
  2120. group="$(getValueFromConfigFile "${CONF_FIELD_NM_GROUP}" "${LEGACY_AGENT_CONF_FILE}" "${BRAND_AGENT_DEFAULT_USER_AND_GROUP_NAME}")"
  2121. toLogInfo "Changing ownership of files to root:${group}"
  2122. #== /opt/cloudwise/cwserveragent 目录下用户和用户组
  2123. commandErrorWrapper chown "${user}:${group}" "${AGENT_BASE_DIR}"
  2124. commandErrorWrapper chown -R "${user}:${group}" "${INSTALL_DIR}"
  2125. toLogInfo "Recursively changing group ownership of ${AGENT_CONF_DIR} to ${group}"
  2126. }
  2127. #== 【5】=文件用户权限检查
  2128. fileCapabilitiesCompatibilityCheck() {
  2129. #== 获取配置用户
  2130. local user
  2131. user="$(getValueFromConfigFile "${CONF_FIELD_NM_USER}" "${LEGACY_AGENT_CONF_FILE}" "${BRAND_AGENT_DEFAULT_USER_AND_GROUP_NAME}")"
  2132. #== 获取OS bin配置路径 /opt/cloudwise/cwserveragent/lib64/cloudwiseosconfig
  2133. if output="$("$(getOsConfigBinPath)" file-capabilities-compatibility-check "${user}" 2>&1)"; then
  2134. return 0
  2135. fi
  2136. if [ "${PARAM_NON_ROOT_MODE}" ]; then
  2137. toConsoleWarn "Failed to enable non-privileged mode, kernel does not support file capabilities. For details, see: ${LOG_FILE}"
  2138. toLogWarn "Capabilities test output: ${output}"
  2139. else
  2140. toConsoleInfo "Non-privileged mode was not enabled, kernel does not support file capabilities. For details, see: ${LOG_FILE}"
  2141. toLogInfo "Capabilities test output: ${output}"
  2142. fi
  2143. #== 设置删除root权限
  2144. "$(getAgentInstallActionPath)" "--set-drop-root-privileges" "false" >>"${LOG_FILE}" 2>&1
  2145. return 1
  2146. }
  2147. #**********************************************************
  2148. # User and group related functions
  2149. #**********************************************************
  2150. #== 【5】=添加用户组
  2151. addGroup() {
  2152. local group="${1}"
  2153. if groupExistsInSystem "${group}"; then
  2154. toLogInfo "Group '${group}' already exists"
  2155. return 0
  2156. fi
  2157. local errorMessage
  2158. errorMessage="$(groupadd "${group}" 2>&1)"
  2159. local returnCode=$?
  2160. case ${returnCode} in
  2161. 0) toLogInfo "Group '${group}' successfully created" ;;
  2162. 9) toLogInfo "Group '${group}' already exists" ;;
  2163. *)
  2164. toLogError "Error occured while adding '${group}' group, return code: ${returnCode}, message ${errorMessage}"
  2165. return 1
  2166. ;;
  2167. esac
  2168. return 0
  2169. }
  2170. #== 【5】=添加用户
  2171. addUser() {
  2172. local user="${1}"
  2173. local group="${2}"
  2174. local groupCreated="${3}"
  2175. local errorMessage
  2176. local mod="/bin/false"
  2177. if [ "${PARAM_USER_LOGIN}"x == "true"x ]; then
  2178. mod="/bin/bash"
  2179. fi
  2180. if userExistsInSystem "${user}"; then
  2181. toLogInfo "User '${user}' already exists."
  2182. #-- 权限更新
  2183. # errorMessage="$(usermod -s "${mod}" "${user}" 2>&1)"
  2184. return 0
  2185. fi
  2186. if [ "${groupCreated}" -eq 0 ]; then
  2187. errorMessage="$(useradd -r --shell "${mod}" -g "${group}" "${user}" 2>&1)"
  2188. else
  2189. errorMessage="$(useradd -r --shell "${mod}" "${user}" 2>&1)"
  2190. fi
  2191. local returnCode=$?
  2192. if [ ${returnCode} -ne 0 ]; then
  2193. toConsoleError "Failed to create user '${user}'"
  2194. toLogError "Error occured while adding '${user}' user, return value: ${returnCode}, error message: ${errorMessage}."
  2195. return 1
  2196. fi
  2197. toConsoleInfo "User '${user}' added successfully."
  2198. return 0
  2199. }
  2200. #== 【5】=添加用户和用户组信息
  2201. addUserAndGroup() {
  2202. local user="${1}"
  2203. local group="${2}"
  2204. #== 添加用户组
  2205. addGroup "${group}"
  2206. #== 添加用户
  2207. addUser "${user}" "${group}" $?
  2208. }
  2209. #== 【5】=配置用户和用户组
  2210. handleUser() {
  2211. toLogInfo "Processing user and group..."
  2212. local user
  2213. local group
  2214. #== 读取用户名(调用 agent 64位数lib路径(lib64/installaction)执行指令 --get-user)
  2215. user="$(getValueFromConfigFile "${CONF_FIELD_NM_USER}" "${LEGACY_AGENT_CONF_FILE}" "${BRAND_AGENT_DEFAULT_USER_AND_GROUP_NAME}")"
  2216. #== 读取用户组(调用 agent 64位数lib路径(lib64/installaction)执行指令 --get-group)
  2217. group="$(getValueFromConfigFile "${CONF_FIELD_NM_GROUP}" "${LEGACY_AGENT_CONF_FILE}" "${BRAND_AGENT_DEFAULT_USER_AND_GROUP_NAME}")"
  2218. #== 添加用户和用户组信息
  2219. addUserAndGroup "${user}" "${group}"
  2220. }
  2221. #== 【4】=获取agent preLoad 安装路径,并校验是否可执行
  2222. checkCompatibilityWithInstallActionBinary() {
  2223. local output
  2224. #== 获取agent preLoad 安装路径,并校验是否可执行
  2225. output="$("$(getAgentInstallActionPathPreInstallation)" "--sanity-check" 2>&1)"
  2226. local exitCode=$?
  2227. toLogAdaptive ${exitCode} "Compatibility check exit code = ${exitCode}, output = ${output}"
  2228. if [ ${exitCode} -ne 0 ] || [ "${output}"x != "SUCCESS"x ]; then
  2229. toConsoleError "System compatibility check failed, this may be caused by a problem with glibc, dynamic loader or incompatible operating system version."
  2230. toConsoleError "Detected version: $(detectLinuxDistribution)"
  2231. toConsoleError "For a list of supported distributions and versions, see: ${HELP_URL}"
  2232. finishInstallation "${EXIT_CODE_GENERIC_ERROR}"
  2233. fi
  2234. }
  2235. #== 【4】=【部署】解压文件
  2236. extractFiles() {
  2237. umask 000
  2238. toConsoleInfo "Extracting..."
  2239. #== 从sh文件读取压缩文件 tarfile_$$.base64
  2240. separateExternalTar
  2241. #== 解压文件(1、通过base64转码后,执行tar解压;2、通过xzdec解压xz文件后在执行tar解压)
  2242. unpackArchive
  2243. umask 022
  2244. }
  2245. #== 【3】=检查发现初始化系统信息(INIT_SYSTEM、INIT_SYSTEM_VERSION、INIT_DIR)
  2246. detectInitSystem() {
  2247. #== 获取初始化系统信息 (INIT_SYSTEM、INIT_SYSTEM_VERSION)
  2248. checkInitSystem
  2249. toLogInfo "Detected init system: ${INIT_SYSTEM}, version: ${INIT_SYSTEM_VERSION}"
  2250. #== 设置系统初始化脚本目录
  2251. if ! setLocationOfScripts; then
  2252. toConsoleError "Cannot determine location of init scripts."
  2253. finishInstallation "${EXIT_CODE_GENERIC_ERROR}"
  2254. fi
  2255. }
  2256. #== 【4】=【旧配置】读取旧配置参数
  2257. readLegacySetting() {
  2258. local paramName="${1}"
  2259. local value
  2260. value="$(sed -n "s|^${paramName}=||p" "${LEGACY_AGENT_CONF_FILE}" | tr -d '\r' 2>/dev/null)"
  2261. if [ "${value}" ]; then
  2262. local valueToPrint="${value}"
  2263. if [ "${paramName}"x = "${CONF_FIELD_NM_LICENSE}"x ]; then
  2264. valueToPrint="***"
  2265. fi
  2266. toLogInfo "Read legacy value: ${paramName} = ${valueToPrint}"
  2267. fi
  2268. printf '%s' "${value}"
  2269. }
  2270. #== 【4】=【旧配置】迁移旧配置文件
  2271. migrateLegacySettingsFromAgentConf() {
  2272. toLogInfo "Looking for legacy config to migrate."
  2273. #== 旧配置文件
  2274. if [ ! -f "${LEGACY_AGENT_CONF_FILE}" ]; then
  2275. toLogInfo "Unable to read agent config file, skipping legacy config migration"
  2276. return
  2277. fi
  2278. if [ ! "${PARAM_CONFIG_SERVER}" ]; then
  2279. local configServerValue
  2280. configServerValue="$(readLegacySetting ${CONF_FIELD_NM_CONFIG_SERVER})"
  2281. toConsoleInfo "#DEBUG== legacy config: ${CONF_FIELD_NM_CONFIG_SERVER}: ${PARAM_CONFIG_SERVER}"
  2282. if [ "${configServerValue}"x = "http://localhost:8020"x ]; then
  2283. toLogInfo "Param 'server' has default value set, skipping it"
  2284. else
  2285. PARAM_CONFIG_SERVER="${configServerValue}"
  2286. fi
  2287. fi
  2288. if [ ! "${PARAM_DATA_SERVER}" ]; then
  2289. PARAM_DATA_SERVER="$(readLegacySetting ${CONF_FIELD_NM_DATA_SERVER})"
  2290. toConsoleInfo "#DEBUG== legacy config: ${CONF_FIELD_NM_DATA_SERVER}: ${PARAM_DATA_SERVER}"
  2291. fi
  2292. if [ ! "${PARAM_LICENSE}" ]; then
  2293. PARAM_LICENSE="$(readLegacySetting ${CONF_FIELD_NM_LICENSE})"
  2294. toConsoleInfo "#DEBUG== legacy config: ${CONF_FIELD_NM_LICENSE}: ${PARAM_LICENSE}"
  2295. fi
  2296. if [ ! "${PARAM_JSON_CONF}" ]; then
  2297. PARAM_JSON_CONF="$(readLegacySetting ${CONF_FIELD_NM_JSON_CONF})"
  2298. toConsoleInfo "#DEBUG== legacy config: ${CONF_FIELD_NM_JSON_CONF}: ${PARAM_JSON_CONF}"
  2299. fi
  2300. if [ ! "${PARAM_USER}" ]; then
  2301. PARAM_USER="$(readLegacySetting ${CONF_FIELD_NM_USER})"
  2302. toConsoleInfo "#DEBUG== legacy config: ${CONF_FIELD_NM_USER}: ${PARAM_USER}"
  2303. if [ ! "${PARAM_GROUP}" ]; then
  2304. PARAM_GROUP="$(readLegacySetting ${CONF_FIELD_NM_GROUP})"
  2305. toConsoleInfo "#DEBUG== legacy config: ${CONF_FIELD_NM_GROUP}: ${PARAM_GROUP}"
  2306. fi
  2307. fi
  2308. }
  2309. listProcesses() {
  2310. local errorMessage="${1}"
  2311. local includeRegex="${2}"
  2312. local excludeRegex=" grep"
  2313. if [ "${3}" ]; then
  2314. excludeRegex="grep|${3}"
  2315. fi
  2316. toLogInfo "#DEBUG== listProcesses command: ps -e -o \"pid,args\" 2>&1 | grep -E \"${includeRegex}\" | awk '{{ print \$1,\$2 }}' | grep -vE \"${excludeRegex}\""
  2317. local output
  2318. if ! output="$(pgrep -f "pid,args" 2>&1 | grep -E "${includeRegex}" | awk '{{ print $1,$2 }}')"; then
  2319. toLogError "Failed to get ${errorMessage}, output: ${output}"
  2320. return 1
  2321. fi
  2322. local foundProcesses
  2323. foundProcesses="$(printf '%s' "${output}" | grep -vE "${excludeRegex}")"
  2324. if [ ! "${foundProcesses}" ]; then
  2325. return 1
  2326. fi
  2327. printf '%s' "${foundProcesses}" | awk '{{ print $1 }}'
  2328. return 0
  2329. }
  2330. #== 版本&帮助信息
  2331. preParams() {
  2332. if [ $# -gt 0 ]; then
  2333. if [ "${1}"x = "-h"x ] || [ "${1}"x = "--help"x ]; then
  2334. displayHelp
  2335. exit "${EXIT_CODE_OK}"
  2336. fi
  2337. if [ "${1}"x = "-v"x ] || [ "${1}"x = "--version"x ]; then
  2338. pad=20
  2339. printf "%-${pad}s%s\n" "Version:" "${AGENT_INSTALLER_VERSION}"
  2340. printf "%-${pad}s%s\n" "Commit:" "${AGENT_BUILD_TAG}"
  2341. printf "%-${pad}s%s\n" "Build At(UTC):" "${AGENT_BUILD_DATE_INFO}"
  2342. printf "%-${pad}s%s\n" "Uploader:" "${AGENT_BUILD_UPLOADER}"
  2343. exit "${EXIT_CODE_OK}"
  2344. fi
  2345. fi
  2346. }
  2347. #**********************************************************
  2348. # Main script functions
  2349. #**********************************************************
  2350. #== 【0】=初始化安装环境
  2351. initializeInstallation() {
  2352. preParams "$@"
  2353. #== 设置PATH
  2354. setPATH
  2355. #== 配置umask权限
  2356. local initialUmask
  2357. initialUmask="$(umask)"
  2358. umask 022
  2359. #== 读取配置参数
  2360. # readParamsSection
  2361. #== 解析命令行参数
  2362. parseCommandLineParameters "$@"
  2363. #== 校验配置参数
  2364. #== 是否存在多个同时安装操作【通过判断 INSTALLER_LOCK_FILE 】
  2365. if isAnotherInstallationRunning; then
  2366. #== 结束安装操作
  2367. finishInstallation "${EXIT_CODE_ANOTHER_INSTALLER_RUNNING}" "keep_lock_file"
  2368. fi
  2369. #== 创建安装标示文件 /tmp/${BRAND_PRODUCT_NAME_LOWER}.lock
  2370. createInstallationLockFile
  2371. #== 配置是否更新
  2372. PARAM_UPGRADE="no"
  2373. #== 获取并校验系统兼容性【LINUX/AIX X86_64/IA64】
  2374. local platformDetectionString
  2375. if ! platformDetectionString="$(checkSystemCompatibility)"; then
  2376. toConsoleError "${platformDetectionString}"
  2377. finishInstallation "${EXIT_CODE_OS_NOT_SUPPORTED}"
  2378. fi
  2379. #== 创建 PARAM_INSTALL_DIR -> INSTALL_DIR 软连接
  2380. createSymlinkToInstallLocation
  2381. #== 创建日志目录及日志文件installation_$$.log
  2382. createLogDirsIfMissing
  2383. #== 配置信号捕获,执行清空安装临时目录
  2384. configureSignalHandling "cleanInstallationTemporaryFiles"
  2385. #== 常规日志
  2386. initializeLog "${@}"
  2387. toLogInfo "Initial umask: ${initialUmask}"
  2388. toConsoleInfo "${platformDetectionString}"
  2389. toLogInfo "Distribution: $(detectLinuxDistribution)"
  2390. }
  2391. #== 【3】=安装前检查
  2392. preInstallationChecks() {
  2393. #== 检查发现初始化系统信息(INIT_SYSTEM、INIT_SYSTEM_VERSION、INIT_DIR)
  2394. detectInitSystem
  2395. #== 检查目录权限
  2396. checkAccessRightsToDirs
  2397. #== 创建临时目录
  2398. prepareTempFolder
  2399. #== 检查是否已经安装
  2400. checkIfAlreadyInstalled
  2401. if [ ! "${PARAM_USER}" ] && [ "${ARCH_ARCH}"x != "AIX"x ] ; then
  2402. #== 配置文件中配置用户和用户组是否存在
  2403. checkUserAndGroupFromConfig
  2404. fi
  2405. #== 检查安装目录空间
  2406. checkInstallPathFreeSpace
  2407. }
  2408. uninstallAgent() {
  2409. toConsoleInfo "Agent already installed. Uninstalling previous version."
  2410. # printf '%s' "upgrade" >"${UNINSTALL_INFO_FILE_LEGACY_PATH}"
  2411. #shellcheck disable=SC2086
  2412. "${INSTALL_DIR}/uninstall.sh" $$ ${SKIP_PRIVILEGES_CHECK} 2>>"${LOG_FILE}"
  2413. local uninstallExitCode=$?
  2414. if [ ${uninstallExitCode} -gt 0 ]; then
  2415. toConsoleError "Error during uninstalling, code: ${uninstallExitCode}. Installation aborted."
  2416. finishInstallation "${EXIT_CODE_GENERIC_ERROR}"
  2417. fi
  2418. toConsoleInfo "Agent uninstalled."
  2419. }
  2420. #== 【4】=部署文件
  2421. deployFiles() {
  2422. if [ "${PARAM_UPGRADE}" = "yes" ]; then
  2423. uninstallAgent
  2424. fi
  2425. #== 【部署】解压文件
  2426. extractFiles
  2427. setupAll
  2428. createCurrentVersionSymlink
  2429. }
  2430. #== 【5】=配置安装
  2431. configureInstallation() {
  2432. #== 配置参数(param、installation.conf)
  2433. #== 自定义修改配置, sed ,echo ... 参考 applyAgentSettings
  2434. if [ "${PARAM_TEST}" ]; then
  2435. toConsoleOnly "Applying test value is: ${PARAM_TEST}"
  2436. fi
  2437. #== 获取bool值参数
  2438. if [ "${PARAM_BOOL}" ]; then
  2439. toConsoleOnly "Applying bool value is: ${PARAM_BOOL}"
  2440. fi
  2441. if [ "${ARCH_ARCH}"x != "AIX"x ]; then
  2442. #== 配置用户和用户组
  2443. if handleUser; then
  2444. #== 修改文件系统用户和用户组
  2445. changeFilesOwnership
  2446. fi
  2447. #== 设置root权限
  2448. fi
  2449. #== 系统配置(策略配置、dump proc、agent 进程配置、自动启动)
  2450. # setupAutostart
  2451. }
  2452. #== 【6】=验证安装状态、运行启动脚本
  2453. postInstallationSteps() {
  2454. #== 运行agent
  2455. # runAgents
  2456. finishInstallation "${EXIT_CODE_OK}"
  2457. }
  2458. readonly CURR_PATH="$(pwd)"
  2459. main() {
  2460. #== 【0】=初始化安装环境
  2461. initializeInstallation "$@"
  2462. #== 【3】=安装前检查
  2463. preInstallationChecks
  2464. #== 【4】=部署文件
  2465. deployFiles
  2466. #== 【5】=配置安装
  2467. configureInstallation
  2468. #== 【6】=验证安装状态、运行启动脚本
  2469. postInstallationSteps
  2470. }
  2471. #**********************************************************
  2472. # Script start
  2473. #**********************************************************
  2474. main "$@"
  2475. ################################################
  2476. ############# DO NOT REMOVE THIS ###############
  2477. #### DO NOT ADD ANYTHING BELOW THIS COMMENT ####
  2478. ################################################
  2479. #################ENDOFSCRIPTMARK################
  2480. ----SIGNED-INSTALLER