@cryptotaxi247 / netdata-1 / commits / 981acd25e

Overhaul handling of installation of Netdata as a system service. (#13451)

* Install templated files from system directory on target system. This will allow more robust handling of auto-updates and installation of service files. * Add a script to handle installing Netdata as a system service. This uses the files installed as a result of the previous commit, and provides more robust detection and system handling than the existing code used for this purpose. A subsequent commit will convert the various installation mechanisms to use this script instead of their own internal code for this purpose. * Assorted cleanup and fixes for install-service.sh script. * Use new service install script on installs when present. * Fix missing .gitignore line. * Fix install command. * Integrate with warning handling in kickstart script. * Fix systemd version check. * Explicitly exit successfully when done. * Further fixes. * Fix handling of start commands on service install. * Fix handling of passing service commands in installer. * Fix handling of inability to detect service manager type. * Centralize install-service.sh invocation and improve error reporting. * Fix typos in Linux service handling.

Austin S. Hemmelgarn committed Oct 6, 2022 at 07:34 UTC 981acd25e01c0b18ae046bc6864550ecb95dc7ed
6 files changed +863 -75
.gitignore
+1
@@ -128,6 +128,7 @@ system/netdata.plist
128 system/netdata-freebsd
129 system/edit-config
130 system/netdata.crontab
131 +system/install-service.sh
132
133 daemon/anonymous-statistics.sh
134 daemon/get-kubernetes-labels.sh
build/subst.inc
+1
@@ -10,6 +10,7 @@
10 -e 's#[@]registrydir_POST@#$(registrydir)#g' \
11 -e 's#[@]varlibdir_POST@#$(varlibdir)#g' \
12 -e 's#[@]webdir_POST@#$(webdir)#g' \
13 + -e 's#[@]libsysdir_POST@#$(libsysdir)#g' \
14 -e 's#[@]enable_aclk_POST@#$(enable_aclk)#g' \
15 -e 's#[@]enable_cloud_POST@#$(enable_cloud)#g' \
16 $< > $@.tmp; then \
configure.ac
+2
@@ -1540,6 +1540,7 @@ configdir="${sysconfdir}/netdata"
1540 libconfigdir="${libdir}/netdata/conf.d"
1541 logdir="${localstatedir}/log/netdata"
1542 pluginsdir="${libexecdir}/netdata/plugins.d"
1543 +libsysdir="${libdir}/netdata/system"
1544
1545 AC_SUBST([varlibdir])
1546 AC_SUBST([registrydir])
@@ -1551,6 +1552,7 @@ AC_SUBST([libconfigdir])
1552 AC_SUBST([logdir])
1553 AC_SUBST([pluginsdir])
1554 AC_SUBST([webdir])
1555 +AC_SUBST([libsysdir])
1556
1557 CFLAGS="${originalCFLAGS} ${OPTIONAL_LTO_CFLAGS} ${OPTIONAL_PROTOBUF_CFLAGS} ${OPTIONAL_MATH_CFLAGS} ${OPTIONAL_NFACCT_CFLAGS} \
1558 ${OPTIONAL_ZLIB_CFLAGS} ${OPTIONAL_UUID_CFLAGS} \
packaging/installer/functions.sh
+148 -73
@@ -475,92 +475,149 @@ install_non_systemd_init() {
475 return 1
476 }
477
478 -# This is used by netdata-installer.sh
479 -# shellcheck disable=SC2034
480 -NETDATA_STOP_CMD="netdatacli shutdown-agent"
478 +run_install_service_script() {
479 + # shellcheck disable=SC2154
480 + save_path="${tmpdir}/netdata-service-cmds"
481 + # shellcheck disable=SC2068
482 + run "${NETDATA_PREFIX}/usr/libexec/netdata/install-service.sh" --save-cmds "${save_path}" ${@}
483 +
484 + case $? in
485 + 0)
486 + if [ -r "${save_path}" ]; then
487 + # shellcheck disable=SC1090
488 + . "${save_path}"
489 + fi
490
482 -NETDATA_START_CMD="netdata"
483 -NETDATA_INSTALLER_START_CMD=""
491 + if [ -z "${NETDATA_INSTALLER_START_CMD}" ]; then
492 + if [ -n "${NETDATA_START_CMD}" ]; then
493 + NETDATA_INSTALLER_START_CMD="${NETDATA_START_CMD}"
494 + else
495 + NETDATA_INSTALLER_START_CMD="netdata"
496 + fi
497 + fi
498 + ;;
499 + 1)
500 + if [ -z "${NETDATA_SERVICE_WARNED_1}" ]; then
501 + warning "Intenral error encountered while attempting to install or manage Netdata as a system service. This is probably a bug."
502 + NETDATA_SERVICE_WARNED_1=1
503 + fi
504 + ;;
505 + 2)
506 + if [ -z "${NETDATA_SERVICE_WARNED_2}" ]; then
507 + 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."
508 + NETDATA_SERVICE_WARNED_2=1
509 + fi
510 + ;;
511 + 3)
512 + if [ -z "${NETDATA_SERVICE_WARNED_3}" ]; then
513 + warning "Detected an unsupported system service manager. Manual setup will be required to manage Netdata as a system service."
514 + NETDATA_SERVICE_WARNED_3=1
515 + fi
516 + ;;
517 + 4)
518 + if [ -z "${NETDATA_SERVICE_WARNED_4}" ]; then
519 + 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."
520 + NETDATA_SERVICE_WARNED_4=1
521 + fi
522 + ;;
523 + 5)
524 + if [ -z "${NETDATA_SERVICE_WARNED_5}" ]; then
525 + warning "We do not support managing Netdata as a system service on this platform. Manual setup will be required."
526 + NETDATA_SERVICE_WARNED_5=1
527 + fi
528 + ;;
529 + esac
530 +}
531
532 install_netdata_service() {
486 - uname="$(uname 2> /dev/null)"
487 -
533 if [ "${UID}" -eq 0 ]; then
489 - if [ "${uname}" = "Darwin" ]; then
490 -
491 - if [ -f "/Library/LaunchDaemons/com.github.netdata.plist" ]; then
492 - echo >&2 "file '/Library/LaunchDaemons/com.github.netdata.plist' already exists."
493 - return 0
494 - else
495 - echo >&2 "Installing MacOS X plist file..."
496 - # This is used by netdata-installer.sh
497 - # shellcheck disable=SC2034
498 - run cp system/netdata.plist /Library/LaunchDaemons/com.github.netdata.plist &&
499 - run launchctl load /Library/LaunchDaemons/com.github.netdata.plist &&
500 - NETDATA_START_CMD="launchctl start com.github.netdata" &&
501 - NETDATA_STOP_CMD="launchctl stop com.github.netdata"
502 - return 0
503 - fi
504 -
505 - elif [ "${uname}" = "FreeBSD" ]; then
506 - # This is used by netdata-installer.sh
507 - # shellcheck disable=SC2034
508 - run cp system/netdata-freebsd /etc/rc.d/netdata && NETDATA_START_CMD="service netdata start" &&
509 - NETDATA_STOP_CMD="service netdata stop" &&
510 - NETDATA_INSTALLER_START_CMD="service netdata onestart" &&
511 - myret=$?
512 -
513 - echo >&2 "Note: To explicitly enable netdata automatic start, set 'netdata_enable' to 'YES' in /etc/rc.conf"
514 - echo >&2 ""
515 -
516 - return ${myret}
517 -
518 - elif issystemd; then
519 - # systemd is running on this system
520 - NETDATA_START_CMD="systemctl start netdata"
534 + if [ -x "${NETDATA_PREFIX}/usr/libexec/netdata/install-service.sh" ]; then
535 + run_install_service_script
536 + else
537 # This is used by netdata-installer.sh
538 # shellcheck disable=SC2034
523 - NETDATA_STOP_CMD="systemctl stop netdata"
524 - NETDATA_INSTALLER_START_CMD="${NETDATA_START_CMD}"
539 + NETDATA_STOP_CMD="netdatacli shutdown-agent"
540
526 - SYSTEMD_DIRECTORY="$(get_systemd_service_dir)"
541 + NETDATA_START_CMD="netdata"
542 + NETDATA_INSTALLER_START_CMD=""
543
528 - if [ "${SYSTEMD_DIRECTORY}x" != "x" ]; then
529 - ENABLE_NETDATA_IF_PREVIOUSLY_ENABLED="run systemctl enable netdata"
530 - IS_NETDATA_ENABLED="$(systemctl is-enabled netdata 2> /dev/null || echo "Netdata not there")"
531 - if [ "${IS_NETDATA_ENABLED}" = "disabled" ]; then
532 - echo >&2 "Netdata was there and disabled, make sure we don't re-enable it ourselves"
533 - ENABLE_NETDATA_IF_PREVIOUSLY_ENABLED="true"
534 - fi
544 + uname="$(uname 2> /dev/null)"
545
536 - echo >&2 "Installing systemd service..."
537 - run cp system/netdata.service "${SYSTEMD_DIRECTORY}/netdata.service" &&
538 - run systemctl daemon-reload &&
539 - ${ENABLE_NETDATA_IF_PREVIOUSLY_ENABLED} &&
546 + if [ "${uname}" = "Darwin" ]; then
547 + if [ -f "/Library/LaunchDaemons/com.github.netdata.plist" ]; then
548 + echo >&2 "file '/Library/LaunchDaemons/com.github.netdata.plist' already exists."
549 return 0
541 - else
542 - warning "Could not find a systemd service directory, unable to install Netdata systemd service."
543 - fi
544 - else
545 - install_non_systemd_init
546 - ret=$?
547 -
548 - if [ ${ret} -eq 0 ]; then
549 - if [ -n "${service_cmd}" ]; then
550 - NETDATA_START_CMD="service netdata start"
551 - # This is used by netdata-installer.sh
552 - # shellcheck disable=SC2034
553 - NETDATA_STOP_CMD="service netdata stop"
554 - elif [ -n "${rcservice_cmd}" ]; then
555 - NETDATA_START_CMD="rc-service netdata start"
550 + else
551 + echo >&2 "Installing MacOS X plist file..."
552 # This is used by netdata-installer.sh
553 # shellcheck disable=SC2034
558 - NETDATA_STOP_CMD="rc-service netdata stop"
554 + run cp system/netdata.plist /Library/LaunchDaemons/com.github.netdata.plist &&
555 + run launchctl load /Library/LaunchDaemons/com.github.netdata.plist &&
556 + NETDATA_START_CMD="launchctl start com.github.netdata" &&
557 + NETDATA_STOP_CMD="launchctl stop com.github.netdata"
558 + return 0
559 fi
560 +
561 + elif [ "${uname}" = "FreeBSD" ]; then
562 + # This is used by netdata-installer.sh
563 + # shellcheck disable=SC2034
564 + run cp system/netdata-freebsd /etc/rc.d/netdata && NETDATA_START_CMD="service netdata start" &&
565 + NETDATA_STOP_CMD="service netdata stop" &&
566 + NETDATA_INSTALLER_START_CMD="service netdata onestart" &&
567 + myret=$?
568 +
569 + echo >&2 "Note: To explicitly enable netdata automatic start, set 'netdata_enable' to 'YES' in /etc/rc.conf"
570 + echo >&2 ""
571 +
572 + return ${myret}
573 +
574 + elif issystemd; then
575 + # systemd is running on this system
576 + NETDATA_START_CMD="systemctl start netdata"
577 + # This is used by netdata-installer.sh
578 + # shellcheck disable=SC2034
579 + NETDATA_STOP_CMD="systemctl stop netdata"
580 NETDATA_INSTALLER_START_CMD="${NETDATA_START_CMD}"
561 - fi
581
563 - return ${ret}
582 + SYSTEMD_DIRECTORY="$(get_systemd_service_dir)"
583 +
584 + if [ "${SYSTEMD_DIRECTORY}x" != "x" ]; then
585 + ENABLE_NETDATA_IF_PREVIOUSLY_ENABLED="run systemctl enable netdata"
586 + IS_NETDATA_ENABLED="$(systemctl is-enabled netdata 2> /dev/null || echo "Netdata not there")"
587 + if [ "${IS_NETDATA_ENABLED}" = "disabled" ]; then
588 + echo >&2 "Netdata was there and disabled, make sure we don't re-enable it ourselves"
589 + ENABLE_NETDATA_IF_PREVIOUSLY_ENABLED="true"
590 + fi
591 +
592 + echo >&2 "Installing systemd service..."
593 + run cp system/netdata.service "${SYSTEMD_DIRECTORY}/netdata.service" &&
594 + run systemctl daemon-reload &&
595 + ${ENABLE_NETDATA_IF_PREVIOUSLY_ENABLED} &&
596 + return 0
597 + else
598 + warning "Could not find a systemd service directory, unable to install Netdata systemd service."
599 + fi
600 + else
601 + install_non_systemd_init
602 + ret=$?
603 +
604 + if [ ${ret} -eq 0 ]; then
605 + if [ -n "${service_cmd}" ]; then
606 + NETDATA_START_CMD="service netdata start"
607 + # This is used by netdata-installer.sh
608 + # shellcheck disable=SC2034
609 + NETDATA_STOP_CMD="service netdata stop"
610 + elif [ -n "${rcservice_cmd}" ]; then
611 + NETDATA_START_CMD="rc-service netdata start"
612 + # This is used by netdata-installer.sh
613 + # shellcheck disable=SC2034
614 + NETDATA_STOP_CMD="rc-service netdata stop"
615 + fi
616 + NETDATA_INSTALLER_START_CMD="${NETDATA_START_CMD}"
617 + fi
618 +
619 + return ${ret}
620 + fi
621 fi
622 fi
623
@@ -642,11 +699,21 @@ netdata_pids() {
699 stop_all_netdata() {
700 stop_success=0
701
702 + if [ -x "${NETDATA_PREFIX}/usr/libexec/netdata/install-service.sh" ]; then
703 + run_install_service_script --cmds-only
704 + fi
705 +
706 if [ "${UID}" -eq 0 ]; then
707 +
708 uname="$(uname 2>/dev/null)"
709
710 # Any of these may fail, but we need to not bail if they do.
649 - if issystemd; then
711 + if [ -n "${NETDATA_STOP_CMD}" ]; then
712 + if ${NETDATA_STOP_CMD}; then
713 + stop_success=1
714 + sleep 5
715 + fi
716 + elif issystemd; then
717 if systemctl stop netdata; then
718 stop_success=1
719 sleep 5
@@ -693,8 +760,16 @@ restart_netdata() {
760
761 progress "Restarting netdata instance"
762
763 + if [ -x "${NETDATA_PREFIX}/usr/libexec/netdata/install-service.sh" ]; then
764 + run_install_service_script --cmds-only
765 + fi
766 +
767 if [ -z "${NETDATA_INSTALLER_START_CMD}" ]; then
697 - NETDATA_INSTALLER_START_CMD="${netdata}"
768 + if [ -n "${NETDATA_START_CMD}" ]; then
769 + NETDATA_INSTALLER_START_CMD="${NETDATA_START_CMD}"
770 + else
771 + NETDATA_INSTALLER_START_CMD="${netdata}"
772 + fi
773 fi
774
775 if [ "${UID}" -eq 0 ]; then
system/Makefile.am
+12 -2
@@ -30,8 +30,14 @@ dist_config_DATA = \
30 # Explicitly install directories to avoid permission issues due to umask
31 install-exec-local:
32 $(INSTALL) -d $(DESTDIR)$(configdir)
33 + $(INSTALL) -d $(DESTDIR)$(libsysdir)
34
34 -nodist_noinst_DATA = \
35 +libexecnetdatadir=$(libexecdir)/netdata
36 +nodist_libexecnetdata_SCRIPTS = \
37 + install-service.sh \
38 + $(NULL)
39 +
40 +nodist_libsys_DATA = \
41 netdata-openrc \
42 netdata.logrotate \
43 netdata.service \
@@ -44,8 +50,13 @@ nodist_noinst_DATA = \
50 netdata-updater.service \
51 $(NULL)
52
53 +dist_libsys_DATA = \
54 + netdata-updater.timer \
55 + $(NULL)
56 +
57 dist_noinst_DATA = \
58 edit-config.in \
59 + install-service.sh.in \
60 netdata-openrc.in \
61 netdata.logrotate.in \
62 netdata.service.in \
@@ -57,5 +68,4 @@ dist_noinst_DATA = \
68 netdata.conf \
69 netdata.crontab.in \
70 netdata-updater.service.in \
60 - netdata-updater.timer \
71 $(NULL)
system/install-service.sh.in new
+699
@@ -0,0 +1,699 @@
1 +#!/usr/bin/env sh
2 +
3 +# SPDX-License-Identifier: GPL-3.0-or-later
4 +
5 +# Handle installation of the Netdata agent as a system service.
6 +#
7 +# Exit codes:
8 +# 0 - Successfully installed service.
9 +# 1 - Invalid arguments or other internal error.
10 +# 2 - Unable to detect system service type.
11 +# 3 - Detected system service type, but type not supported.
12 +# 4 - Detected system service type, but could not install due to other issues.
13 +# 5 - Platform not supported.
14 +
15 +set -e
16 +
17 +SCRIPT_SOURCE="$(
18 + self=${0}
19 + while [ -L "${self}" ]
20 + do
21 + cd "${self%/*}" || exit 1
22 + self=$(readlink "${self}")
23 + done
24 + cd "${self%/*}" || exit 1
25 + echo "$(pwd -P)/${self##*/}"
26 +)"
27 +
28 +DUMP_CMDS=0
29 +ENABLE="auto"
30 +EXPORT_CMDS=0
31 +INSTALL=1
32 +LINUX_INIT_TYPES="wsl systemd openrc lsb initd runit"
33 +PLATFORM="$(uname -s)"
34 +SVC_SOURCE="@libsysdir_POST@"
35 +SVC_TYPE="detect"
36 +
37 +# =====================================================================
38 +# Utility functions
39 +
40 +cleanup() {
41 + ec="${?}"
42 +
43 + if [ -n "${NETDATA_SAVE_WARNINGS}" ]; then
44 + if [ -n "${NETDATA_PROPAGATE_WARNINGS}" ]; then
45 + export NETDATA_WARNINGS="${NETDATA_WARNINGS}${SAVED_WARNINGS}"
46 + fi
47 + fi
48 +
49 + trap - EXIT
50 +
51 + exit "${ec}"
52 +}
53 +
54 +info() {
55 + printf >&2 "%s\n" "${*}"
56 +}
57 +
58 +warning() {
59 + if [ -n "${NETDATA_SAVE_WARNINGS}" ]; then
60 + SAVED_WARNINGS="${SAVED_WARNINGS}\n - ${*}"
61 + fi
62 + printf >&2 "WARNING: %s\n" "${*}"
63 +}
64 +
65 +error() {
66 + if [ -n "${NETDATA_SAVE_WARNINGS}" ]; then
67 + SAVED_WARNINGS="${SAVED_WARNINGS}\n - ${*}"
68 + fi
69 + printf >&2 "ERROR: %s\n" "${*}"
70 +}
71 +
72 +get_os_key() {
73 + if [ -f /etc/os-release ]; then
74 + # shellcheck disable=SC1091
75 + . /etc/os-release || return 1
76 + echo "${ID}-${VERSION_ID}"
77 +
78 + elif [ -f /etc/redhat-release ]; then
79 + cat /etc/redhat-release
80 + else
81 + echo "unknown"
82 + fi
83 +}
84 +
85 +valid_types() {
86 + case "${PLATFORM}" in
87 + Linux)
88 + echo "detect systemd openrc lsb initd"
89 + ;;
90 + FreeBSD)
91 + echo "detect freebsd"
92 + ;;
93 + Darwin)
94 + echo "detect launchd"
95 + ;;
96 + *)
97 + echo "detect"
98 + ;;
99 + esac
100 +}
101 +
102 +install_generic_service() {
103 + svc_type="${1}"
104 + svc_type_name="${2}"
105 + svc_file="${3}"
106 + svc_enable_hook="${4}"
107 + svc_disable_hook="${5}"
108 +
109 + info "Installing ${svc_type_name} service file."
110 + if [ ! -f "${svc_file}" ] && [ "${ENABLE}" = "auto" ]; then
111 + ENABLE="enable"
112 + fi
113 +
114 + if ! install -p -m 0755 -o 0 -g 0 "${SVC_SOURCE}/netdata-${svc_type}" /etc/init.d/netdata; then
115 + error "Failed to install service file."
116 + exit 4
117 + fi
118 +
119 + case "${ENABLE}" in
120 + auto) true ;;
121 + disable)
122 + info "Disabling Netdata service."
123 + ${svc_disable_hook}
124 + ;;
125 + enable)
126 + info "Enabling Netdata service."
127 + ${svc_enable_hook}
128 + ;;
129 + esac
130 +}
131 +
132 +dump_cmds() {
133 + [ -n "${NETDATA_START_CMD}" ] && echo "NETDATA_START_CMD='${NETDATA_START_CMD}'"
134 + [ -n "${NETDATA_STOP_CMD}" ] && echo "NETDATA_STOP_CMD='${NETDATA_STOP_CMD}'"
135 + [ -n "${NETDATA_INSTALLER_START_CMD}" ] && echo "NETDATA_INSTALLER_START_CMD='${NETDATA_INSTALLER_START_CMD}'"
136 + return 0
137 +}
138 +
139 +export_cmds() {
140 + [ -n "${NETDATA_START_CMD}" ] && export NETDATA_START_CMD="${NETDATA_START_CMD}"
141 + [ -n "${NETDATA_STOP_CMD}" ] && export NETDATA_STOP_CMD="${NETDATA_STOP_CMD}"
142 + [ -n "${NETDATA_INSTALLER_START_CMD}" ] && export NETDATA_INSTALLER_START_CMD="${NETDATA_INSTALLER_START_COMMAND}"
143 + return 0
144 +}
145 +
146 +save_cmds() {
147 + dump_cmds > "${SAVE_CMDS_PATH}"
148 +}
149 +
150 +# =====================================================================
151 +# Help functions
152 +
153 +usage() {
154 + cat << HEREDOC
155 +USAGE: install-service.sh [options]
156 + where options include:
157 +
158 + --source Specify where to find the service files to install (default ${SVC_SOURCE}).
159 + --type Specify the type of service file to install. Specify a type of 'help' to get a list of valid types for your platform.
160 + --cmds Additionally print a list of commands for starting and stopping the agent with the detected service type.
161 + --export-cmds Export the variables that would be printed by the --cmds option.
162 + --cmds-only Don't install, just handle the --cmds or --export-cmds option.
163 + --enable Explicitly enable the service on install (default is to enable if not already installed).
164 + --disable Explicitly disable the service on install.
165 + --help Print this help information.
166 +HEREDOC
167 +}
168 +
169 +help_types() {
170 + cat << HEREDOC
171 +Valid service types for ${PLATFORM} are:
172 +$(valid_types)
173 +HEREDOC
174 +}
175 +
176 +# =====================================================================
177 +# systemd support functions
178 +
179 +issystemd() {
180 + pids=''
181 + p=''
182 + myns=''
183 + ns=''
184 + systemctl=''
185 +
186 + # if the directory /lib/systemd/system OR /usr/lib/systemd/system (SLES 12.x) does not exit, it is not systemd
187 + if [ ! -d /lib/systemd/system ] && [ ! -d /usr/lib/systemd/system ]; then
188 + return 1
189 + fi
190 +
191 + # if there is no systemctl command, it is not systemd
192 + systemctl=$(command -v systemctl 2> /dev/null)
193 + if [ -z "${systemctl}" ] || [ ! -x "${systemctl}" ]; then
194 + return 1
195 + fi
196 +
197 + # if pid 1 is systemd, it is systemd
198 + [ "$(basename "$(readlink /proc/1/exe)" 2> /dev/null)" = "systemd" ] && return 0
199 +
200 + # if systemd is not running, it is not systemd
201 + pids=$(safe_pidof systemd 2> /dev/null)
202 + [ -z "${pids}" ] && return 1
203 +
204 + # check if the running systemd processes are not in our namespace
205 + myns="$(readlink /proc/self/ns/pid 2> /dev/null)"
206 + for p in ${pids}; do
207 + ns="$(readlink "/proc/${p}/ns/pid" 2> /dev/null)"
208 +
209 + # if pid of systemd is in our namespace, it is systemd
210 + [ -n "${myns}" ] && [ "${myns}" = "${ns}" ] && return 0
211 + done
212 +
213 + # else, it is not systemd
214 + return 1
215 +}
216 +
217 +check_systemd() {
218 + if [ -z "${IS_SYSTEMD}" ]; then
219 + issystemd
220 + IS_SYSTEMD="$?"
221 + fi
222 +
223 + return "${IS_SYSTEMD}"
224 +}
225 +
226 +get_systemd_service_dir() {
227 + if [ -w "/lib/systemd/system" ]; then
228 + echo "/lib/systemd/system"
229 + elif [ -w "/usr/lib/systemd/system" ]; then
230 + echo "/usr/lib/systemd/system"
231 + elif [ -w "/etc/systemd/system" ]; then
232 + echo "/etc/systemd/system"
233 + else
234 + error "Unable to detect systemd service directory."
235 + exit 4
236 + fi
237 +}
238 +
239 +install_systemd_service() {
240 + SRCFILE="${SVC_SOURCE}/netdata.service"
241 +
242 + if [ "$(systemctl --version | head -n 1 | cut -f 2 -d ' ')" -le 235 ]; then
243 + SRCFILE="${SVC_SOURCE}/netdata.service.v235"
244 + fi
245 +
246 + if [ "${ENABLE}" = "auto" ]; then
247 + IS_NETDATA_ENABLED="$(systemctl is-enabled netdata 2> /dev/null || echo "Netdata not there")"
248 +
249 + if [ "${IS_NETDATA_ENABLED}" = "disabled" ]; then
250 + ENABLE="disable"
251 + else
252 + ENABLE="enable"
253 + fi
254 + fi
255 +
256 + info "Installing systemd service..."
257 + if ! install -p -m 0644 -o 0 -g 0 "${SRCFILE}" "$(get_systemd_service_dir)/netdata.service"; then
258 + error "Failed to install systemd service file."
259 + exit 4
260 + fi
261 +
262 + if ! systemctl daemon-reload; then
263 + warning "Failed to reload systemd unit files."
264 + fi
265 +
266 + if ! systemctl ${ENABLE} netdata; then
267 + warning "Failed to ${ENABLE} Netdata service."
268 + fi
269 +}
270 +
271 +systemd_cmds() {
272 + NETDATA_START_CMD='systemctl start netdata'
273 + NETDATA_STOP_CMD='systemctl stop netdata'
274 +}
275 +
276 +# =====================================================================
277 +# OpenRC support functions
278 +
279 +isopenrc() {
280 + # if /lib/rc/sh/functions.sh does not exist, it's not OpenRC
281 + [ ! -f /lib/rc/sh/functions.sh ] && return 1
282 +
283 + # if there is no /etc/init.d, it's not OpenRC
284 + [ ! -d /etc/init.d ] && return 1
285 +
286 + # if PID 1 is openrc-init, it's OpenRC
287 + [ "$(basename "$(readlink /proc/1/exe)" 2> /dev/null)" = "openrc-init" ] && return 0
288 +
289 + # If /run/openrc/softlevel exists, it's OpenRC
290 + [ -f /run/openrc/softlevel ] && return 0
291 +
292 + # if there is an openrc command, it's OpenRC
293 + command -v openrc > /dev/null 2>&1 && return 0
294 +
295 + # Otherwise, it’s not OpenRC
296 + return 1
297 +}
298 +
299 +check_openrc() {
300 + if [ -z "${IS_OPENRC}" ]; then
301 + isopenrc
302 + IS_OPENRC="$?"
303 + fi
304 +
305 + return "${IS_OPENRC}"
306 +}
307 +
308 +enable_openrc() {
309 + runlevel="$(rc-status -r)"
310 + runlevel="${runlevel:-default}"
311 + if ! rc-update add netdata "${runlevel}"; then
312 + warning "Failed to enable Netdata service in runlevel ${runlevel}."
313 + fi
314 +}
315 +
316 +disable_openrc() {
317 + for runlevel in /etc/runlevels/*; do
318 + if [ -e "${runlevel}/netdata" ]; then
319 + runlevel="$(basename "${runlevel}")"
320 + if ! rc-update del netdata "${runlevel}"; then
321 + warning "Failed to disable Netdata service in runlevel ${runlevel}."
322 + fi
323 + fi
324 + done
325 +}
326 +
327 +install_openrc_service() {
328 + install_generic_service openrc OpenRC /etc/init.d/netdata enable_openrc disable_openrc
329 +}
330 +
331 +openrc_cmds() {
332 + NETDATA_START_CMD='rc-service netdata start'
333 + NETDATA_STOP_CMD='rc-service netdata stop'
334 +}
335 +
336 +# =====================================================================
337 +# LSB init script support functions
338 +
339 +islsb() {
340 + # if there is no /etc/init.d directory, it’s not an LSB system
341 + [ ! -d /etc/init.d ] && return 1
342 +
343 + # If it's an OpenRC system, then it's not an LSB system
344 + check_openrc && return 1
345 +
346 + # If /lib/lsb/init-functions exists, it’s an LSB system
347 + [ -f /lib/lsb/init-functions ] && return 0
348 +
349 + return 1
350 +}
351 +
352 +check_lsb() {
353 + if [ -z "${IS_LSB}" ]; then
354 + islsb
355 + IS_LSB="$?"
356 + fi
357 +
358 + return "${IS_LSB}"
359 +}
360 +
361 +enable_lsb() {
362 + if ! update-rc.d netdata defaults; then
363 + warning "Failed to enable Netdata service."
364 + elif ! update-rc.d netdata defaults-disable; then
365 + warning "Failed to fully enable Netdata service."
366 + fi
367 +}
368 +
369 +disable_lsb() {
370 + if ! update-rc.d netdata remove; then
371 + warning "Failed to disable Netdata service."
372 + fi
373 +}
374 +
375 +install_lsb_service() {
376 + install_generic_service lsb LSB /etc/init.d/netdata enable_lsb disable_lsb
377 +}
378 +
379 +lsb_cmds() {
380 + if command -v service >/dev/null 2>&1; then
381 + NETDATA_START_CMD='service netdata start'
382 + NETDATA_STOP_CMD='service netdata stop'
383 + else
384 + NETDATA_START_CMD='/etc/init.d/netdata start'
385 + NETDATA_STOP_CMD='/etc/init.d/netdata stop'
386 + fi
387 +}
388 +
389 +# =====================================================================
390 +# init.d init script support functions
391 +
392 +isinitd() {
393 + # if there is no /etc/init.d directory, it’s not an init.d system
394 + [ ! -d /etc/init.d ] && return 1
395 +
396 + # if there is no chkconfig command, it's not a (usable) init.d system
397 + command -v chkconfig >/dev/null 2>&1 || return 1
398 +
399 + # if it's not an LSB setup, it’s init.d
400 + check_initd || return 0
401 +
402 + return 1
403 +}
404 +
405 +check_initd() {
406 + if [ -z "${IS_INITD}" ]; then
407 + isinitd
408 + IS_INITD="$?"
409 + fi
410 +
411 + return "${IS_INITD}"
412 +}
413 +
414 +enable_initd() {
415 + if ! chkconfig netdata on; then
416 + warning "Failed to enable Netdata service."
417 + fi
418 +}
419 +
420 +disable_initd() {
421 + if ! chkconfig netdata off; then
422 + warning "Failed to disable Netdata service."
423 + fi
424 +}
425 +
426 +install_initd_service() {
427 + install_generic_service init-d init.d /etc/init.d/netdata enable_initd disable_initd
428 +}
429 +
430 +initd_cmds() {
431 + if command -v service >/dev/null 2>&1; then
432 + NETDATA_START_CMD='service netdata start'
433 + NETDATA_STOP_CMD='service netdata stop'
434 + else
435 + NETDATA_START_CMD='/etc/init.d/netdata start'
436 + NETDATA_STOP_CMD='/etc/init.d/netdata stop'
437 + fi
438 +}
439 +
440 +# =====================================================================
441 +# runit support functions
442 +#
443 +# Currently not supported, this exists to provide useful error messages.
444 +
445 +isrunit() {
446 + # if there is no /lib/rc/sv.d, then it's not runit
447 + [ ! -d /lib/rc/sv.d ] && return 1
448 +
449 + # if there is no runit command, then it's not runit
450 + command -v runit >/dev/null 2>&1 || return 1
451 +
452 + # if /run/runit exists, then it's runit
453 + [ -d /run/runit ] && return 0
454 +
455 + # if /etc/runit/1 exists and is executable, then it's runit
456 + [ -x /etc/runit/1 ] && return 0
457 +
458 + return 1
459 +}
460 +
461 +check_runit() {
462 + if [ -z "${IS_RUNIT}" ]; then
463 + isrunit
464 + IS_RUNIT="$?"
465 + fi
466 +
467 + return "${IS_RUNIT}"
468 +}
469 +
470 +install_runit_service() {
471 + error "Detected runit, which we do not currently support."
472 + exit 3
473 +}
474 +
475 +runit_cmds() {
476 + error "Detected runit, which we do not currently support."
477 + exit 3
478 +}
479 +
480 +# =====================================================================
481 +# WSL support functions
482 +#
483 +# Cannot be supported, this exists to provide useful error messages.
484 +
485 +iswsl() {
486 + # If uname -r contains the string WSL, then it's WSL.
487 + uname -r | grep -q 'WSL' && return 0
488 +
489 + # If uname -r contains the string Microsoft, then it's WSL.
490 + # This probably throws a false positive on CBL-Mariner, but it's part of what MS officially recommends for
491 + # detecting if you're running under WSL.
492 + uname -r | grep -q "Microsoft" && return 0
493 +
494 + return 1
495 +}
496 +
497 +check_wsl() {
498 + if [ -z "${IS_WSL}" ]; then
499 + iswsl
500 + IS_WSL="$?"
501 + fi
502 +
503 + return "${IS_WSL}"
504 +}
505 +
506 +install_wsl_service() {
507 + error "We appear to be running in WSL. Netdata cannot be automatically installed as a service under WSL."
508 + exit 3
509 +}
510 +
511 +wsl_cmds() {
512 + error "We appear to be running in WSL. Netdata cannot be automatically installed as a service under WSL."
513 + exit 3
514 +}
515 +
516 +# =====================================================================
517 +# FreeBSD support functions
518 +
519 +enable_freebsd() {
520 + if ! sysrc netdata_enable=YES; then
521 + warning "Failed to enable netdata service."
522 + fi
523 +}
524 +
525 +disable_freebsd() {
526 + if ! sysrc netdata_enable=NO; then
527 + warning "Failed to disable netdata service."
528 + fi
529 +}
530 +
531 +install_freebsd_service() {
532 + install_generic_service freebsd "FreeBSD rc.d" /usr/local/etc/rc.d/netdata enable_freebsd disable_freebsd
533 +}
534 +
535 +freebsd_cmds() {
536 + NETDATA_START_CMD='service netdata start'
537 + NETDATA_STOP_CMD='service netdata stop'
538 + NETDATA_INSTALLER_START_CMD='service netdata onestart'
539 +}
540 +
541 +# =====================================================================
542 +# macOS support functions
543 +
544 +install_darwin_service() {
545 + info "Installing macOS plist file for launchd."
546 + if ! install -C -S -p -m 0644 -o 0 -g 0 system/netdata.plist /Library/LaunchDaemons/com.github.netdata.plist; then
547 + error "Failed to copy plist file."
548 + exit 4
549 + fi
550 +
551 + if ! launchctl load /Library/LaunchDaemons/com.github.netdata.plist; then
552 + error "Failed to load plist file."
553 + exit 4
554 + fi
555 +}
556 +
557 +darwin_cmds() {
558 + NETDATA_START_CMD='launchctl start com.github.netdata'
559 + NETDATA_STOP_CMD='launchctl stop com.github.netdata'
560 +}
561 +
562 +# =====================================================================
563 +# Linux support functions
564 +
565 +detect_linux_svc_type() {
566 + if [ "${SVC_TYPE}" = "detect" ]; then
567 + for t in ${LINUX_INIT_TYPES}; do
568 + if "check_${t}"; then
569 + SVC_TYPE="${t}"
570 + break
571 + fi
572 + done
573 +
574 + if [ "${SVC_TYPE}" = "detect" ]; then
575 + error "Failed to detect what type of service manager is in use."
576 + else
577 + echo "${SVC_TYPE}"
578 + fi
579 + else
580 + echo "${SVC_TYPE}"
581 + fi
582 +}
583 +
584 +install_linux_service() {
585 + t="$(detect_linux_svc_type)"
586 +
587 + if [ -z "${t}" ]; then
588 + exit 2
589 + fi
590 +
591 + "install_${t}_service"
592 +}
593 +
594 +linux_cmds() {
595 + t="$(detect_linux_svc_type)"
596 +
597 + if [ -z "${t}" ]; then
598 + exit 2
599 + fi
600 +
601 + "${t}_cmds"
602 +}
603 +
604 +# =====================================================================
605 +# Argument handling
606 +
607 +parse_args() {
608 + while [ -n "${1}" ]; do
609 + case "${1}" in
610 + "--source" | "-s")
611 + SVC_SOURCE="${2}"
612 + shift 1
613 + ;;
614 + "--type" | "-t")
615 + if [ "${2}" = "help" ]; then
616 + help_types
617 + exit 0
618 + else
619 + SVC_TYPE="${2}"
620 + shift 1
621 + fi
622 + ;;
623 + "--save-cmds")
624 + if [ -z "${2}" ]; then
625 + info "No path specified to save command variables."
626 + exit 1
627 + else
628 + SAVE_CMDS_PATH="${2}"
629 + shift 1
630 + fi
631 + ;;
632 + "--cmds" | "-c") DUMP_CMDS=1 ;;
633 + "--cmds-only") INSTALL=0 ;;
634 + "--export-cmds") EXPORT_CMDS=1 ;;
635 + "--enable" | "-e") ENABLE="enable" ;;
636 + "--disable" | "-d") ENABLE="disable" ;;
637 + "--help" | "-h")
638 + usage
639 + exit 0
640 + ;;
641 + *)
642 + info "Unrecognized option '${1}'."
643 + exit 1
644 + ;;
645 + esac
646 + shift 1
647 + done
648 +
649 + if [ "${SVC_SOURCE#@}" = "libsysdir_POST@" ]; then
650 + SVC_SOURCE="$(dirname "${SCRIPT_SOURCE}")/../../lib/netdata/system"
651 + warning "SVC_SOURCE not templated, using ${SVC_SOURCE} as source directory."
652 + fi
653 +
654 + if [ ! -d "${SVC_SOURCE}" ] && [ "${INSTALL}" -eq 1 ]; then
655 + error "${SVC_SOURCE} does not appear to be a directory. Please specify a valid source for service files with the --source option."
656 + exit 1
657 + fi
658 +
659 + if valid_types | grep -vw "${SVC_TYPE}"; then
660 + error "${SVC_TYPE} is not supported on this platform."
661 + help_types
662 + exit 1
663 + fi
664 +}
665 +
666 +# =====================================================================
667 +# Core logic
668 +
669 +main() {
670 + trap "cleanup" EXIT
671 +
672 + parse_args "${@}"
673 +
674 + case "${PLATFORM}" in
675 + FreeBSD)
676 + [ "${INSTALL}" -eq 1 ] && install_freebsd_service
677 + freebsd_cmds
678 + ;;
679 + Darwin)
680 + [ "${INSTALL}" -eq 1 ] && install_darwin_service
681 + darwin_cmds
682 + ;;
683 + Linux)
684 + [ "${INSTALL}" -eq 1 ] && install_linux_service
685 + linux_cmds
686 + ;;
687 + *)
688 + error "${PLATFORM} is not supported by this script."
689 + exit 5
690 + ;;
691 + esac
692 +
693 + [ "${DUMP_CMDS}" -eq 1 ] && dump_cmds
694 + [ "${EXPORT_CMDS}" -eq 1 ] && export_cmds
695 + [ -n "${SAVE_CMDS_PATH}" ] && save_cmds
696 + exit 0
697 +}
698 +
699 +main "${@}"