master
sh 1,321 lines 37.5 KB
Raw
1 #!/bin/sh
2
3 # SPDX-License-Identifier: GPL-3.0-or-later
4
5 # next unused error code: L0003
6
7 # make sure we have a UID
8 [ -z "${UID}" ] && UID="$(id -u)"
9 # -----------------------------------------------------------------------------
10
11 setup_terminal() {
12 TPUT_RESET=""
13 TPUT_BLACK=""
14 TPUT_RED=""
15 TPUT_GREEN=""
16 TPUT_YELLOW=""
17 TPUT_BLUE=""
18 TPUT_PURPLE=""
19 TPUT_CYAN=""
20 TPUT_WHITE=""
21 TPUT_BGBLACK=""
22 TPUT_BGRED=""
23 TPUT_BGGREEN=""
24 TPUT_BGYELLOW=""
25 TPUT_BGBLUE=""
26 TPUT_BGPURPLE=""
27 TPUT_BGCYAN=""
28 TPUT_BGWHITE=""
29 TPUT_BOLD=""
30 TPUT_DIM=""
31 TPUT_UNDERLINED=""
32 TPUT_BLINK=""
33 TPUT_INVERTED=""
34 TPUT_STANDOUT=""
35 TPUT_BELL=""
36 TPUT_CLEAR=""
37
38 # Is stderr on the terminal? If not, then fail
39 test -t 2 || return 1
40
41 if command -v tput 1> /dev/null 2>&1; then
42 if [ $(($(tput colors 2> /dev/null))) -ge 8 ]; then
43 # Enable colors
44 TPUT_RESET="$(tput sgr 0)"
45 # shellcheck disable=SC2034
46 TPUT_BLACK="$(tput setaf 0)"
47 # shellcheck disable=SC2034
48 TPUT_RED="$(tput setaf 1)"
49 TPUT_GREEN="$(tput setaf 2)"
50 # shellcheck disable=SC2034
51 TPUT_YELLOW="$(tput setaf 3)"
52 # shellcheck disable=SC2034
53 TPUT_BLUE="$(tput setaf 4)"
54 # shellcheck disable=SC2034
55 TPUT_PURPLE="$(tput setaf 5)"
56 # shellcheck disable=SC2034
57 TPUT_CYAN="$(tput setaf 6)"
58 TPUT_WHITE="$(tput setaf 7)"
59 # shellcheck disable=SC2034
60 TPUT_BGBLACK="$(tput setab 0)"
61 TPUT_BGRED="$(tput setab 1)"
62 TPUT_BGGREEN="$(tput setab 2)"
63 # shellcheck disable=SC2034
64 TPUT_BGYELLOW="$(tput setab 3)"
65 # shellcheck disable=SC2034
66 TPUT_BGBLUE="$(tput setab 4)"
67 # shellcheck disable=SC2034
68 TPUT_BGPURPLE="$(tput setab 5)"
69 # shellcheck disable=SC2034
70 TPUT_BGCYAN="$(tput setab 6)"
71 # shellcheck disable=SC2034
72 TPUT_BGWHITE="$(tput setab 7)"
73 TPUT_BOLD="$(tput bold)"
74 TPUT_DIM="$(tput dim)"
75 # shellcheck disable=SC2034
76 TPUT_UNDERLINED="$(tput smul)"
77 # shellcheck disable=SC2034
78 TPUT_BLINK="$(tput blink)"
79 # shellcheck disable=SC2034
80 TPUT_INVERTED="$(tput rev)"
81 # shellcheck disable=SC2034
82 TPUT_STANDOUT="$(tput smso)"
83 # shellcheck disable=SC2034
84 TPUT_BELL="$(tput bel)"
85 # shellcheck disable=SC2034
86 TPUT_CLEAR="$(tput clear)"
87 fi
88 fi
89
90 return 0
91 }
92 setup_terminal || echo > /dev/null
93
94 progress() {
95 echo >&2 " --- ${TPUT_DIM}${TPUT_BOLD}${*}${TPUT_RESET} --- "
96 }
97
98 check_for_curl() {
99 if [ -z "${curl}" ]; then
100 curl="$(PATH="${PATH}:/opt/netdata/bin" command -v curl 2>/dev/null && true)"
101 fi
102 }
103
104 get() {
105 url="${1}"
106 checked=0
107 succeeded=0
108
109 check_for_curl
110
111 if [ -n "${curl}" ]; then
112 checked=1
113
114 if "${curl}" -q -o - -sSL --connect-timeout 10 --retry 3 "${url}"; then
115 succeeded=1
116 fi
117 fi
118
119 if [ "${succeeded}" -eq 0 ]; then
120 if command -v wget > /dev/null 2>&1; then
121 checked=1
122
123 if wget -T 15 -O - "${url}"; then
124 succeeded=1
125 fi
126 fi
127 fi
128
129 if [ "${succeeded}" -eq 1 ]; then
130 return 0
131 elif [ "${checked}" -eq 1 ]; then
132 return 1
133 else
134 fatal "I need curl or wget to proceed, but neither is available on this system." "L0002"
135 fi
136 }
137
138 download_file() {
139 url="${1}"
140 dest="${2}"
141 name="${3}"
142 opt="${4}"
143
144 check_for_curl
145
146 if [ -n "${curl}" ]; then
147 checked=1
148
149 if run "${curl}" -q -sSL --connect-timeout 10 --retry 3 --output "${dest}" "${url}"; then
150 succeeded=1
151 else
152 rm -f "${dest}"
153 fi
154 fi
155
156 if [ "${succeeded}" -eq 0 ]; then
157 if command -v wget > /dev/null 2>&1; then
158 checked=1
159
160 if run wget -T 15 -O "${dest}" "${url}"; then
161 succeeded=1
162 fi
163 fi
164 fi
165
166 if [ "${succeeded}" -eq 1 ]; then
167 return 0
168 elif [ "${checked}" -eq 1 ]; then
169 return 1
170 else
171 echo >&2
172 echo >&2 "Downloading ${name} from '${url}' failed because of missing mandatory packages."
173 if [ -n "$opt" ]; then
174 echo >&2 "Either add packages or disable it by issuing '--disable-${opt}' in the installer"
175 fi
176 echo >&2
177
178 run_failed "I need curl or wget to proceed, but neither is available on this system."
179 fi
180 }
181
182 # -----------------------------------------------------------------------------
183 # external component handling
184
185 fetch_and_verify() {
186 component="${1}"
187 url="${2}"
188 base_name="${3}"
189 tmp="${4}"
190 override="${5}"
191
192 if [ -z "${override}" ]; then
193 download_file "${url}" "${tmp}/${base_name}" "${component}"
194 else
195 progress "Using provided ${component} archive ${override}"
196 run cp "${override}" "${tmp}/${base_name}"
197 fi
198
199 if [ ! -f "${tmp}/${base_name}" ] || [ ! -s "${tmp}/${base_name}" ]; then
200 run_failed "Unable to find usable archive for ${component}"
201 return 1
202 fi
203
204 grep "${base_name}\$" "${INSTALLER_DIR}/packaging/${component}.checksums" > "${tmp}/sha256sums.txt" 2> /dev/null
205
206 # Checksum validation
207 if ! (cd "${tmp}" && safe_sha256sum -c "sha256sums.txt"); then
208 run_failed "${component} files checksum validation failed."
209 return 1
210 fi
211 }
212
213 # -----------------------------------------------------------------------------
214
215 netdata_banner() {
216 l1=" ^" \
217 l2=" |.-. .-. .-. .-. .-. .-. .-. .-. .-. .-. .-. .-. .-" \
218 l4=" +----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+--->" \
219 space=" "
220 l3f=" | '-' '-' '-' '-' '-'"
221 l3e=" '-' '-' '-' '-' '-' "
222
223 netdata="netdata"
224 chartcolor="${TPUT_DIM}"
225
226 echo >&2
227 echo >&2 "${chartcolor}${l1}${TPUT_RESET}"
228 echo >&2 "${chartcolor}${l2%-. .-. .-. .-. .-. .-. .-. .-}${space}${TPUT_RESET}${TPUT_BOLD}${TPUT_GREEN}${netdata}${TPUT_RESET}${chartcolor}${l2# |.-. .-. .-. .-. .-. .-. .-. }${TPUT_RESET}"
229 echo >&2 "${chartcolor}${l3f}${l3e}${TPUT_RESET}"
230 echo >&2 "${chartcolor}${l4}${TPUT_RESET}"
231 echo >&2
232 }
233
234 # -----------------------------------------------------------------------------
235 # Feature management and configuration commands
236
237 enable_feature() {
238 NETDATA_CMAKE_OPTIONS="$(echo "${NETDATA_CMAKE_OPTIONS}" | sed -e "s/-DENABLE_${1}=Off[[:space:]]*//g" -e "s/-DENABLE_${1}=On[[:space:]]*//g")"
239 if [ "${2}" -eq 1 ]; then
240 NETDATA_CMAKE_OPTIONS="$(echo "${NETDATA_CMAKE_OPTIONS}" | sed "s/$/ -DENABLE_${1}=On/")"
241 else
242 NETDATA_CMAKE_OPTIONS="$(echo "${NETDATA_CMAKE_OPTIONS}" | sed "s/$/ -DENABLE_${1}=Off/")"
243 fi
244 }
245
246 check_for_module() {
247 if [ -z "${pkgconf}" ]; then
248 pkgconf="$(command -v pkgconf 2>/dev/null)"
249 [ -z "${pkgconf}" ] && pkgconf="$(command -v pkg-config 2>/dev/null)"
250 [ -z "${pkgconf}" ] && fatal "Unable to find a usable pkgconf/pkg-config command, cannot build Netdata." I0013
251 fi
252
253 "${pkgconf}" "${1}"
254 return "${?}"
255 }
256
257 check_for_feature() {
258 feature_name="${1}"
259 feature_state="${2}"
260 shift 2
261 feature_modules="${*}"
262
263 if [ -z "${feature_state}" ]; then
264 # shellcheck disable=SC2086
265 if check_for_module ${feature_modules}; then
266 enable_feature "${feature_name}" 1
267 else
268 enable_feature "${feature_name}" 0
269 fi
270 else
271 enable_feature "${feature_name}" "${feature_state}"
272 fi
273 }
274
275 prepare_cmake_options() {
276 NETDATA_CMAKE_OPTIONS="-S ./ -B ${NETDATA_BUILD_DIR} ${CMAKE_OPTS} ${NETDATA_USER:+-DNETDATA_USER=${NETDATA_USER}} ${NETDATA_CMAKE_OPTIONS} "
277
278 # Keep forwarding the install prefix even when it is empty.
279 # This installer uses an empty prefix for /usr/... destinations instead of
280 # CMake's /usr/local default.
281 NETDATA_CMAKE_INSTALL_PREFIX_OPTION="-DCMAKE_INSTALL_PREFIX=${NETDATA_PREFIX-}"
282 NETDATA_WINDOWS_PATH_PREFIX_OPTION=
283
284 #
285 # Do not append either prefix-related option to NETDATA_CMAKE_OPTIONS,
286 # because that variable is later expanded as a space-delimited string and
287 # path values may contain spaces. Keep them as dedicated variables so
288 # callers can pass them as separately quoted arguments.
289
290 if [ -n "${NETDATA_WINDOWS_PATH_PREFIX:-}" ]; then
291 NETDATA_WINDOWS_PATH_PREFIX_OPTION="-DNETDATA_WINDOWS_PATH_PREFIX=${NETDATA_WINDOWS_PATH_PREFIX}"
292 fi
293
294 NEED_OLD_CXX=0
295
296 if [ "${FORCE_LEGACY_CXX:-0}" -eq 1 ]; then
297 NEED_OLD_CXX=1
298 else
299 if command -v gcc >/dev/null 2>&1; then
300 if [ "$(gcc --version | head -n 1 | sed 's/(.*) //' | cut -f 2 -d ' ' | cut -f 1 -d '.')" -lt 5 ]; then
301 NEED_OLD_CXX=1
302 fi
303 fi
304
305 if command -v clang >/dev/null 2>&1; then
306 if [ "$(clang --version | head -n 1 | cut -f 3 -d ' ' | cut -f 1 -d '.')" -lt 4 ]; then
307 NEED_OLD_CXX=1
308 fi
309 fi
310 fi
311
312 if [ "${NEED_OLD_CXX}" -eq 1 ]; then
313 NETDATA_CMAKE_OPTIONS="${NETDATA_CMAKE_OPTIONS} -DUSE_CXX_11=On"
314 fi
315
316 if [ -n "${NETDATA_ENABLE_LTO}" ]; then
317 if [ "${NETDATA_ENABLE_LTO}" -eq 1 ]; then
318 NETDATA_CMAKE_OPTIONS="${NETDATA_CMAKE_OPTIONS} -DCMAKE_INTERPROCEDURAL_OPTIMIZATION=On -DUSE_LTO=On"
319 else
320 NETDATA_CMAKE_OPTIONS="${NETDATA_CMAKE_OPTIONS} -DCMAKE_INTERPROCEDURAL_OPTIMIZATION=Off -DUSE_LTO=Off"
321 fi
322 fi
323
324 if [ "${ENABLE_GO:-1}" -eq 1 ]; then
325 enable_feature PLUGIN_GO 1
326 else
327 enable_feature PLUGIN_GO 0
328 fi
329
330 if [ "${ENABLE_PYTHON:-1}" -eq 1 ]; then
331 enable_feature PLUGIN_PYTHON 1
332 else
333 enable_feature PLUGIN_PYTHON 0
334 fi
335
336 if [ "${ENABLE_CHARTS:-1}" -eq 1 ]; then
337 enable_feature PLUGIN_CHARTS 1
338 else
339 enable_feature PLUGIN_CHARTS 0
340 fi
341
342 if [ "${USE_SYSTEM_PROTOBUF:-0}" -eq 1 ]; then
343 enable_feature BUNDLED_PROTOBUF 0
344 else
345 enable_feature BUNDLED_PROTOBUF 1
346 fi
347
348 if [ -z "${ENABLE_SYSTEMD_JOURNAL}" ]; then
349 if check_for_module libsystemd; then
350 if check_for_module libelogind; then
351 ENABLE_SYSTEMD_JOURNAL=0
352 else
353 ENABLE_SYSTEMD_JOURNAL=1
354 fi
355 else
356 ENABLE_SYSTEMD_JOURNAL=0
357 fi
358 fi
359
360 enable_feature PLUGIN_SYSTEMD_JOURNAL "${ENABLE_SYSTEMD_JOURNAL}"
361
362 if [ "${ENABLE_SYSTEMD_JOURNAL}" -eq 1 ] && [ -n "${USE_RUST_JOURNAL_FILE}" ]; then
363 enable_feature NETDATA_JOURNAL_FILE_READER 1
364 else
365 enable_feature NETDATA_JOURNAL_FILE_READER 0
366 fi
367
368 if check_for_module 'libsystemd >= 221'; then
369 enable_feature PLUGIN_SYSTEMD_UNITS 1
370 else
371 enable_feature PLUGIN_SYSTEMD_UNITS 0
372 fi
373
374 if command -v cups-config >/dev/null 2>&1 || check_for_module libcups || check_for_module cups; then
375 ENABLE_CUPS=1
376 else
377 ENABLE_CUPS=0
378 fi
379
380 enable_feature PLUGIN_CUPS "${ENABLE_CUPS}"
381
382 IS_LINUX=0
383 [ "$(uname -s)" = "Linux" ] && IS_LINUX=1
384 IS_LINUX_OR_FREEBSD="${IS_LINUX}"
385 [ "$(uname -s)" = "FreeBSD" ] && IS_LINUX_OR_FREEBSD=1
386 enable_feature PLUGIN_DEBUGFS "${IS_LINUX}"
387 enable_feature PLUGIN_PERF "${IS_LINUX}"
388 enable_feature PLUGIN_SLABINFO "${IS_LINUX}"
389 enable_feature PLUGIN_CGROUP_NETWORK "${IS_LINUX}"
390 enable_feature PLUGIN_LOCAL_LISTENERS "${IS_LINUX}"
391 enable_feature PLUGIN_NETWORK_VIEWER "${IS_LINUX_OR_FREEBSD}"
392 enable_feature PLUGIN_EBPF "${ENABLE_EBPF:-0}"
393
394 enable_feature BUNDLED_JSONC "${NETDATA_BUILD_JSON_C:-0}"
395 enable_feature DBENGINE "${ENABLE_DBENGINE:-1}"
396 enable_feature ML "${NETDATA_ENABLE_ML:-1}"
397 enable_feature PLUGIN_APPS "${ENABLE_APPS:-1}"
398 enable_feature PLUGIN_NETFLOW "${ENABLE_NETFLOW:-0}"
399 enable_feature PLUGIN_OTEL "${ENABLE_OTEL:-0}"
400 enable_feature PLUGIN_OTEL_SIGNAL_VIEWER "${ENABLE_OTEL_SIGNAL_VIEWER:-0}"
401 enable_feature PLUGIN_IBM "${ENABLE_IBM:-0}"
402 enable_feature PLUGIN_SCRIPTS "${ENABLE_SCRIPTS:-0}"
403
404 check_for_feature EXPORTER_PROMETHEUS_REMOTE_WRITE "${EXPORTER_PROMETHEUS}" snappy
405 check_for_feature EXPORTER_MONGODB "${EXPORTER_MONGODB}" libmongoc-1.0
406 check_for_feature PLUGIN_FREEIPMI "${ENABLE_FREEIPMI}" libipmimonitoring
407 check_for_feature PLUGIN_NFACCT "${ENABLE_NFACCT}" libnetfilter_acct libnml
408 check_for_feature PLUGIN_XENSTAT "${ENABLE_XENSTAT}" xenstat xenlight
409 }
410
411 # -----------------------------------------------------------------------------
412 # portable service command
413
414 service_cmd="$(command -v service 2> /dev/null || true)"
415 rcservice_cmd="$(command -v rc-service 2> /dev/null || true)"
416 systemctl_cmd="$(command -v systemctl 2> /dev/null || true)"
417 service() {
418
419 cmd="${1}"
420 action="${2}"
421
422 if [ -n "${systemctl_cmd}" ]; then
423 run "${systemctl_cmd}" "${action}" "${cmd}"
424 return $?
425 elif [ -n "${service_cmd}" ]; then
426 run "${service_cmd}" "${cmd}" "${action}"
427 return $?
428 elif [ -n "${rcservice_cmd}" ]; then
429 run "${rcservice_cmd}" "${cmd}" "${action}"
430 return $?
431 fi
432 return 1
433 }
434
435 # -----------------------------------------------------------------------------
436 # portable pidof
437
438 safe_pidof() {
439 pidof_cmd="$(command -v pidof 2> /dev/null)"
440 if [ -n "${pidof_cmd}" ]; then
441 ${pidof_cmd} "${@}"
442 return $?
443 else
444 ps -acxo pid,comm |
445 sed "s/^ *//g" |
446 grep netdata |
447 cut -d ' ' -f 1
448 return $?
449 fi
450 }
451
452 # -----------------------------------------------------------------------------
453 find_processors() {
454 # Most UNIX systems have `nproc` as part of their userland (including Linux and BSD)
455 if command -v nproc > /dev/null; then
456 nproc && return
457 fi
458
459 # macOS has no nproc but it may have gnproc installed from Homebrew or from Macports.
460 if command -v gnproc > /dev/null; then
461 gnproc && return
462 fi
463
464 if [ -f "/proc/cpuinfo" ]; then
465 # linux
466 cpus=$(grep -c ^processor /proc/cpuinfo)
467 else
468 # freebsd
469 cpus=$(sysctl hw.ncpu 2> /dev/null | grep ^hw.ncpu | cut -d ' ' -f 2)
470 fi
471 if [ -z "${cpus}" ] || [ $((cpus)) -lt 1 ]; then
472 echo 1
473 else
474 echo "${cpus}"
475 fi
476 }
477
478 # -----------------------------------------------------------------------------
479 exit_reason() {
480 if [ -n "${NETDATA_SAVE_WARNINGS}" ]; then
481 EXIT_REASON="${1}"
482 EXIT_CODE="${2}"
483 if [ -n "${NETDATA_PROPAGATE_WARNINGS}" ]; then
484 if [ -n "${NETDATA_SCRIPT_STATUS_PATH}" ]; then
485 {
486 echo "EXIT_REASON=\"${EXIT_REASON}\""
487 echo "EXIT_CODE=\"${EXIT_CODE}\""
488 echo "NETDATA_WARNINGS=\"${NETDATA_WARNINGS}${SAVED_WARNINGS}\""
489 } >> "${NETDATA_SCRIPT_STATUS_PATH}"
490 else
491 export EXIT_REASON
492 export EXIT_CODE
493 export NETDATA_WARNINGS="${NETDATA_WARNINGS}${SAVED_WARNINGS}"
494 fi
495 fi
496 fi
497 }
498
499 fatal() {
500 printf >&2 "%s ABORTED %s %s \n\n" "${TPUT_BGRED}${TPUT_WHITE}${TPUT_BOLD}" "${TPUT_RESET}" "${1}"
501 if [ -n "${NETDATA_SAVE_WARNINGS}" ]; then
502 SAVED_WARNINGS="${SAVED_WARNINGS}\n - ${1}"
503 fi
504 exit_reason "${1}" "${2}"
505 exit 1
506 }
507
508 warning() {
509 printf >&2 "%s WARNING %s %s\n\n" "${TPUT_BGYELLOW}${TPUT_BLACK}${TPUT_BOLD}" "${TPUT_RESET}" "${1}"
510 if [ -n "${NETDATA_SAVE_WARNINGS}" ]; then
511 SAVED_WARNINGS="${SAVED_WARNINGS}\n - ${1}"
512 fi
513 }
514
515 run_ok() {
516 printf >&2 "%s OK %s %s\n\n" "${TPUT_BGGREEN}${TPUT_WHITE}${TPUT_BOLD}" "${TPUT_RESET}" "${1:-''}"
517 }
518
519 run_failed() {
520 printf >&2 "%s FAILED %s %s\n\n" "${TPUT_BGRED}${TPUT_WHITE}${TPUT_BOLD}" "${TPUT_RESET}" "${1:-''}"
521 if [ -n "${NETDATA_SAVE_WARNINGS}" ] && [ -n "${1:-''}" ]; then
522 SAVED_WARNINGS="${SAVED_WARNINGS}\n - ${1}"
523 fi
524 }
525
526 ESCAPED_PRINT_METHOD=
527 if printf "%s " test > /dev/null 2>&1; then
528 ESCAPED_PRINT_METHOD="printfq"
529 fi
530 escaped_print() {
531 if [ "${ESCAPED_PRINT_METHOD}" = "printfq" ]; then
532 printf "%s " "${@}"
533 else
534 printf "%s" "${*}"
535 fi
536 return 0
537 }
538
539 run_logfile="/dev/null"
540 run() {
541 local_user="${USER--}"
542 local_dir="${PWD}"
543 if [ "${UID}" = "0" ]; then
544 info="[root ${local_dir}]# "
545 info_console="[${TPUT_DIM}${local_dir}${TPUT_RESET}]# "
546 else
547 info="[${local_user} ${local_dir}]$ "
548 info_console="[${TPUT_DIM}${local_dir}${TPUT_RESET}]$ "
549 fi
550
551 {
552 printf "%s" "${info}"
553 escaped_print "${@}"
554 printf "%s" " ... "
555 } >> "${run_logfile}"
556
557 printf >&2 "%s" "${info_console}${TPUT_BOLD}${TPUT_YELLOW}"
558 escaped_print >&2 "${@}"
559 printf >&2 "%s\n" "${TPUT_RESET}"
560
561 "${@}"
562
563 ret=$?
564 if [ ${ret} -ne 0 ]; then
565 run_failed
566 printf >> "${run_logfile}" "FAILED with exit code %s\n" "${ret}"
567 if [ -n "${NETDATA_SAVE_WARNINGS}" ]; then
568 SAVED_WARNINGS="${SAVED_WARNINGS}\n - Command '${*}' failed with exit code ${ret}."
569 fi
570 else
571 run_ok
572 printf >> "${run_logfile}" "OK\n"
573 fi
574
575 return ${ret}
576 }
577
578 iscontainer() {
579 # man systemd-detect-virt
580 cmd=$(command -v systemd-detect-virt 2> /dev/null)
581 if [ -n "${cmd}" ] && [ -x "${cmd}" ]; then
582 "${cmd}" --container > /dev/null 2>&1 && return 0
583 fi
584
585 # /proc/1/sched exposes the host's pid of our init !
586 # http://stackoverflow.com/a/37016302
587 pid=$(head -n 1 /proc/1/sched 2> /dev/null | {
588 # shellcheck disable=SC2034
589 IFS='(),#:' read -r name pid th threads
590 echo "$pid"
591 })
592 if [ -n "${pid}" ]; then
593 pid=$((pid + 0))
594 [ ${pid} -gt 1 ] && return 0
595 fi
596
597 # lxc sets environment variable 'container'
598 # shellcheck disable=SC2154
599 [ -n "${container}" ] && return 0
600
601 # docker creates /.dockerenv
602 # http://stackoverflow.com/a/25518345
603 [ -f "/.dockerenv" ] && return 0
604
605 # ubuntu and debian supply /bin/running-in-container
606 # https://www.apt-browse.org/browse/ubuntu/trusty/main/i386/upstart/1.12.1-0ubuntu4/file/bin/running-in-container
607 if [ -x "/bin/running-in-container" ]; then
608 "/bin/running-in-container" > /dev/null 2>&1 && return 0
609 fi
610
611 return 1
612 }
613
614 get_os_key() {
615 if [ -f /etc/os-release ]; then
616 # shellcheck disable=SC1091
617 . /etc/os-release || return 1
618 echo "${ID}-${VERSION_ID}"
619
620 elif [ -f /etc/redhat-release ]; then
621 cat /etc/redhat-release
622 else
623 echo "unknown"
624 fi
625 }
626
627 get_group(){
628 if command -v getent > /dev/null 2>&1; then
629 getent group "${1:-""}"
630 else
631 grep "^${1}:" /etc/group
632 fi
633 }
634
635 issystemd() {
636 pids=''
637 p=''
638 myns=''
639 ns=''
640 systemctl=''
641
642 # if there is no systemctl command, it is not systemd
643 systemctl=$(command -v systemctl 2> /dev/null)
644 if [ -z "${systemctl}" ] || [ ! -x "${systemctl}" ]; then
645 return 1
646 fi
647
648 # Check the output of systemctl is-system-running.
649 # If this reports 'offline', it’s not systemd. If it reports 'unknown'
650 # or nothing at all (which indicates the command is not supported), it
651 # may or may not be systemd, so continue to other checks. If it reports
652 # anything else, it is systemd.
653 case "$(systemctl is-system-running)" in
654 offline) return 1 ;;
655 unknown) : ;;
656 "") : ;;
657 *) return 0 ;;
658 esac
659
660 # if pid 1 is systemd, it is systemd
661 [ "$(basename "$(readlink /proc/1/exe)" 2> /dev/null)" = "systemd" ] && return 0
662
663 # if systemd is not running, it is not systemd
664 pids=$(safe_pidof systemd 2> /dev/null)
665 [ -z "${pids}" ] && return 1
666
667 # check if the running systemd processes are not in our namespace
668 myns="$(readlink /proc/self/ns/pid 2> /dev/null)"
669 for p in ${pids}; do
670 ns="$(readlink "/proc/${p}/ns/pid" 2> /dev/null)"
671
672 # if pid of systemd is in our namespace, it is systemd
673 [ -n "${myns}" ] && [ "${myns}" = "${ns}" ] && return 0
674 done
675
676 # else, it is not systemd
677 return 1
678 }
679
680 get_systemd_service_dir() {
681 unit_paths="$(systemctl show -p UnitPath | cut -f 2- -d '=' | tr ' ' '\n')"
682
683 if [ -n "${unit_paths}" ]; then
684 lib_paths="$(echo "${unit_paths}" | grep -vE '^/(run|etc)' | awk '{line[NR] = $0} END {for (i = NR; i > 0; i--) print line[i]}')"
685 etc_paths="$(echo "${unit_paths}" | grep -E '^/etc' | grep -vE '(attached|control)$')"
686 else
687 lib_paths="/usr/lib/systemd/system /lib/systemd/system /usr/local/lib/systemd/system"
688 etc_paths="/etc/systemd/system"
689 fi
690
691 for path in ${lib_paths} ${etc_paths}; do
692 if [ -d "${path}" ] && [ -w "${path}" ]; then
693 echo "${path}"
694 return 0
695 fi
696 done
697 }
698
699 run_install_service_script() {
700 if [ -z "${tmpdir}" ]; then
701 tmpdir="${TMPDIR:-/tmp}"
702 fi
703
704 # shellcheck disable=SC2154
705 save_path="${tmpdir}/netdata-service-cmds"
706 # shellcheck disable=SC2068
707 "${NETDATA_PREFIX}/usr/libexec/netdata/install-service.sh" --save-cmds "${save_path}" ${@}
708
709 case $? in
710 0)
711 if [ -r "${save_path}" ]; then
712 # shellcheck disable=SC1090
713 . "${save_path}"
714 fi
715
716 if [ -z "${NETDATA_INSTALLER_START_CMD}" ]; then
717 if [ -n "${NETDATA_START_CMD}" ]; then
718 NETDATA_INSTALLER_START_CMD="${NETDATA_START_CMD}"
719 else
720 NETDATA_INSTALLER_START_CMD="netdata"
721 fi
722 fi
723 ;;
724 1)
725 if [ -z "${NETDATA_SERVICE_WARNED_1}" ]; then
726 warning "Intenral error encountered while attempting to install or manage Netdata as a system service. This is probably a bug."
727 NETDATA_SERVICE_WARNED_1=1
728 fi
729 ;;
730 2)
731 if [ -z "${NETDATA_SERVICE_WARNED_2}" ]; then
732 warning "Failed to detect system service manager type. Cannot cleanly install or manage Netdata as a system service. If you are running this script in a container, this is expected and can safely be ignored."
733 NETDATA_SERVICE_WARNED_2=1
734 fi
735 ;;
736 3)
737 if [ -z "${NETDATA_SERVICE_WARNED_3}" ]; then
738 warning "Detected an unsupported system service manager. Manual setup will be required to manage Netdata as a system service."
739 NETDATA_SERVICE_WARNED_3=1
740 fi
741 ;;
742 4)
743 if [ -z "${NETDATA_SERVICE_WARNED_4}" ]; then
744 warning "Detected a supported system service manager, but failed to install Netdata as a system service. Usually this is a result of incorrect permissions. Manually running ${NETDATA_PREFIX}/usr/libexec/netdata/install-service.sh may provide more information about the exact issue."
745 NETDATA_SERVICE_WARNED_4=1
746 fi
747 ;;
748 5)
749 if [ -z "${NETDATA_SERVICE_WARNED_5}" ]; then
750 warning "We do not support managing Netdata as a system service on this platform. Manual setup will be required."
751 NETDATA_SERVICE_WARNED_5=1
752 fi
753 ;;
754 esac
755 }
756
757 install_netdata_service() {
758 if [ "${UID}" -eq 0 ]; then
759 if [ -x "${NETDATA_PREFIX}/usr/libexec/netdata/install-service.sh" ]; then
760 run_install_service_script && return 0
761 else
762 warning "Could not find service install script, not installing Netdata as a system service."
763 fi
764 fi
765
766 return 1
767 }
768
769 install_netdata_tmpfiles() {
770 if [ "${UID}" -eq 0 ]; then
771 run mkdir -p /usr/lib/tmpfiles.d || return 1
772 run install -m 0644 -p "${NETDATA_PREFIX}/usr/lib/netdata/system/systemd/tmpfiles/netdata.conf" /usr/lib/tmpfiles.d/netdata.conf || return 1
773 return 0
774 else
775 return 1
776 fi
777 }
778
779 install_netdata_dirs() {
780 _DIRS_INSTALLED=0
781 if install_netdata_tmpfiles && command -v systemd-tmpfiles >/dev/null 2>&1 ; then
782 systemd-tmpfiles --create /usr/lib/tmpfiles.d/netdata.conf && _DIRS_INSTALLED=1
783 fi
784
785 if [ "${_DIRS_INSTALLED}" -eq 0 ]; then
786 for x in "${NETDATA_LIB_DIR}" "${NETDATA_CACHE_DIR}" "${NETDATA_LOG_DIR}"; do
787 if [ ! -d "${x}" ]; then
788 echo >&2 "Creating directory '${x}'"
789 if ! run mkdir -p "${x}"; then
790 warning "Failed to create ${x}, it must be created by hand or the Netdata Agent will not be able to be started."
791 fi
792 fi
793
794 run chown -R "${NETDATA_USER}:${NETDATA_GROUP}" "${x}"
795 done
796
797 run chmod 755 "${NETDATA_LOG_DIR}"
798
799 if [ ! -d "${NETDATA_CLAIMING_DIR}" ]; then
800 echo >&2 "Creating directory '${NETDATA_CLAIMING_DIR}'"
801 if ! run mkdir -p "${NETDATA_CLAIMING_DIR}"; then
802 warning "failed to create ${NETDATA_CLAIMING_DIR}, it will need to be created manually."
803 fi
804 fi
805 run chown -R "${NETDATA_USER}:${NETDATA_GROUP}" "${NETDATA_CLAIMING_DIR}"
806 run chmod 770 "${NETDATA_CLAIMING_DIR}"
807 fi
808 }
809
810 # -----------------------------------------------------------------------------
811 # stop netdata
812
813 pidisnetdata() {
814 if [ -d /proc/self ]; then
815 if [ -z "$1" ] || [ ! -f "/proc/$1/stat" ]; then
816 return 1
817 fi
818 [ "$(cut -d '(' -f 2 "/proc/$1/stat" | cut -d ')' -f 1)" = "netdata" ] && return 0
819 return 1
820 fi
821 return 0
822 }
823
824 stop_netdata_on_pid() {
825 pid="${1}"
826 ret=0
827 count=0
828
829 pidisnetdata "${pid}" || return 0
830
831 printf >&2 "Stopping netdata on pid %s ..." "${pid}"
832 while [ -n "${pid}" ] && [ ${ret} -eq 0 ]; do
833 if [ ${count} -gt 24 ]; then
834 warning "Cannot stop netdata agent with PID ${pid}."
835 return 1
836 fi
837
838 count=$((count + 1))
839
840 pidisnetdata "${pid}" || ret=1
841 if [ ${ret} -eq 1 ]; then
842 break
843 fi
844
845 if [ ${count} -lt 12 ]; then
846 run kill "${pid}" 2> /dev/null
847 ret=$?
848 else
849 run kill -9 "${pid}" 2> /dev/null
850 ret=$?
851 fi
852
853 test ${ret} -eq 0 && printf >&2 "." && sleep 5
854
855 done
856
857 echo >&2
858 if [ ${ret} -eq 0 ]; then
859 warning "Failed to stop netdata agent process with PID ${pid}."
860 return 1
861 fi
862
863 echo >&2 "netdata on pid ${pid} stopped."
864 return 0
865 }
866
867 netdata_pids() {
868 myns="$(readlink /proc/self/ns/pid 2> /dev/null)"
869
870 for p in \
871 $(cat /var/run/netdata.pid 2> /dev/null) \
872 $(cat /var/run/netdata/netdata.pid 2> /dev/null) \
873 $(safe_pidof netdata 2> /dev/null); do
874 ns="$(readlink "/proc/${p}/ns/pid" 2> /dev/null)"
875
876 if [ -z "${myns}" ] || [ -z "${ns}" ] || [ "${myns}" = "${ns}" ]; then
877 pidisnetdata "${p}" && echo "${p}"
878 fi
879 done
880 }
881
882 stop_all_netdata() {
883 stop_success=0
884
885 if [ -x "${NETDATA_PREFIX}/usr/libexec/netdata/install-service.sh" ]; then
886 run_install_service_script --cmds-only
887 fi
888
889 if [ "${UID}" -eq 0 ]; then
890
891 uname="$(uname 2>/dev/null)"
892
893 # Any of these may fail, but we need to not bail if they do.
894 if [ -n "${NETDATA_STOP_CMD}" ]; then
895 if ${NETDATA_STOP_CMD}; then
896 stop_success=1
897 fi
898 elif issystemd; then
899 if systemctl stop netdata; then
900 stop_success=1
901 fi
902 elif [ "${uname}" = "Darwin" ]; then
903 if launchctl stop netdata; then
904 stop_success=1
905 fi
906 elif [ "${uname}" = "FreeBSD" ]; then
907 if /etc/rc.d/netdata stop; then
908 stop_success=1
909 fi
910 else
911 if service netdata stop; then
912 stop_success=1
913 fi
914 fi
915 fi
916
917 if [ "${stop_success}" = "1" ]; then
918 sleep 30
919
920 if [ -n "$(netdata_pids)" ]; then
921 stop_success=0
922 fi
923 fi
924
925 if [ "$stop_success" = "0" ]; then
926 if [ -n "$(netdata_pids)" ] && [ -n "$(command -v netdatacli)" ]; then
927 for p in /tmp/netdata-ipc /run/netdata/netdata.pipe /var/run/netdata/netdata.pipe /tmp/netdata/netdata.pipe; do
928 if [ -f "${p}" ]; then
929 NETDATA_PIPENAME="${p}" netdatacli shutdown-agent && break
930 fi
931 done
932
933 sleep 30
934 fi
935
936 for p in $(netdata_pids); do
937 # shellcheck disable=SC2086
938 stop_netdata_on_pid ${p}
939 done
940 fi
941 }
942
943 # -----------------------------------------------------------------------------
944 # restart netdata
945
946 restart_netdata() {
947 netdata="${1}"
948 shift
949
950 started=0
951
952 progress "Restarting netdata instance"
953
954 if [ -x "${NETDATA_PREFIX}/usr/libexec/netdata/install-service.sh" ]; then
955 run_install_service_script --cmds-only
956 fi
957
958 if [ -z "${NETDATA_INSTALLER_START_CMD}" ]; then
959 if [ -n "${NETDATA_START_CMD}" ]; then
960 NETDATA_INSTALLER_START_CMD="${NETDATA_START_CMD}"
961 else
962 NETDATA_INSTALLER_START_CMD="${netdata}"
963 fi
964 fi
965
966 if [ "${UID}" -eq 0 ]; then
967 echo >&2
968 echo >&2 "Stopping all netdata threads"
969 run stop_all_netdata
970
971 echo >&2 "Starting netdata using command '${NETDATA_INSTALLER_START_CMD}'"
972 # shellcheck disable=SC2086
973 run ${NETDATA_INSTALLER_START_CMD} && started=1
974
975 if [ ${started} -eq 1 ] && sleep 5 && [ -z "$(netdata_pids)" ]; then
976 echo >&2 "Ooops! it seems netdata is not started."
977 started=0
978 fi
979
980 if [ ${started} -eq 0 ]; then
981 echo >&2 "Attempting another netdata start using command '${NETDATA_INSTALLER_START_CMD}'"
982 # shellcheck disable=SC2086
983 run ${NETDATA_INSTALLER_START_CMD} && started=1
984 fi
985
986 if [ ${started} -eq 1 ] && sleep 5 && [ -z "$(netdata_pids)" ]; then
987 echo >&2 "Hm... it seems netdata is still not started."
988 started=0
989 fi
990 fi
991
992
993 if [ ${started} -eq 0 ]; then
994 # still not started... another forced attempt, just run the binary
995 warning "Netdata service still not started, attempting another forced restart by running '${netdata} ${*}'"
996 run stop_all_netdata
997 run "${netdata}" "${@}"
998 return $?
999 fi
1000
1001 return 0
1002 }
1003
1004 # -----------------------------------------------------------------------------
1005 # install netdata logrotate
1006
1007 install_netdata_logrotate() {
1008 src="${NETDATA_PREFIX}/usr/lib/netdata/system/logrotate/netdata"
1009
1010 if [ "${UID}" -eq 0 ]; then
1011 if [ -d /etc/logrotate.d ]; then
1012 if [ ! -f /etc/logrotate.d/netdata ]; then
1013 run cp "${src}" /etc/logrotate.d/netdata
1014 fi
1015
1016 if [ -f /etc/logrotate.d/netdata ]; then
1017 run chmod 644 /etc/logrotate.d/netdata
1018 fi
1019
1020 return 0
1021 fi
1022 fi
1023
1024 return 1
1025 }
1026
1027 # -----------------------------------------------------------------------------
1028 # install netdata journald configuration
1029
1030 install_netdata_journald_conf() {
1031 src="${NETDATA_PREFIX}/usr/lib/netdata/system/systemd/journald@netdata.conf"
1032
1033 [ ! -d /usr/lib/systemd/ ] && return 0
1034 [ "${UID}" -ne 0 ] && return 1
1035
1036 if [ ! -d /usr/lib/systemd/journald@netdata.conf.d/ ]; then
1037 run mkdir /usr/lib/systemd/journald@netdata.conf.d/
1038 fi
1039
1040 run cp "${src}" /usr/lib/systemd/journald@netdata.conf.d/netdata.conf
1041
1042 if [ -f /usr/lib/systemd/journald@netdata.conf.d/netdata.conf ]; then
1043 run chmod 644 /usr/lib/systemd/journald@netdata.conf.d/netdata.conf
1044 fi
1045
1046 return 0
1047 }
1048
1049 # -----------------------------------------------------------------------------
1050 # create netdata.conf
1051
1052 create_netdata_conf() {
1053 path="${1}"
1054 url="${2}"
1055
1056 if [ -s "${path}" ]; then
1057 return 0
1058 fi
1059
1060 if [ -n "$url" ]; then
1061 echo >&2 "Downloading default configuration from netdata..."
1062 sleep 5
1063
1064 # remove a possibly obsolete configuration file
1065 [ -f "${path}.new" ] && rm "${path}.new"
1066
1067 # disable a proxy to get data from the local netdata
1068 export http_proxy=
1069 export https_proxy=
1070
1071 check_for_curl
1072
1073 if [ -n "${curl}" ]; then
1074 run "${curl}" -sSL --connect-timeout 10 --retry 3 "${url}" > "${path}.new"
1075 elif command -v wget 1> /dev/null 2>&1; then
1076 run wget -T 15 -O - "${url}" > "${path}.new"
1077 fi
1078
1079 if [ -s "${path}.new" ]; then
1080 run mv "${path}.new" "${path}"
1081 run_ok "New configuration saved for you to edit at ${path}"
1082 else
1083 [ -f "${path}.new" ] && rm "${path}.new"
1084 run_failed "Cannot download configuration from netdata daemon using url '${url}'"
1085 url=''
1086 fi
1087 fi
1088
1089 if [ -z "$url" ]; then
1090 cat << EOF > "${path}"
1091 # netdata can generate its own config which is available at 'http://<IP>:19999/netdata.conf'
1092 # You can download it using:
1093 # curl -o ${path} http://localhost:19999/netdata.conf
1094 # or
1095 # wget -O ${path} http://localhost:19999/netdata.conf
1096 EOF
1097 fi
1098
1099 }
1100
1101 # -----------------------------------------------------------------------------
1102 # user handling functions
1103
1104 create_netdata_accounts() {
1105 NETDATA_WANTED_GROUPS="docker ceph I2C"
1106
1107 if [ -d "/etc/pve" ]; then
1108 NETDATA_WANTED_GROUPS="${NETDATA_WANTED_GROUPS} www-data"
1109 fi
1110 if [ -e "/dev/nvidiactl" ]; then
1111 NETDATA_WANTED_GROUPS="${NETDATA_WANTED_GROUPS} video"
1112 fi
1113
1114 if command -v systemd-sysusers >/dev/null 2>&1; then
1115 install -m 644 -o root -g root "${NETDATA_PREFIX}/usr/lib/netdata/system/systemd/sysusers/netdata.conf" /usr/lib/sysusers.d/netdata.conf
1116 systemd-sysusers /usr/lib/sysusers.d/netdata.conf
1117 else
1118 portable_add_group netdata || :
1119 portable_add_user netdata "${NETDATA_PREFIX}/var/lib/netdata" || :
1120 fi
1121
1122 for g in ${NETDATA_WANTED_GROUPS}; do
1123 # shellcheck disable=SC2086
1124 portable_add_user_to_group ${g} netdata && NETDATA_ADDED_TO_GROUPS="${NETDATA_ADDED_TO_GROUPS:-} ${g}"
1125 done
1126 }
1127
1128 portable_add_user() {
1129 username="${1}"
1130 homedir="${2}"
1131
1132 [ -z "${homedir}" ] && homedir="/tmp"
1133
1134 # Check if user exists
1135 if command -v getent > /dev/null 2>&1; then
1136 if getent passwd "${username}" > /dev/null 2>&1; then
1137 echo >&2 "User '${username}' already exists."
1138 return 0
1139 fi
1140 elif command -v dscl > /dev/null 2>&1; then
1141 if dscl . read /Users/"${username}" >/dev/null 2>&1; then
1142 echo >&2 "User '${username}' already exists."
1143 return 0
1144 fi
1145 else
1146 if cut -d ':' -f 1 < /etc/passwd | grep "^${username}$" 1> /dev/null 2>&1; then
1147 echo >&2 "User '${username}' already exists."
1148 return 0
1149 fi
1150 fi
1151
1152 echo >&2 "Adding ${username} user account with home ${homedir} ..."
1153
1154 nologin="$(command -v nologin || echo '/bin/false')"
1155
1156 if command -v useradd 1> /dev/null 2>&1; then
1157 run useradd -r -g "${username}" -c "${username}" -s "${nologin}" --no-create-home -d "${homedir}" "${username}" && return 0
1158 elif command -v pw 1> /dev/null 2>&1; then
1159 run pw useradd "${username}" -d "${homedir}" -g "${username}" -s "${nologin}" && return 0
1160 elif command -v adduser 1> /dev/null 2>&1; then
1161 run adduser -h "${homedir}" -s "${nologin}" -D -G "${username}" "${username}" && return 0
1162 elif command -v sysadminctl 1> /dev/null 2>&1; then
1163 gid=$(dscl . read /Groups/"${username}" 2>/dev/null | grep PrimaryGroupID | grep -Eo "[0-9]+")
1164 if run sysadminctl -addUser "${username}" -shell /usr/bin/false -home /var/empty -GID "$gid"; then
1165 # FIXME: I think the proper solution is to create a role account:
1166 # -roleAccount + name starting with _ and UID in 200-400 range.
1167 run dscl . create /Users/"${username}" IsHidden 1
1168 return 0
1169 fi
1170 elif command -v synouser 1> /dev/null 2>&1; then
1171 run synouser -add "${username}" "" "netdata agent" 0 "" 0 && return 0
1172 fi
1173
1174 warning "Failed to add ${username} user account!"
1175
1176 return 1
1177 }
1178
1179 portable_add_group() {
1180 groupname="${1}"
1181
1182 # Check if group exist
1183 if get_group "${groupname}" > /dev/null 2>&1; then
1184 echo >&2 "Group '${groupname}' already exists."
1185 return 0
1186 fi
1187
1188 echo >&2 "Adding ${groupname} user group ..."
1189
1190 # Linux
1191 if command -v groupadd 1> /dev/null 2>&1; then
1192 run groupadd -r "${groupname}" && return 0
1193 elif command -v pw 1> /dev/null 2>&1; then
1194 run pw groupadd "${groupname}" && return 0
1195 elif command -v addgroup 1> /dev/null 2>&1; then
1196 run addgroup "${groupname}" && return 0
1197 elif command -v dseditgroup 1> /dev/null 2>&1; then
1198 dseditgroup -o create "${groupname}" && return 0
1199 elif command -v synogroup 1> /dev/null 2>&1; then
1200 run synogroup --add "${groupname}" && return 0
1201 fi
1202
1203 warning >&2 "Failed to add ${groupname} user group !"
1204 return 1
1205 }
1206
1207 portable_add_user_to_group() {
1208 groupname="${1}"
1209 username="${2}"
1210
1211 # Check if group exist
1212 if ! get_group "${groupname}" > /dev/null 2>&1; then
1213 echo >&2 "Group '${groupname}' does not exist."
1214 # Don’t treat this as a failure, if the group does not exist we should not be trying to add the user to it.
1215 return 0
1216 fi
1217
1218 # Check if user is in group
1219 if get_group "${groupname}" | cut -d ':' -f 4 | grep -wq "${username}"; then
1220 # username is already there
1221 echo >&2 "User '${username}' is already in group '${groupname}'."
1222 return 0
1223 else
1224 # username is not in group
1225 echo >&2 "Adding ${username} user to the ${groupname} group ..."
1226
1227 # Linux
1228 if command -v usermod 1> /dev/null 2>&1; then
1229 run usermod -a -G "${groupname}" "${username}" && return 0
1230 elif command -v pw 1> /dev/null 2>&1; then
1231 run pw groupmod "${groupname}" -m "${username}" && return 0
1232 elif command -v addgroup 1> /dev/null 2>&1; then
1233 run addgroup "${username}" "${groupname}" && return 0
1234 elif command -v dseditgroup 1> /dev/null 2>&1; then
1235 dseditgroup -u "${username}" "${groupname}" && return 0
1236 elif command -v synogroup 1> /dev/null 2>&1; then
1237 # Get current members of the group
1238 current_members_list=$(synogroup --get "${groupname}" | grep '^[0-9]')
1239 current_members=$(echo "${current_members_list}" | grep -oP '\[\K[^\]]+' | tr '\n' ' ' | sed 's/ $//')
1240
1241 # Append username to the list
1242 if [ -n "$current_members" ]; then
1243 new_members="${current_members} ${username}"
1244 else
1245 new_members="${username}"
1246 fi
1247
1248 # Set the member list
1249 # shellcheck disable=SC2086
1250 run synogroup --member "${groupname}" ${new_members} && return 0
1251 fi
1252
1253 warning >&2 "Failed to add user ${username} to group ${groupname}!"
1254 return 1
1255 fi
1256 }
1257
1258 safe_sha256sum() {
1259 # Within the context of the installer, we only use -c option that is common between the two commands
1260 # We will have to reconsider if we start non-common options
1261 if command -v sha256sum > /dev/null 2>&1; then
1262 sha256sum "$@"
1263 elif command -v shasum > /dev/null 2>&1; then
1264 shasum -a 256 "$@"
1265 else
1266 fatal "I could not find a suitable checksum binary to use" "L0001"
1267 fi
1268 }
1269
1270 _get_scheduler_type() {
1271 if _get_intervaldir > /dev/null ; then
1272 echo 'interval'
1273 elif issystemd ; then
1274 echo 'systemd'
1275 elif [ -d /etc/cron.d ] ; then
1276 echo 'crontab'
1277 else
1278 echo 'none'
1279 fi
1280 }
1281
1282 _get_intervaldir() {
1283 if [ -d /etc/cron.daily ]; then
1284 echo /etc/cron.daily
1285 elif [ -d /etc/periodic/daily ]; then
1286 echo /etc/periodic/daily
1287 else
1288 return 1
1289 fi
1290
1291 return 0
1292 }
1293
1294 install_netdata_updater() {
1295 if [ "${INSTALLER_DIR}" ] && [ -f "${INSTALLER_DIR}/packaging/installer/netdata-updater.sh" ]; then
1296 cat "${INSTALLER_DIR}/packaging/installer/netdata-updater.sh" > "${NETDATA_PREFIX}/usr/libexec/netdata/netdata-updater.sh" || return 1
1297 fi
1298
1299 if [ "${NETDATA_SOURCE_DIR}" ] && [ -f "${NETDATA_SOURCE_DIR}/packaging/installer/netdata-updater.sh" ]; then
1300 cat "${NETDATA_SOURCE_DIR}/packaging/installer/netdata-updater.sh" > "${NETDATA_PREFIX}/usr/libexec/netdata/netdata-updater.sh" || return 1
1301 fi
1302
1303 # these files are installed by cmake
1304 libsysdir="${NETDATA_PREFIX}/usr/lib/netdata/system/systemd/"
1305 if [ -d "${libsysdir}" ] && issystemd && [ -n "$(get_systemd_service_dir)" ]; then
1306 cat "${libsysdir}/netdata-updater.timer" > "$(get_systemd_service_dir)/netdata-updater.timer"
1307 cat "${libsysdir}/netdata-updater.service" > "$(get_systemd_service_dir)/netdata-updater.service"
1308 fi
1309
1310 sed -i -e "s|THIS_SHOULD_BE_REPLACED_BY_INSTALLER_SCRIPT|${NETDATA_USER_CONFIG_DIR}/.environment|" "${NETDATA_PREFIX}/usr/libexec/netdata/netdata-updater.sh" || return 1
1311
1312 chmod 0755 "${NETDATA_PREFIX}/usr/libexec/netdata/netdata-updater.sh"
1313 echo >&2 "Update script is located at ${TPUT_GREEN}${TPUT_BOLD}${NETDATA_PREFIX}/usr/libexec/netdata/netdata-updater.sh${TPUT_RESET}"
1314 echo >&2
1315
1316 return 0
1317 }
1318
1319 set_netdata_updater_channel() {
1320 sed -i -e "s/^RELEASE_CHANNEL=.*/RELEASE_CHANNEL=\"${RELEASE_CHANNEL}\"/" "${NETDATA_USER_CONFIG_DIR}/.environment"
1321 }