netdata-updater.sh 41 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333
  1. #!/bin/sh
  2. # SPDX-License-Identifier: GPL-3.0-or-later
  3. #
  4. # Netdata updater utility
  5. #
  6. # Variables needed by script:
  7. # - PATH
  8. # - CFLAGS
  9. # - LDFLAGS
  10. # - MAKEOPTS
  11. # - IS_NETDATA_STATIC_BINARY
  12. # - NETDATA_CONFIGURE_OPTIONS
  13. # - REINSTALL_OPTIONS
  14. # - NETDATA_TARBALL_URL
  15. # - NETDATA_TARBALL_CHECKSUM_URL
  16. # - NETDATA_TARBALL_CHECKSUM
  17. # - NETDATA_PREFIX
  18. # - NETDATA_LIB_DIR
  19. #
  20. # Optional environment options:
  21. #
  22. # - TMPDIR (set to a usable temporary directory)
  23. # - NETDATA_NIGHTLIES_BASEURL (set the base url for downloading the dist tarball)
  24. # Next unused error code: U001D
  25. set -e
  26. PACKAGES_SCRIPT="https://raw.githubusercontent.com/netdata/netdata/master/packaging/installer/install-required-packages.sh"
  27. NETDATA_STABLE_BASE_URL="${NETDATA_BASE_URL:-https://github.com/netdata/netdata/releases}"
  28. NETDATA_NIGHTLY_BASE_URL="${NETDATA_BASE_URL:-https://github.com/netdata/netdata-nightlies/releases}"
  29. NETDATA_DEFAULT_ACCEPT_MAJOR_VERSIONS="1 2"
  30. # Following variables are intended to be overridden by the updater config file.
  31. NETDATA_UPDATER_JITTER=3600
  32. NETDATA_NO_SYSTEMD_JOURNAL=0
  33. NETDATA_ACCEPT_MAJOR_VERSIONS=''
  34. script_dir="$(CDPATH='' cd -- "$(dirname -- "$0")" && pwd -P)"
  35. if [ -x "${script_dir}/netdata-updater" ]; then
  36. script_source="${script_dir}/netdata-updater"
  37. else
  38. script_source="${script_dir}/netdata-updater.sh"
  39. fi
  40. PATH="${PATH}:/usr/local/bin:/usr/local/sbin"
  41. if [ ! -t 1 ]; then
  42. INTERACTIVE=0
  43. else
  44. INTERACTIVE=1
  45. fi
  46. if [ -n "${script_source}" ]; then
  47. script_name="$(basename "${script_source}")"
  48. else
  49. script_name="netdata-updater.sh"
  50. fi
  51. info() {
  52. echo >&3 "$(date) : INFO: ${script_name}: " "${1}"
  53. }
  54. warning() {
  55. echo >&3 "$(date) : WARNING: ${script_name}: " "${@}"
  56. }
  57. error() {
  58. echo >&3 "$(date) : ERROR: ${script_name}: " "${1}"
  59. if [ -n "${NETDATA_SAVE_WARNINGS}" ]; then
  60. NETDATA_WARNINGS="${NETDATA_WARNINGS}\n - ${1}"
  61. fi
  62. }
  63. fatal() {
  64. echo >&3 "$(date) : FATAL: ${script_name}: FAILED TO UPDATE NETDATA: " "${1}"
  65. if [ -n "${NETDATA_SAVE_WARNINGS}" ]; then
  66. NETDATA_WARNINGS="${NETDATA_WARNINGS}\n - ${1}"
  67. fi
  68. exit_reason "${1}" "${2}"
  69. exit 1
  70. }
  71. exit_reason() {
  72. if [ -n "${NETDATA_SAVE_WARNINGS}" ]; then
  73. EXIT_REASON="${1}"
  74. EXIT_CODE="${2}"
  75. if [ -n "${NETDATA_PROPAGATE_WARNINGS}" ]; then
  76. if [ -n "${NETDATA_SCRIPT_STATUS_PATH}" ]; then
  77. {
  78. echo "EXIT_REASON=\"${EXIT_REASON}\""
  79. echo "EXIT_CODE=\"${EXIT_CODE}\""
  80. echo "NETDATA_WARNINGS=\"${NETDATA_WARNINGS}\""
  81. } >> "${NETDATA_SCRIPT_STATUS_PATH}"
  82. else
  83. export EXIT_REASON
  84. export EXIT_CODE
  85. export NETDATA_WARNINGS
  86. fi
  87. fi
  88. fi
  89. }
  90. is_integer () {
  91. case "${1#[+-]}" in
  92. *[!0123456789]*) return 1 ;;
  93. '') return 1 ;;
  94. *) return 0 ;;
  95. esac
  96. }
  97. safe_pidof() {
  98. pidof_cmd="$(command -v pidof 2> /dev/null)"
  99. if [ -n "${pidof_cmd}" ]; then
  100. ${pidof_cmd} "${@}"
  101. return $?
  102. else
  103. ps -acxo pid,comm |
  104. sed "s/^ *//g" |
  105. grep netdata |
  106. cut -d ' ' -f 1
  107. return $?
  108. fi
  109. }
  110. issystemd() {
  111. # if there is no systemctl command, it is not systemd
  112. systemctl=$(command -v systemctl 2> /dev/null)
  113. if [ -z "${systemctl}" ] || [ ! -x "${systemctl}" ]; then
  114. return 1
  115. fi
  116. # Check the output of systemctl is-system-running.
  117. # If this reports 'offline', it’s not systemd. If it reports 'unknown'
  118. # or nothing at all (which indicates the command is not supported), it
  119. # may or may not be systemd, so continue to other checks. If it reports
  120. # anything else, it is systemd.
  121. #
  122. # This may return a non-zero exit status in cases when it actually
  123. # succeeded for our purposes (notably, if the state is `degraded`),
  124. # so we need to toggle set -e off here.
  125. set +e
  126. systemd_state="$(systemctl is-system-running)"
  127. set -e
  128. case "${systemd_state}" in
  129. offline) return 1 ;;
  130. unknown) : ;;
  131. "") : ;;
  132. *) return 0 ;;
  133. esac
  134. # if pid 1 is systemd, it is systemd
  135. [ "$(basename "$(readlink /proc/1/exe)" 2> /dev/null)" = "systemd" ] && return 0
  136. # if systemd is not running, it is not systemd
  137. pids=$(safe_pidof systemd 2> /dev/null)
  138. [ -z "${pids}" ] && return 1
  139. # check if the running systemd processes are not in our namespace
  140. myns="$(readlink /proc/self/ns/pid 2> /dev/null)"
  141. for p in ${pids}; do
  142. ns="$(readlink "/proc/${p}/ns/pid" 2> /dev/null)"
  143. # if pid of systemd is in our namespace, it is systemd
  144. [ -n "${myns}" ] && [ "${myns}" = "${ns}" ] && return 0
  145. done
  146. # else, it is not systemd
  147. return 1
  148. }
  149. systemd_unit_exists() {
  150. if systemctl list-unit-files "${1}" 2>&1 | tail -n 1 | grep -qv '^0 '; then
  151. return 0
  152. else
  153. return 1
  154. fi
  155. }
  156. # shellcheck disable=SC2009
  157. running_under_anacron() {
  158. pid="${1:-$$}"
  159. iter="${2:-0}"
  160. [ "${iter}" -gt 50 ] && return 1
  161. if [ "$(uname -s)" = "Linux" ] && [ -r "/proc/${pid}/stat" ]; then
  162. ppid="$(cut -f 4 -d ' ' "/proc/${pid}/stat")"
  163. if [ -n "${ppid}" ]; then
  164. # The below case accounts for the hidepid mount option for procfs, as well as setups with LSM
  165. [ ! -r "/proc/${ppid}/comm" ] && return 1
  166. [ "${ppid}" -eq "${pid}" ] && return 1
  167. grep -q anacron "/proc/${ppid}/comm" && return 0
  168. running_under_anacron "${ppid}" "$((iter + 1))"
  169. return "$?"
  170. fi
  171. else
  172. ppid="$(ps -o pid= -o ppid= 2>/dev/null | grep -e "^ *${pid}" | xargs | cut -f 2 -d ' ')"
  173. if [ -n "${ppid}" ]; then
  174. [ "${ppid}" -eq "${pid}" ] && return 1
  175. ps -o pid= -o command= 2>/dev/null | grep -e "^ *${ppid}" | grep -q anacron && return 0
  176. running_under_anacron "${ppid}" "$((iter + 1))"
  177. return "$?"
  178. fi
  179. fi
  180. return 1
  181. }
  182. _get_intervaldir() {
  183. if [ -d /etc/cron.daily ]; then
  184. echo /etc/cron.daily
  185. elif [ -d /etc/periodic/daily ]; then
  186. echo /etc/periodic/daily
  187. else
  188. return 1
  189. fi
  190. return 0
  191. }
  192. _get_scheduler_type() {
  193. if _get_intervaldir > /dev/null ; then
  194. echo 'interval'
  195. elif issystemd ; then
  196. echo 'systemd'
  197. elif [ -d /etc/cron.d ] ; then
  198. echo 'crontab'
  199. else
  200. echo 'none'
  201. fi
  202. }
  203. confirm() {
  204. prompt="${1} [y/n]"
  205. while true; do
  206. echo "${prompt}"
  207. read -r yn
  208. case "$yn" in
  209. [Yy]*) return 0;;
  210. [Nn]*) return 1;;
  211. *) echo "Please answer yes or no.";;
  212. esac
  213. done
  214. }
  215. warn_major_update() {
  216. nmv_suffix="New major versions generally involve breaking changes, and may not work in the same way as older versions."
  217. if [ "${INTERACTIVE}" -eq 0 ]; then
  218. warning "Would update to a new major version of Netdata. ${nmv_suffix}"
  219. warning "To install the new major version anyway, either run the updater interactively, or include the new major version number in the NETDATA_ACCEPT_MAJOR_VERSIONS variable in ${UPDATER_CONFIG_PATH}."
  220. fatal "Aborting update to new major version to avoid breaking things." U001B
  221. else
  222. warning "This update will install a new major version of Netdata. ${nmv_suffix}"
  223. if confirm "Are you sure you want to update to a new major version of Netdata?"; then
  224. notice "User accepted update to new major version of Netdata."
  225. else
  226. fatal "Aborting update to new major version at user request." U001C
  227. fi
  228. fi
  229. }
  230. install_build_dependencies() {
  231. bash="$(command -v bash 2> /dev/null)"
  232. if [ -z "${bash}" ] || [ ! -x "${bash}" ]; then
  233. error "Unable to find a usable version of \`bash\` (required for local build)."
  234. return 1
  235. fi
  236. info "Fetching dependency handling script..."
  237. download "${PACKAGES_SCRIPT}" "./install-required-packages.sh" || true
  238. if [ ! -s "./install-required-packages.sh" ]; then
  239. error "Downloaded dependency installation script is empty."
  240. else
  241. info "Running dependency handling script..."
  242. opts="--dont-wait --non-interactive"
  243. # shellcheck disable=SC2086
  244. if ! "${bash}" "./install-required-packages.sh" ${opts} netdata >&3 2>&3; then
  245. error "Installing build dependencies failed. The update should still work, but you might be missing some features."
  246. fi
  247. fi
  248. }
  249. enable_netdata_updater() {
  250. updater_type="$(echo "${1}" | tr '[:upper:]' '[:lower:]')"
  251. case "${updater_type}" in
  252. systemd|interval|crontab)
  253. updater_type="${1}"
  254. ;;
  255. "")
  256. updater_type="$(_get_scheduler_type)"
  257. ;;
  258. *)
  259. fatal "Unrecognized updater type ${updater_type} requested. Supported types are 'systemd', 'interval', and 'crontab'." U0001
  260. ;;
  261. esac
  262. case "${updater_type}" in
  263. "systemd")
  264. if issystemd; then
  265. if systemd_unit_exists netdata-updater.timer; then
  266. systemctl enable netdata-updater.timer
  267. systemctl start netdata-updater.timer
  268. info "Auto-updating has been ENABLED using a systemd timer unit.\n"
  269. info "If the update process fails, the failure will be logged to the systemd journal just like a regular service failure."
  270. info "Successful updates should produce empty logs."
  271. else
  272. error "Systemd-based auto-update scheduling requested, but the required timer unit does not exist. Auto-updates have NOT been enabled."
  273. return 1
  274. fi
  275. else
  276. error "Systemd-based auto-update scheduling requested, but this does not appear to be a systemd system. Auto-updates have NOT been enabled."
  277. return 1
  278. fi
  279. ;;
  280. "interval")
  281. if _get_intervaldir > /dev/null; then
  282. ln -sf "${NETDATA_PREFIX}/usr/libexec/netdata/netdata-updater.sh" "$(_get_intervaldir)/netdata-updater"
  283. info "Auto-updating has been ENABLED through cron, updater script linked to $(_get_intervaldir)/netdata-updater\n"
  284. info "If the update process fails and you have email notifications set up correctly for cron on this system, you should receive an email notification of the failure."
  285. info "Successful updates will not send an email."
  286. else
  287. error "Interval-based auto-update scheduling requested, but I could not find an interval scheduling directory. Auto-updates have NOT been enabled."
  288. return 1
  289. fi
  290. ;;
  291. "crontab")
  292. if [ -d "/etc/cron.d" ]; then
  293. [ -f "/etc/cron.d/netdata-updater" ] && rm -f "/etc/cron.d/netdata-updater"
  294. install -p -m 0644 -o 0 -g 0 "${NETDATA_PREFIX}/usr/lib/system/cron/netdata-updater-daily" "/etc/cron.d/netdata-updater-daily"
  295. info "Auto-updating has been ENABLED through cron, using a crontab at /etc/cron.d/netdata-updater\n"
  296. info "If the update process fails and you have email notifications set up correctly for cron on this system, you should receive an email notification of the failure."
  297. info "Successful updates will not send an email."
  298. else
  299. error "Crontab-based auto-update scheduling requested, but there is no '/etc/cron.d'. Auto-updates have NOT been enabled."
  300. return 1
  301. fi
  302. ;;
  303. *)
  304. error "Unable to determine what type of auto-update scheduling to use. Auto-updates have NOT been enabled."
  305. return 1
  306. esac
  307. return 0
  308. }
  309. disable_netdata_updater() {
  310. if issystemd && systemd_unit_exists "netdata-updater.timer" ; then
  311. systemctl disable netdata-updater.timer
  312. systemctl stop netdata-updater.timer
  313. fi
  314. if [ -d /etc/cron.daily ]; then
  315. rm -f /etc/cron.daily/netdata-updater.sh
  316. rm -f /etc/cron.daily/netdata-updater
  317. fi
  318. if [ -d /etc/periodic/daily ]; then
  319. rm -f /etc/periodic/daily/netdata-updater.sh
  320. rm -f /etc/periodic/daily/netdata-updater
  321. fi
  322. if [ -d /etc/cron.d ]; then
  323. rm -f /etc/cron.d/netdata-updater
  324. rm -f /etc/cron.d/netdata-updater-daily
  325. fi
  326. info "Auto-updates have been DISABLED."
  327. return 0
  328. }
  329. auto_update_status() {
  330. case "$(_get_scheduler_type)" in
  331. systemd) info "The default auto-update scheduling method for this system is: systemd timer units" ;;
  332. crontab) info "The default auto-update scheduling method for this system is: drop-in crontab" ;;
  333. interval) info "The default auto-update scheduling method for this system is: drop-in periodic script" ;;
  334. *) info "No recognized auto-update scheduling method found" ; return ;;
  335. esac
  336. duplicate=""
  337. enabled=""
  338. if issystemd; then
  339. if systemd_unit_exists "netdata-updater.timer"; then
  340. if systemctl is-enabled netdata-updater.timer; then
  341. info "Auto-updates using a systemd timer unit are ENABLED"
  342. enabled="systemd"
  343. else
  344. info "Auto-updates using a systemd timer unit are DISABLED"
  345. fi
  346. else
  347. info "Auto-updates using a systemd timer unit are NOT SUPPORTED due to: Required unit files not installed"
  348. fi
  349. else
  350. info "Auto-updates using a systemd timer unit are NOT SUPPORTED due to: Systemd not present"
  351. fi
  352. interval_found=""
  353. if [ -d /etc/cron.daily ]; then
  354. interval_found="1"
  355. if [ -x /etc/cron.daily/netdata-updater.sh ] || [ -x /etc/cron.daily/netdata-updater ]; then
  356. info "Auto-updates using a drop-in periodic script in /etc/cron.daily are ENABLED"
  357. if [ -n "${enabled}" ]; then
  358. duplicate="1"
  359. else
  360. enabled="cron.daily"
  361. fi
  362. else
  363. info "Auto-updates using a drop-in periodic script in /etc/cron.daily are DISABLED"
  364. fi
  365. else
  366. info "Auto-updates using a drop-in periodic script in /etc/cron.daily are NOT SUPPORTED: due to: Directory does not exist"
  367. fi
  368. if [ -d /etc/periodic/daily ]; then
  369. if [ -x /etc/periodic/daily/netdata-updater.sh ] || [ -x /etc/periodic/daily/netdata-updater ]; then
  370. info "Auto-updates using a drop-in periodic script in /etc/periodic/daily are ENABLED"
  371. if [ -n "${enabled}" ]; then
  372. duplicate="1"
  373. else
  374. enabled="periodic/daily"
  375. fi
  376. else
  377. if [ -z "${interval_found}" ]; then
  378. info "Auto-updates using a drop-in periodic script in /etc/periodic/daily are DISABLED"
  379. fi
  380. fi
  381. elif [ -z "${interval_found}" ]; then
  382. info "Auto-updates using a drop-in periodic script in /etc/periodic/daily are NOT SUPPORTED due to: Directory does not exist"
  383. fi
  384. if [ -d /etc/cron.d ]; then
  385. if [ -f /etc/cron.d/netdata-updater ] || [ -f /etc/cron.d/netdata-updater-daily ]; then
  386. info "Auto-updates using a drop-in crontab are ENABLED"
  387. if [ -n "${enabled}" ]; then
  388. duplicate="1"
  389. else
  390. enabled="cron.d"
  391. fi
  392. else
  393. info "Auto-updates using a drop-in crontab are DISABLED"
  394. fi
  395. else
  396. info "Auto-updates using a drop-in crontab are NOT SUPPORTED due to: Directory does not exist"
  397. fi
  398. if [ -n "${duplicate}" ]; then
  399. warning "More than one method of auto-updates is enabled! Please disable and re-enable auto-updates to correct this."
  400. fi
  401. }
  402. str_in_list() {
  403. printf "%s\n" "${2}" | tr ' ' "\n" | grep -qE "^${1}\$"
  404. return $?
  405. }
  406. safe_sha256sum() {
  407. # Within the context of the installer, we only use -c option that is common between the two commands
  408. # We will have to reconsider if we start non-common options
  409. if command -v shasum > /dev/null 2>&1; then
  410. shasum -a 256 "$@"
  411. elif command -v sha256sum > /dev/null 2>&1; then
  412. sha256sum "$@"
  413. else
  414. fatal "I could not find a suitable checksum binary to use" U0002
  415. fi
  416. }
  417. cleanup() {
  418. if [ -n "${logfile}" ]; then
  419. cat >&2 "${logfile}"
  420. rm "${logfile}"
  421. fi
  422. if [ -n "$ndtmpdir" ] && [ -d "$ndtmpdir" ]; then
  423. rm -rf "$ndtmpdir"
  424. fi
  425. }
  426. _cannot_use_tmpdir() {
  427. testfile="$(TMPDIR="${1}" mktemp -q -t netdata-test.XXXXXXXXXX)"
  428. ret=0
  429. if [ -z "${testfile}" ] ; then
  430. return "${ret}"
  431. fi
  432. if printf '#!/bin/sh\necho SUCCESS\n' > "${testfile}" ; then
  433. if chmod +x "${testfile}" ; then
  434. if [ "$("${testfile}" 2>/dev/null)" = "SUCCESS" ] ; then
  435. ret=1
  436. fi
  437. fi
  438. fi
  439. rm -f "${testfile}"
  440. return "${ret}"
  441. }
  442. create_exec_tmp_directory() {
  443. if [ -n "${NETDATA_TMPDIR_PATH}" ]; then
  444. echo "${NETDATA_TMPDIR_PATH}"
  445. return
  446. fi
  447. root_dir=""
  448. if [ -n "${NETDATA_TMPDIR}" ] && ! _cannot_use_tmpdir "${NETDATA_TMPDIR}"; then
  449. root_dir="${NETDATA_TMPDIR}"
  450. elif [ -n "${TMPDIR}" ] && ! _cannot_use_tmpdir "${TMPDIR}"; then
  451. root_dir="${TMPDIR}"
  452. elif ! _cannot_use_tmpdir /tmp; then
  453. root_dir="/tmp"
  454. elif ! _cannot_use_tmpdir "${PWD}"; then
  455. root_dir="${PWD}"
  456. else
  457. fatal "Unable to find a usable temporary directory. Please set \$TMPDIR to a path that is both writable and allows execution of files and try again." U0003
  458. fi
  459. TMPDIR="${root_dir}"
  460. mktemp -d -p "${root_dir}" -t netdata-updater-XXXXXXXXXX
  461. }
  462. check_for_curl() {
  463. if [ -z "${curl}" ]; then
  464. curl="$(PATH="${PATH}:/opt/netdata/bin" command -v curl 2>/dev/null && true)"
  465. fi
  466. }
  467. _safe_download() {
  468. url="${1}"
  469. dest="${2}"
  470. succeeded=0
  471. checked=0
  472. if echo "${url}" | grep -Eq "^file:///"; then
  473. run cp "${url#file://}" "${dest}" || return 1
  474. return 0
  475. fi
  476. check_for_curl
  477. if [ -n "${curl}" ]; then
  478. checked=1
  479. if "${curl}" -fsSL --connect-timeout 10 --retry 3 "${url}" > "${dest}"; then
  480. succeeded=1
  481. else
  482. rm -f "${dest}"
  483. fi
  484. fi
  485. if [ "${succeeded}" -eq 0 ]; then
  486. if command -v wget > /dev/null 2>&1; then
  487. checked=1
  488. if wget -T 15 -O - "${url}" > "${dest}"; then
  489. succeeded=1
  490. else
  491. rm -f "${dest}"
  492. fi
  493. fi
  494. fi
  495. if [ "${succeeded}" -eq 1 ]; then
  496. return 0
  497. elif [ "${checked}" -eq 1 ]; then
  498. return 1
  499. else
  500. return 255
  501. fi
  502. }
  503. download() {
  504. url="${1}"
  505. dest="${2}"
  506. _safe_download "${url}" "${dest}"
  507. ret=$?
  508. if [ ${ret} -eq 0 ]; then
  509. return 0
  510. elif [ ${ret} -eq 255 ]; then
  511. fatal "I need curl or wget to proceed, but neither is available on this system." U0004
  512. else
  513. fatal "Cannot download ${url}" U0005
  514. fi
  515. }
  516. get_netdata_latest_tag() {
  517. url="${1}/latest"
  518. check_for_curl
  519. if [ -n "${curl}" ]; then
  520. tag=$("${curl}" "${url}" -s -L -I -o /dev/null -w '%{url_effective}')
  521. fi
  522. if [ -z "${tag}" ]; then
  523. if command -v wget >/dev/null 2>&1; then
  524. tag=$(wget -S -O /dev/null "${url}" 2>&1 | grep Location)
  525. fi
  526. fi
  527. if [ -z "${tag}" ]; then
  528. fatal "I need curl or wget to proceed, but neither of them are available on this system." U0006
  529. fi
  530. tag="$(echo "${tag}" | grep -Eom 1 '[^/]*/?$')"
  531. # Fallback case for simpler local testing.
  532. if echo "${tag}" | grep -Eq 'latest/?$'; then
  533. if _safe_download "${url}/latest-version.txt" ./ndupdate-version.txt; then
  534. tag="$(cat ./ndupdate-version.txt)"
  535. if grep -q 'Not Found' ./ndupdate-version.txt; then
  536. tag="latest"
  537. fi
  538. rm -f ./ndupdate-version.txt
  539. else
  540. tag="latest"
  541. fi
  542. fi
  543. echo "${tag}"
  544. }
  545. newer_commit_date() {
  546. info "Checking if a newer version of the updater script is available."
  547. ndtmpdir="$(create_exec_tmp_directory)"
  548. commit_check_file="${ndtmpdir}/latest-commit.json"
  549. commit_check_url="https://api.github.com/repos/netdata/netdata/commits?path=packaging%2Finstaller%2Fnetdata-updater.sh&page=1&per_page=1"
  550. python_version_check="
  551. from __future__ import print_function
  552. import sys, json
  553. try:
  554. data = json.load(sys.stdin)
  555. except:
  556. print('')
  557. else:
  558. print(data[0]['commit']['committer']['date'] if isinstance(data, list) and data else '')
  559. "
  560. _safe_download "${commit_check_url}" "${commit_check_file}"
  561. if command -v jq > /dev/null 2>&1; then
  562. commit_date="$(jq '.[0].commit.committer.date' 2>/dev/null < "${commit_check_file}" | tr -d '"')"
  563. elif command -v python > /dev/null 2>&1;then
  564. commit_date="$(python -c "${python_version_check}" < "${commit_check_file}")"
  565. elif command -v python3 > /dev/null 2>&1;then
  566. commit_date="$(python3 -c "${python_version_check}" < "${commit_check_file}")"
  567. fi
  568. if [ -z "${NETDATA_TMPDIR_PATH}" ]; then
  569. rm -rf "${ndtmpdir}" >&3 2>&3
  570. fi
  571. if [ -z "${commit_date}" ] ; then
  572. return 0
  573. elif [ "$(uname)" = "Linux" ]; then
  574. commit_date="$(date -d "${commit_date}" +%s)"
  575. else # assume BSD-style `date` if we are not on Linux
  576. commit_date="$(/bin/date -j -f "%Y-%m-%dT%H:%M:%SZ" "${commit_date}" +%s 2>/dev/null)"
  577. if [ -z "${commit_date}" ]; then
  578. return 0
  579. fi
  580. fi
  581. if [ -e "${script_source}" ]; then
  582. script_date="$(date -r "${script_source}" +%s)"
  583. else
  584. script_date="$(date +%s)"
  585. fi
  586. [ "${commit_date}" -ge "${script_date}" ]
  587. }
  588. self_update() {
  589. if [ -z "${NETDATA_NO_UPDATER_SELF_UPDATE}" ] && newer_commit_date; then
  590. info "Downloading newest version of updater script."
  591. ndtmpdir=$(create_exec_tmp_directory)
  592. cd "$ndtmpdir" || exit 1
  593. if _safe_download "https://raw.githubusercontent.com/netdata/netdata/master/packaging/installer/netdata-updater.sh" ./netdata-updater.sh; then
  594. chmod +x ./netdata-updater.sh || exit 1
  595. export ENVIRONMENT_FILE="${ENVIRONMENT_FILE}"
  596. cmd="./netdata-updater.sh --not-running-from-cron --no-updater-self-update"
  597. [ "$NETDATA_FORCE_UPDATE" = "1" ] && cmd="$cmd --force-update"
  598. [ "$INTERACTIVE" = "0" ] && cmd="$cmd --non-interactive"
  599. cmd="$cmd --tmpdir-path $(pwd)"
  600. exec $cmd
  601. else
  602. error "Failed to download newest version of updater script, continuing with current version."
  603. fi
  604. fi
  605. }
  606. parse_version() {
  607. r="${1}"
  608. if [ "${r}" = "latest" ]; then
  609. # If we get ‘latest’ as a version, return the largest possible
  610. # version value.
  611. printf "99999999999999"
  612. return 0
  613. elif echo "${r}" | grep -q '^v.*'; then
  614. # shellcheck disable=SC2001
  615. # XXX: Need a regex group substitution here.
  616. r="$(echo "${r}" | sed -e 's/^v\(.*\)/\1/')"
  617. fi
  618. tmpfile="$(mktemp)"
  619. echo "${r}" | tr '-' ' ' > "${tmpfile}"
  620. read -r v b _ < "${tmpfile}"
  621. if echo "${b}" | grep -vEq "^[0-9]+$"; then
  622. b="0"
  623. fi
  624. echo "${v}" | tr '.' ' ' > "${tmpfile}"
  625. read -r maj min patch _ < "${tmpfile}"
  626. rm -f "${tmpfile}"
  627. printf "%03d%03d%03d%05d" "${maj}" "${min}" "${patch}" "${b}"
  628. }
  629. get_latest_version() {
  630. if [ "${RELEASE_CHANNEL}" = "stable" ]; then
  631. get_netdata_latest_tag "${NETDATA_STABLE_BASE_URL}"
  632. else
  633. get_netdata_latest_tag "${NETDATA_NIGHTLY_BASE_URL}"
  634. fi
  635. }
  636. validate_environment_file() {
  637. if [ -n "${NETDATA_PREFIX+SET_BUT_NULL}" ] && [ -n "${REINSTALL_OPTIONS+SET_BUT_NULL}" ]; then
  638. return 0
  639. else
  640. fatal "Environment file located at ${ENVIRONMENT_FILE} is not valid, unable to update." U0007
  641. fi
  642. }
  643. update_available() {
  644. if [ "$NETDATA_FORCE_UPDATE" = "1" ]; then
  645. info "Force update requested"
  646. return 0
  647. fi
  648. basepath="$(dirname "$(dirname "$(dirname "${NETDATA_LIB_DIR}")")")"
  649. searchpath="${basepath}/bin:${basepath}/sbin:${basepath}/usr/bin:${basepath}/usr/sbin:${PATH}"
  650. searchpath="${basepath}/netdata/bin:${basepath}/netdata/sbin:${basepath}/netdata/usr/bin:${basepath}/netdata/usr/sbin:${searchpath}"
  651. ndbinary="$(PATH="${searchpath}" command -v netdata 2>/dev/null)"
  652. if [ -z "${ndbinary}" ]; then
  653. current_version=0
  654. else
  655. current_version="$(parse_version "$(${ndbinary} -v | cut -f 2 -d ' ')")"
  656. fi
  657. latest_tag="$(get_latest_version)"
  658. latest_version="$(parse_version "${latest_tag}")"
  659. path_version="$(echo "${latest_tag}" | cut -f 1 -d "-")"
  660. # If we can't get the current version for some reason assume `0`
  661. current_version="${current_version:-0}"
  662. # If we can't get the latest version for some reason assume `0`
  663. latest_version="${latest_version:-0}"
  664. info "Current Version: ${current_version}"
  665. info "Latest Version: ${latest_version}"
  666. if [ "${latest_version}" -gt 0 ] && [ "${current_version}" -gt 0 ] && [ "${current_version}" -ge "${latest_version}" ]; then
  667. info "Newest version (current=${current_version} >= latest=${latest_version}) is already installed"
  668. return 1
  669. else
  670. info "Update available"
  671. if [ "${current_version}" -ne 0 ] && [ "${latest_version}" -ne 0 ]; then
  672. current_major="$(${ndbinary} -v | cut -f 2 -d ' ' | cut -f 1 -d '.' | tr -d 'v')"
  673. latest_major="$(echo "${latest_tag}" | cut -f 1 -d '.' | tr -d 'v')"
  674. if [ "${current_major}" -ne "${latest_major}" ]; then
  675. update_safe=0
  676. for v in ${NETDATA_ACCEPT_MAJOR_VERSIONS}; do
  677. if [ "${latest_major}" -eq "${v}" ]; then
  678. update_safe=1
  679. break
  680. fi
  681. done
  682. if [ "${update_safe}" -eq 0 ]; then
  683. warn_major_update
  684. fi
  685. fi
  686. fi
  687. return 0
  688. fi
  689. }
  690. set_tarball_urls() {
  691. filename="netdata-latest.tar.gz"
  692. if [ "$2" = "yes" ]; then
  693. if [ -e /opt/netdata/etc/netdata/.install-type ]; then
  694. # shellcheck disable=SC1091
  695. . /opt/netdata/etc/netdata/.install-type
  696. [ -z "${PREBUILT_ARCH:-}" ] && PREBUILT_ARCH="$(uname -m)"
  697. filename="netdata-${PREBUILT_ARCH}-latest.gz.run"
  698. else
  699. filename="netdata-x86_64-latest.gz.run"
  700. fi
  701. fi
  702. if [ -n "${NETDATA_OFFLINE_INSTALL_SOURCE}" ]; then
  703. path="$(cd "${NETDATA_OFFLINE_INSTALL_SOURCE}" || exit 1; pwd)"
  704. export NETDATA_TARBALL_URL="file://${path}/${filename}"
  705. export NETDATA_TARBALL_CHECKSUM_URL="file://${path}/sha256sums.txt"
  706. elif [ "$1" = "stable" ]; then
  707. latest="$(get_netdata_latest_tag "${NETDATA_STABLE_BASE_URL}")"
  708. export NETDATA_TARBALL_URL="${NETDATA_STABLE_BASE_URL}/download/$latest/${filename}"
  709. export NETDATA_TARBALL_CHECKSUM_URL="${NETDATA_STABLE_BASE_URL}/download/$latest/sha256sums.txt"
  710. else
  711. tag="$(get_netdata_latest_tag "${NETDATA_NIGHTLY_BASE_URL}")"
  712. export NETDATA_TARBALL_URL="${NETDATA_NIGHTLY_BASE_URL}/download/${tag}/${filename}"
  713. export NETDATA_TARBALL_CHECKSUM_URL="${NETDATA_NIGHTLY_BASE_URL}/download/${tag}/sha256sums.txt"
  714. fi
  715. }
  716. update_build() {
  717. [ -z "${logfile}" ] && info "Running on a terminal - (this script also supports running headless from crontab)"
  718. RUN_INSTALLER=0
  719. ndtmpdir=$(create_exec_tmp_directory)
  720. cd "$ndtmpdir" || fatal "Failed to change current working directory to ${ndtmpdir}" U0016
  721. install_build_dependencies
  722. if update_available; then
  723. download "${NETDATA_TARBALL_CHECKSUM_URL}" "${ndtmpdir}/sha256sum.txt" >&3 2>&3
  724. download "${NETDATA_TARBALL_URL}" "${ndtmpdir}/netdata-latest.tar.gz"
  725. if [ -n "${NETDATA_TARBALL_CHECKSUM}" ] &&
  726. grep "${NETDATA_TARBALL_CHECKSUM}" sha256sum.txt >&3 2>&3 &&
  727. [ "$NETDATA_FORCE_UPDATE" != "1" ]; then
  728. info "Newest version is already installed"
  729. else
  730. if ! grep netdata-latest.tar.gz sha256sum.txt | safe_sha256sum -c - >&3 2>&3; then
  731. fatal "Tarball checksum validation failed. Stopping netdata upgrade and leaving tarball in ${ndtmpdir}\nUsually this is a result of an older copy of the tarball or checksum file being cached somewhere upstream and can be resolved by retrying in an hour." U0008
  732. fi
  733. NEW_CHECKSUM="$(safe_sha256sum netdata-latest.tar.gz 2> /dev/null | cut -d' ' -f1)"
  734. tar -xf netdata-latest.tar.gz >&3 2>&3
  735. rm netdata-latest.tar.gz >&3 2>&3
  736. if [ -z "$path_version" ]; then
  737. latest_tag="$(get_latest_version)"
  738. path_version="$(echo "${latest_tag}" | cut -f 1 -d "-")"
  739. fi
  740. cd "$(find . -maxdepth 1 -type d -name "netdata-${path_version}*" | head -n 1)" || fatal "Failed to switch to build directory" U0017
  741. RUN_INSTALLER=1
  742. fi
  743. fi
  744. # We got the sources, run the update now
  745. if [ ${RUN_INSTALLER} -eq 1 ]; then
  746. # signal netdata to start saving its database
  747. # this is handy if your database is big
  748. possible_pids=$(pidof netdata)
  749. do_not_start=
  750. if [ -n "${possible_pids}" ]; then
  751. # shellcheck disable=SC2086
  752. kill -USR1 ${possible_pids}
  753. else
  754. # netdata is currently not running, so do not start it after updating
  755. do_not_start="--dont-start-it"
  756. fi
  757. env="env TMPDIR=${TMPDIR}"
  758. if [ -n "${NETDATA_SELECTED_DASHBOARD}" ]; then
  759. env="${env} NETDATA_SELECTED_DASHBOARD=${NETDATA_SELECTED_DASHBOARD}"
  760. fi
  761. if [ ! -x ./netdata-installer.sh ]; then
  762. if [ "$(find . -mindepth 1 -maxdepth 1 -type d | wc -l)" -eq 1 ] && [ -x "$(find . -mindepth 1 -maxdepth 1 -type d)/netdata-installer.sh" ]; then
  763. cd "$(find . -mindepth 1 -maxdepth 1 -type d)" || fatal "Failed to switch to build directory" U0018
  764. fi
  765. fi
  766. if [ -e "${NETDATA_PREFIX}/etc/netdata/.install-type" ] ; then
  767. install_type="$(cat "${NETDATA_PREFIX}"/etc/netdata/.install-type)"
  768. else
  769. install_type="INSTALL_TYPE='legacy-build'"
  770. fi
  771. if [ "${INSTALL_TYPE}" = "custom" ] && [ -f "${NETDATA_PREFIX}" ]; then
  772. install_type="INSTALL_TYPE='legacy-build'"
  773. fi
  774. info "Re-installing netdata..."
  775. export NETDATA_SAVE_WARNINGS=1
  776. export NETDATA_PROPAGATE_WARNINGS=1
  777. export NETDATA_WARNINGS="${NETDATA_WARNINGS}"
  778. export NETDATA_SCRIPT_STATUS_PATH="${NETDATA_SCRIPT_STATUS_PATH}"
  779. # shellcheck disable=SC2086
  780. if ! ${env} ./netdata-installer.sh ${REINSTALL_OPTIONS} --dont-wait ${do_not_start} >&3 2>&3; then
  781. if [ -r "${NETDATA_SCRIPT_STATUS_PATH}" ]; then
  782. # shellcheck disable=SC1090
  783. . "${NETDATA_SCRIPT_STATUS_PATH}"
  784. rm -f "${NETDATA_SCRIPT_STATUS_PATH}"
  785. fi
  786. if [ -n "${EXIT_REASON}" ]; then
  787. fatal "Failed to rebuild existing netdata install: ${EXIT_REASON}" "U${EXIT_CODE}"
  788. else
  789. fatal "Failed to rebuild existing netdata reinstall." UI0000
  790. fi
  791. fi
  792. # We no longer store checksum info here. but leave this so that we clean up all environment files upon next update.
  793. sed -i '/NETDATA_TARBALL/d' "${ENVIRONMENT_FILE}"
  794. info "Updating tarball checksum info"
  795. echo "${NEW_CHECKSUM}" > "${NETDATA_LIB_DIR}/netdata.tarball.checksum"
  796. echo "${install_type}" > "${NETDATA_PREFIX}/etc/netdata/.install-type"
  797. fi
  798. rm -rf "${ndtmpdir}" >&3 2>&3
  799. [ -n "${logfile}" ] && rm "${logfile}" && logfile=
  800. return 0
  801. }
  802. update_static() {
  803. ndtmpdir="$(create_exec_tmp_directory)"
  804. PREVDIR="$(pwd)"
  805. info "Entering ${ndtmpdir}"
  806. cd "${ndtmpdir}" || fatal "Failed to change current working directory to ${ndtmpdir}" U0019
  807. if update_available; then
  808. sysarch="${PREBUILT_ARCH}"
  809. [ -z "$sysarch" ] && sysarch="$(uname -m)"
  810. download "${NETDATA_TARBALL_CHECKSUM_URL}" "${ndtmpdir}/sha256sum.txt"
  811. download "${NETDATA_TARBALL_URL}" "${ndtmpdir}/netdata-${sysarch}-latest.gz.run"
  812. if ! grep "netdata-${sysarch}-latest.gz.run" "${ndtmpdir}/sha256sum.txt" | safe_sha256sum -c - > /dev/null 2>&1; then
  813. fatal "Static binary checksum validation failed. Stopping netdata installation and leaving binary in ${ndtmpdir}\nUsually this is a result of an older copy of the file being cached somewhere and can be resolved by simply retrying in an hour." U000A
  814. fi
  815. if [ -e /opt/netdata/etc/netdata/.install-type ] ; then
  816. install_type="$(cat /opt/netdata/etc/netdata/.install-type)"
  817. else
  818. install_type="INSTALL_TYPE='legacy-static'"
  819. fi
  820. # Do not pass any options other than the accept, for now
  821. # shellcheck disable=SC2086
  822. if sh "${ndtmpdir}/netdata-${sysarch}-latest.gz.run" --accept -- ${REINSTALL_OPTIONS} >&3 2>&3; then
  823. rm -r "${ndtmpdir}"
  824. else
  825. info "NOTE: did not remove: ${ndtmpdir}"
  826. fi
  827. echo "${install_type}" > /opt/netdata/etc/netdata/.install-type
  828. fi
  829. if [ -e "${PREVDIR}" ]; then
  830. info "Switching back to ${PREVDIR}"
  831. cd "${PREVDIR}"
  832. fi
  833. [ -n "${logfile}" ] && rm "${logfile}" && logfile=
  834. exit 0
  835. }
  836. get_new_binpkg_major() {
  837. case "${pm_cmd}" in
  838. apt-get) apt-get --just-print upgrade 2>&1 | grep Inst | grep ' netdata ' | cut -f 3 -d ' ' | tr -d '[]' | cut -f 1 -d '.' ;;
  839. yum) yum check-update netdata | grep -E '^netdata ' | awk '{print $2}' | cut -f 1 -d '.' ;;
  840. dnf) dnf check-update netdata | grep -E '^netdata ' | awk '{print $2}' | cut -f 1 -d '.' ;;
  841. zypper) zypper list-updates | grep '| netdata |' | cut -f 5 -d '|' | tr -d ' ' | cut -f 1 -d '.' ;;
  842. esac
  843. }
  844. update_binpkg() {
  845. os_release_file=
  846. if [ -s "/etc/os-release" ] && [ -r "/etc/os-release" ]; then
  847. os_release_file="/etc/os-release"
  848. elif [ -s "/usr/lib/os-release" ] && [ -r "/usr/lib/os-release" ]; then
  849. os_release_file="/usr/lib/os-release"
  850. else
  851. fatal "Cannot find an os-release file ..." U000B
  852. fi
  853. # shellcheck disable=SC1090
  854. . "${os_release_file}"
  855. DISTRO="${ID}"
  856. supported_compat_names="debian ubuntu centos fedora opensuse ol amzn"
  857. if str_in_list "${DISTRO}" "${supported_compat_names}"; then
  858. DISTRO_COMPAT_NAME="${DISTRO}"
  859. else
  860. case "${DISTRO}" in
  861. opensuse-leap|opensuse-tumbleweed)
  862. DISTRO_COMPAT_NAME="opensuse"
  863. ;;
  864. cloudlinux|almalinux|centos-stream|rocky|rhel)
  865. DISTRO_COMPAT_NAME="centos"
  866. ;;
  867. *)
  868. DISTRO_COMPAT_NAME="unknown"
  869. ;;
  870. esac
  871. fi
  872. interactive_opts=""
  873. env=""
  874. case "${DISTRO_COMPAT_NAME}" in
  875. debian|ubuntu)
  876. if [ "${INTERACTIVE}" = "0" ]; then
  877. upgrade_subcmd="-o Dpkg::Options::=--force-confdef -o Dpkg::Options::=--force-confold --only-upgrade install"
  878. interactive_opts="-y"
  879. env="DEBIAN_FRONTEND=noninteractive"
  880. else
  881. upgrade_subcmd="--only-upgrade install"
  882. fi
  883. pm_cmd="apt-get"
  884. repo_subcmd="update"
  885. install_subcmd="install"
  886. mark_auto_cmd="apt-mark auto"
  887. pkg_install_opts="${interactive_opts}"
  888. repo_update_opts="${interactive_opts}"
  889. pkg_installed_check="dpkg-query -s"
  890. INSTALL_TYPE="binpkg-deb"
  891. ;;
  892. centos|fedora|ol|amzn)
  893. if [ "${INTERACTIVE}" = "0" ]; then
  894. interactive_opts="-y"
  895. fi
  896. if command -v dnf > /dev/null; then
  897. pm_cmd="dnf"
  898. repo_subcmd="makecache"
  899. mark_auto_cmd="dnf mark remove"
  900. else
  901. pm_cmd="yum"
  902. mark_auto_cmd="yumdb set reason dep"
  903. fi
  904. upgrade_subcmd="upgrade"
  905. install_subcmd="install"
  906. pkg_install_opts="${interactive_opts}"
  907. repo_update_opts="${interactive_opts}"
  908. pkg_installed_check="rpm -q"
  909. INSTALL_TYPE="binpkg-rpm"
  910. ;;
  911. opensuse)
  912. if [ "${INTERACTIVE}" = "0" ]; then
  913. upgrade_subcmd="--non-interactive update"
  914. else
  915. upgrade_subcmd="update"
  916. fi
  917. pm_cmd="zypper"
  918. repo_subcmd="--gpg-auto-import-keys refresh"
  919. install_subcmd="install"
  920. mark_auto_cmd=""
  921. pkg_install_opts=""
  922. repo_update_opts=""
  923. pkg_installed_check="rpm -q"
  924. INSTALL_TYPE="binpkg-rpm"
  925. ;;
  926. *)
  927. warning "We do not provide native packages for ${DISTRO}."
  928. return 2
  929. ;;
  930. esac
  931. if [ -n "${repo_subcmd}" ]; then
  932. # shellcheck disable=SC2086
  933. env ${env} ${pm_cmd} ${repo_subcmd} ${repo_update_opts} >&3 2>&3 || fatal "Failed to update repository metadata." U000C
  934. fi
  935. for repopkg in netdata-repo netdata-repo-edge; do
  936. if ${pkg_installed_check} ${repopkg} > /dev/null 2>&1; then
  937. # shellcheck disable=SC2086
  938. env ${env} ${pm_cmd} ${upgrade_subcmd} ${pkg_install_opts} ${repopkg} >&3 2>&3 || fatal "Failed to update Netdata repository config." U000D
  939. # shellcheck disable=SC2086
  940. if [ -n "${repo_subcmd}" ]; then
  941. env ${env} ${pm_cmd} ${repo_subcmd} ${repo_update_opts} >&3 2>&3 || fatal "Failed to update repository metadata." U000E
  942. fi
  943. fi
  944. done
  945. current_major="$(netdata -v | cut -f 2 -d ' ' | cut -f 1 -d '.' | tr -d 'v')"
  946. latest_major="$(get_new_binpkg_major)"
  947. if [ -n "${latest_major}" ] && [ "${latest_major}" -ne "${current_major}" ]; then
  948. update_safe=0
  949. for v in ${NETDATA_ACCEPT_MAJOR_VERSIONS}; do
  950. if [ "${latest_major}" -eq "${v}" ]; then
  951. update_safe=1
  952. break
  953. fi
  954. done
  955. if [ "${update_safe}" -eq 0 ]; then
  956. warn_major_update
  957. fi
  958. fi
  959. # shellcheck disable=SC2086
  960. env ${env} ${pm_cmd} ${upgrade_subcmd} ${pkg_install_opts} netdata >&3 2>&3 || fatal "Failed to update Netdata package." U000F
  961. if ${pkg_installed_check} systemd > /dev/null 2>&1; then
  962. if [ "${NETDATA_NO_SYSTEMD_JOURNAL}" -eq 0 ]; then
  963. if ! ${pkg_installed_check} netdata-plugin-systemd-journal > /dev/null 2>&1; then
  964. env ${env} ${pm_cmd} ${install_subcmd} ${pkg_install_opts} netdata-plugin-systemd-journal >&3 2>&3
  965. if [ -n "${mark_auto_cmd}" ]; then
  966. # shellcheck disable=SC2086
  967. env ${env} ${mark_auto_cmd} netdata-plugin-systemd-journal >&3 2>&3
  968. fi
  969. fi
  970. fi
  971. fi
  972. [ -n "${logfile}" ] && rm "${logfile}" && logfile=
  973. return 0
  974. }
  975. # Simple function to encapsulate original updater behavior.
  976. update_legacy() {
  977. set_tarball_urls "${RELEASE_CHANNEL}" "${IS_NETDATA_STATIC_BINARY}"
  978. case "${IS_NETDATA_STATIC_BINARY}" in
  979. yes) update_static && exit 0 ;;
  980. *) update_build && exit 0 ;;
  981. esac
  982. }
  983. logfile=
  984. ndtmpdir=
  985. trap cleanup EXIT
  986. if [ -t 2 ] || [ "${GITHUB_ACTIONS}" ]; then
  987. # we are running on a terminal or under CI
  988. # open fd 3 and send it to stderr
  989. exec 3>&2
  990. else
  991. # we are headless
  992. # create a temporary file for the log
  993. logfile="$(mktemp -t netdata-updater.log.XXXXXX)"
  994. # open fd 3 and send it to logfile
  995. exec 3> "${logfile}"
  996. fi
  997. : "${ENVIRONMENT_FILE:=THIS_SHOULD_BE_REPLACED_BY_INSTALLER_SCRIPT}"
  998. if [ "${ENVIRONMENT_FILE}" = "THIS_SHOULD_BE_REPLACED_BY_INSTALLER_SCRIPT" ]; then
  999. if [ -r "${script_dir}/../../../etc/netdata/.environment" ] || [ -r "${script_dir}/../../../etc/netdata/.install-type" ]; then
  1000. ENVIRONMENT_FILE="${script_dir}/../../../etc/netdata/.environment"
  1001. elif [ -r "/etc/netdata/.environment" ] || [ -r "/etc/netdata/.install-type" ]; then
  1002. ENVIRONMENT_FILE="/etc/netdata/.environment"
  1003. elif [ -r "/opt/netdata/etc/netdata/.environment" ] || [ -r "/opt/netdata/etc/netdata/.install-type" ]; then
  1004. ENVIRONMENT_FILE="/opt/netdata/etc/netdata/.environment"
  1005. else
  1006. envpath="$(find / -type d \( -path /sys -o -path /proc -o -path /dev \) -prune -false -o -path '*netdata/.environment' -type f 2> /dev/null | head -n 1)"
  1007. itpath="$(find / -type d \( -path /sys -o -path /proc -o -path /dev \) -prune -false -o -path '*netdata/.install-type' -type f 2> /dev/null | head -n 1)"
  1008. if [ -r "${envpath}" ]; then
  1009. ENVIRONMENT_FILE="${envpath}"
  1010. elif [ -r "${itpath}" ]; then
  1011. ENVIRONMENT_FILE="$(dirname "${itpath}")/.environment"
  1012. else
  1013. fatal "Cannot find environment file or install type file, unable to update." U0010
  1014. fi
  1015. fi
  1016. fi
  1017. if [ -r "${ENVIRONMENT_FILE}" ] ; then
  1018. # shellcheck source=/dev/null
  1019. . "${ENVIRONMENT_FILE}" || fatal "Failed to source ${ENVIRONMENT_FILE}" U0014
  1020. fi
  1021. if [ -r "$(dirname "${ENVIRONMENT_FILE}")/.install-type" ]; then
  1022. # shellcheck source=/dev/null
  1023. . "$(dirname "${ENVIRONMENT_FILE}")/.install-type" || fatal "Failed to source $(dirname "${ENVIRONMENT_FILE}")/.install-type" U0015
  1024. fi
  1025. UPDATER_CONFIG_PATH="$(dirname "${ENVIRONMENT_FILE}")/netdata-updater.conf"
  1026. if [ -r "${UPDATER_CONFIG_PATH}" ]; then
  1027. # shellcheck source=/dev/null
  1028. . "${UPDATER_CONFIG_PATH}"
  1029. fi
  1030. [ -z "${NETDATA_ACCEPT_MAJOR_VERSIONS}" ] && NETDATA_ACCEPT_MAJOR_VERSIONS="${NETDATA_DEFAULT_ACCEPT_MAJOR_VERSIONS}"
  1031. while [ -n "${1}" ]; do
  1032. case "${1}" in
  1033. --not-running-from-cron) NETDATA_NOT_RUNNING_FROM_CRON=1 ;;
  1034. --no-updater-self-update) NETDATA_NO_UPDATER_SELF_UPDATE=1 ;;
  1035. --force-update) NETDATA_FORCE_UPDATE=1 ;;
  1036. --non-interactive) INTERACTIVE=0 ;;
  1037. --interactive) INTERACTIVE=1 ;;
  1038. --offline-install-source)
  1039. NETDATA_OFFLINE_INSTALL_SOURCE="${2}"
  1040. shift 1
  1041. ;;
  1042. --tmpdir-path)
  1043. NETDATA_TMPDIR_PATH="${2}"
  1044. shift 1
  1045. ;;
  1046. --enable-auto-updates)
  1047. enable_netdata_updater "${2}"
  1048. exit $?
  1049. ;;
  1050. --disable-auto-updates)
  1051. disable_netdata_updater
  1052. exit $?
  1053. ;;
  1054. --auto-update-status)
  1055. auto_update_status
  1056. exit 0
  1057. ;;
  1058. *) fatal "Unrecognized option ${1}" U001A ;;
  1059. esac
  1060. shift 1
  1061. done
  1062. if [ -n "${NETDATA_OFFLINE_INSTALL_SOURCE}" ]; then
  1063. NETDATA_NO_UPDATER_SELF_UPDATE=1
  1064. NETDATA_UPDATER_JITTER=0
  1065. NETDATA_FORCE_UPDATE=1
  1066. fi
  1067. # If we seem to be running under anacron, act as if we’re not running from cron.
  1068. # This is mostly to disable jitter, which should not be needed when run from anacron.
  1069. if running_under_anacron; then
  1070. NETDATA_NOT_RUNNING_FROM_CRON="${NETDATA_NOT_RUNNING_FROM_CRON:-1}"
  1071. fi
  1072. # Random sleep to alleviate stampede effect of Agents upgrading
  1073. # and disconnecting/reconnecting at the same time (or near to).
  1074. # But only we're not a controlling terminal (tty)
  1075. # Randomly sleep between 1s and 60m
  1076. if [ ! -t 1 ] && \
  1077. [ -z "${GITHUB_ACTIONS}" ] && \
  1078. [ -z "${NETDATA_NOT_RUNNING_FROM_CRON}" ] && \
  1079. is_integer "${NETDATA_UPDATER_JITTER}" && \
  1080. [ "${NETDATA_UPDATER_JITTER}" -gt 1 ]; then
  1081. rnd="$(awk "
  1082. BEGIN { srand()
  1083. printf(\"%d\\n\", ${NETDATA_UPDATER_JITTER} * rand())
  1084. }")"
  1085. sleep $(((rnd % NETDATA_UPDATER_JITTER) + 1))
  1086. fi
  1087. # We dont expect to find lib dir variable on older installations, so load this path if none found
  1088. export NETDATA_LIB_DIR="${NETDATA_LIB_DIR:-${NETDATA_PREFIX}/var/lib/netdata}"
  1089. # Source the tarball checksum, if not already available from environment (for existing installations with the old logic)
  1090. [ -z "${NETDATA_TARBALL_CHECKSUM}" ] && [ -f "${NETDATA_LIB_DIR}/netdata.tarball.checksum" ] && NETDATA_TARBALL_CHECKSUM="$(cat "${NETDATA_LIB_DIR}/netdata.tarball.checksum")"
  1091. if echo "$INSTALL_TYPE" | grep -qv ^binpkg && [ "${INSTALL_UID}" != "$(id -u)" ]; then
  1092. fatal "You are running this script as user with uid $(id -u). We recommend to run this script as root (user with uid 0)" U0011
  1093. fi
  1094. self_update
  1095. # shellcheck disable=SC2153
  1096. case "${INSTALL_TYPE}" in
  1097. *-build)
  1098. validate_environment_file
  1099. set_tarball_urls "${RELEASE_CHANNEL}" "${IS_NETDATA_STATIC_BINARY}"
  1100. update_build && exit 0
  1101. ;;
  1102. *-static*)
  1103. validate_environment_file
  1104. set_tarball_urls "${RELEASE_CHANNEL}" "${IS_NETDATA_STATIC_BINARY}"
  1105. update_static && exit 0
  1106. ;;
  1107. *binpkg*) update_binpkg && exit 0 ;;
  1108. "") # Fallback case for no `.install-type` file. This just works like the old install type detection.
  1109. validate_environment_file
  1110. update_legacy
  1111. ;;
  1112. custom)
  1113. # At this point, we _should_ have a valid `.environment` file, but it's best to just check.
  1114. # If we do, then behave like the legacy updater.
  1115. if validate_environment_file && [ -n "${IS_NETDATA_STATIC_BINARY}" ]; then
  1116. update_legacy
  1117. else
  1118. fatal "This script does not support updating custom installations without valid environment files." U0012
  1119. fi
  1120. ;;
  1121. oci) fatal "This script does not support updating Netdata inside our official Docker containers, please instead update the container itself." U0013 ;;
  1122. *) fatal "Unrecognized installation type (${INSTALL_TYPE}), unable to update." U0014 ;;
  1123. esac