summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--build/subst.inc1
-rw-r--r--configure.ac2
-rw-r--r--packaging/installer/functions.sh221
-rw-r--r--system/Makefile.am14
-rwxr-xr-xsystem/install-service.sh.in699
6 files changed, 863 insertions, 75 deletions
diff --git a/.gitignore b/.gitignore
index 275b5d0076..b90428a14f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -128,6 +128,7 @@ system/netdata.plist
system/netdata-freebsd
system/edit-config
system/netdata.crontab
+system/install-service.sh
daemon/anonymous-statistics.sh
daemon/get-kubernetes-labels.sh
diff --git a/build/subst.inc b/build/subst.inc
index cc8825e247..f51f47074d 100644
--- a/build/subst.inc
+++ b/build/subst.inc
@@ -10,6 +10,7 @@
-e 's#[@]registrydir_POST@#$(registrydir)#g' \
-e 's#[@]varlibdir_POST@#$(varlibdir)#g' \
-e 's#[@]webdir_POST@#$(webdir)#g' \
+ -e 's#[@]libsysdir_POST@#$(libsysdir)#g' \
-e 's#[@]enable_aclk_POST@#$(enable_aclk)#g' \
-e 's#[@]enable_cloud_POST@#$(enable_cloud)#g' \
$< > $@.tmp; then \
diff --git a/configure.ac b/configure.ac
index ef060a91f8..e2c73e28b2 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1540,6 +1540,7 @@ configdir="${sysconfdir}/netdata"
libconfigdir="${libdir}/netdata/conf.d"
logdir="${localstatedir}/log/netdata"
pluginsdir="${libexecdir}/netdata/plugins.d"
+libsysdir="${libdir}/netdata/system"
AC_SUBST([varlibdir])
AC_SUBST([registrydir])
@@ -1551,6 +1552,7 @@ AC_SUBST([libconfigdir])
AC_SUBST([logdir])
AC_SUBST([pluginsdir])
AC_SUBST([webdir])
+AC_SUBST([libsysdir])
CFLAGS="${originalCFLAGS} ${OPTIONAL_LTO_CFLAGS} ${OPTIONAL_PROTOBUF_CFLAGS} ${OPTIONAL_MATH_CFLAGS} ${OPTIONAL_NFACCT_CFLAGS} \
${OPTIONAL_ZLIB_CFLAGS} ${OPTIONAL_UUID_CFLAGS} \
diff --git a/packaging/installer/functions.sh b/packaging/installer/functions.sh
index 8bf7fafcfa..c3fb25bcea 100644
--- a/packaging/installer/functions.sh
+++ b/packaging/installer/functions.sh
@@ -475,92 +475,149 @@ install_non_systemd_init() {
return 1
}
-# This is used by netdata-installer.sh
-# shellcheck disable=SC2034
-NETDATA_STOP_CMD="netdatacli shutdown-agent"
+run_install_service_script() {
+ # shellcheck disable=SC2154
+ save_path="${tmpdir}/netdata-service-cmds"
+ # shellcheck disable=SC2068
+ run "${NETDATA_PREFIX}/usr/libexec/netdata/install-service.sh" --save-cmds "${save_path}" ${@}
+
+ case $? in
+ 0)
+ if [ -r "${save_path}" ]; then
+ # shellcheck disable=SC1090
+ . "${save_path}"
+ fi
-NETDATA_START_CMD="netdata"
-NETDATA_INSTALLER_START_CMD=""
+ if [ -z "${NETDATA_INSTALLER_START_CMD}" ]; then
+ if [ -n "${NETDATA_START_CMD}" ]; then
+ NETDATA_INSTALLER_START_CMD="${NETDATA_START_CMD}"
+ else
+ NETDATA_INSTALLER_START_CMD="netdata"
+ fi
+ fi
+ ;;
+ 1)
+ if [ -z "${NETDATA_SERVICE_WARNED_1}" ]; then
+ warning "Intenral error encountered while attempting to install or manage Netdata as a system service. This is probably a bug."
+ NETDATA_SERVICE_WARNED_1=1
+ fi
+ ;;
+ 2)
+ if [ -z "${NETDATA_SERVICE_WARNED_2}" ]; then
+ 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."
+ NETDATA_SERVICE_WARNED_2=1
+ fi
+ ;;
+ 3)
+ if [ -z "${NETDATA_SERVICE_WARNED_3}" ]; then
+ warning "Detected an unsupported system service manager. Manual setup will be required to manage Netdata as a system service."
+ NETDATA_SERVICE_WARNED_3=1
+ fi
+ ;;
+ 4)
+ if [ -z "${NETDATA_SERVICE_WARNED_4}" ]; then
+ 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."
+ NETDATA_SERVICE_WARNED_4=1
+ fi
+ ;;
+ 5)
+ if [ -z "${NETDATA_SERVICE_WARNED_5}" ]; then
+ warning "We do not support managing Netdata as a system service on this platform. Manual setup will be required."
+ NETDATA_SERVICE_WARNED_5=1
+ fi
+ ;;
+ esac
+}
install_netdata_service() {
- uname="$(uname 2> /dev/null)"
-
if [ "${UID}" -eq 0 ]; then
- if [ "${uname}" = "Darwin" ]; then
-
- if [ -f "/Library/LaunchDaemons/com.github.netdata.plist" ]; then
- echo >&2 "file '/Library/LaunchDaemons/com.github.netdata.plist' already exists."
- return 0
- else
- echo >&2 "Installing MacOS X plist file..."
- # This is used by netdata-installer.sh
- # shellcheck disable=SC2034
- run cp system/netdata.plist /Library/LaunchDaemons/com.github.netdata.plist &&
- run launchctl load /Library/LaunchDaemons/com.github.netdata.plist &&
- NETDATA_START_CMD="launchctl start com.github.netdata" &&
- NETDATA_STOP_CMD="launchctl stop com.github.netdata"
- return 0
- fi
-
- elif [ "${uname}" = "FreeBSD" ]; then
- # This is used by netdata-installer.sh
- # shellcheck disable=SC2034
- run cp system/netdata-freebsd /etc/rc.d/netdata && NETDATA_START_CMD="service netdata start" &&
- NETDATA_STOP_CMD="service netdata stop" &&
- NETDATA_INSTALLER_START_CMD="service netdata onestart" &&
- myret=$?
-
- echo >&2 "Note: To explicitly enable netdata automatic start, set 'netdata_enable' to 'YES' in /etc/rc.conf"
- echo >&2 ""
-
- return ${myret}
-
- elif issystemd; then
- # systemd is running on this system
- NETDATA_START_CMD="systemctl start netdata"
+ if [ -x "${NETDATA_PREFIX}/usr/libexec/netdata/install-service.sh" ]; then
+ run_install_service_script
+ else
# This is used by netdata-installer.sh
# shellcheck disable=SC2034
- NETDATA_STOP_CMD="systemctl stop netdata"
- NETDATA_INSTALLER_START_CMD="${NETDATA_START_CMD}"
+ NETDATA_STOP_CMD="netdatacli shutdown-agent"
- SYSTEMD_DIRECTORY="$(get_systemd_service_dir)"
+ NETDATA_START_CMD="netdata"
+ NETDATA_INSTALLER_START_CMD=""
- if [ "${SYSTEMD_DIRECTORY}x" != "x" ]; then
- ENABLE_NETDATA_IF_PREVIOUSLY_ENABLED="run systemctl enable netdata"
- IS_NETDATA_ENABLED="$(systemctl is-enabled netdata 2> /dev/null || echo "Netdata not there")"
- if [ "${IS_NETDATA_ENABLED}" = "disabled" ]; then
- echo >&2 "Netdata was there and disabled, make sure we don't re-enable it ourselves"
- ENABLE_NETDATA_IF_PREVIOUSLY_ENABLED="true"
- fi
+ uname="$(uname 2> /dev/null)"
- echo >&2 "Installing systemd service..."
- run cp system/netdata.service "${SYSTEMD_DIRECTORY}/netdata.service" &&
- run systemctl daemon-reload &&
- ${ENABLE_NETDATA_IF_PREVIOUSLY_ENABLED} &&
+ if [ "${uname}" = "Darwin" ]; then
+ if [ -f "/Library/LaunchDaemons/com.github.netdata.plist" ]; then
+ echo >&2 "file '/Library/LaunchDaemons/com.github.netdata.plist' already exists."
return 0
- else
- warning "Could not find a systemd service directory, unable to install Netdata systemd service."
- fi
- else
- install_non_systemd_init
- ret=$?
-
- if [ ${ret} -eq 0 ]; then
- if [ -n "${service_cmd}" ]; then
- NETDATA_START_CMD="service netdata start"
- # This is used by netdata-installer.sh
- # shellcheck disable=SC2034
- NETDATA_STOP_CMD="service netdata stop"
- elif [ -n "${rcservice_cmd}" ]; then
- NETDATA_START_CMD="rc-service netdata start"
+ else
+ echo >&2 "Installing MacOS X plist file..."
# This is used by netdata-installer.sh
# shellcheck disable=SC2034
- NETDATA_STOP_CMD="rc-service netdata stop"
+ run cp system/netdata.plist /Library/LaunchDaemons/com.github.netdata.plist &&
+ run launchctl load /Library/LaunchDaemons/com.github.netdata.plist &&
+ NETDATA_START_CMD="launchctl start com.github.netdata" &&
+ NETDATA_STOP_CMD="launchctl stop com.github.netdata"
+ return 0
fi
+
+ elif [ "${uname}" = "FreeBSD" ]; then
+ # This is used by netdata-installer.sh
+ # shellcheck disable=SC2034
+ run cp system/netdata-freebsd /etc/rc.d/netdata && NETDATA_START_CMD="service netdata start" &&
+ NETDATA_STOP_CMD="service netdata stop" &&
+ NETDATA_INSTALLER_START_CMD="service netdata onestart" &&
+ myret=$?
+
+ echo >&2 "Note: To explicitly enable netdata automatic start, set 'netdata_enable' to 'YES' in /etc/rc.conf"
+ echo >&2 ""
+
+ return ${myret}
+
+ elif issystemd; then
+ # systemd is running on this system
+ NETDATA_START_CMD="systemctl start netdata"
+ # This is used by netdata-installer.sh
+ # shellcheck disable=SC2034
+ NETDATA_STOP_CMD="systemctl stop netdata"
NETDATA_INSTALLER_START_CMD="${NETDATA_START_CMD}"
- fi
- return ${ret}
+ SYSTEMD_DIRECTORY="$(get_systemd_service_dir)"
+
+ if [ "${SYSTEMD_DIRECTORY}x" != "x" ]; then
+ ENABLE_NETDATA_IF_PREVIOUSLY_ENABLED="run systemctl enable netdata"
+ IS_NETDATA_ENABLED="$(systemctl is-enabled netdata 2> /dev/null || echo "Netdata not there")"
+ if [ "${IS_NETDATA_ENABLED}" = "disabled" ]; then
+ echo >&2 "Netdata was there and disabled, make sure we don't re-enable it ourselves"
+ ENABLE_NETDATA_IF_PREVIOUSLY_ENABLED="true"
+ fi
+
+ echo >&2 "Installing systemd service..."
+ run cp system/netdata.service "${SYSTEMD_DIRECTORY}/netdata.service" &&
+ run systemctl daemon-reload &&
+ ${ENABLE_NETDATA_IF_PREVIOUSLY_ENABLED} &&
+ return 0
+ else
+ warning "Could not find a systemd service directory, unable to install Netdata systemd service."
+ fi
+ else
+ install_non_systemd_init
+ ret=$?
+
+ if [ ${ret} -eq 0 ]; then
+ if [ -n "${service_cmd}" ]; then
+ NETDATA_START_CMD="service netdata start"
+ # This is used by netdata-installer.sh
+ # shellcheck disable=SC2034
+ NETDATA_STOP_CMD="service netdata stop"
+ elif [ -n "${rcservice_cmd}" ]; then
+ NETDATA_START_CMD="rc-service netdata start"
+ # This is used by netdata-installer.sh
+ # shellcheck disable=SC2034
+ NETDATA_STOP_CMD="rc-service netdata stop"
+ fi
+ NETDATA_INSTALLER_START_CMD="${NETDATA_START_CMD}"
+ fi
+
+ return ${ret}
+ fi
fi
fi
@@ -642,11 +699,21 @@ netdata_pids() {
stop_all_netdata() {
stop_success=0
+ if [ -x "${NETDATA_PREFIX}/usr/libexec/netdata/install-service.sh" ]; then
+ run_install_service_script --cmds-only
+ fi
+
if [ "${UID}" -eq 0 ]; then
+
uname="$(uname 2>/dev/null)"
# Any of these may fail, but we need to not bail if they do.
- if issystemd; then
+ if [ -n "${NETDATA_STOP_CMD}" ]; then
+ if ${NETDATA_STOP_CMD}; then
+ stop_success=1
+ sleep 5
+ fi
+ elif issystemd; then
if systemctl stop netdata; then
stop_success=1
sleep 5
@@ -693,8 +760,16 @@ restart_netdata() {
progress "Restarting netdata instance"
+ if [ -x "${NETDATA_PREFIX}/usr/libexec/netdata/install-service.sh" ]; then
+ run_install_service_script --cmds-only
+ fi
+
if [ -z "${NETDATA_INSTALLER_START_CMD}" ]; then
- NETDATA_INSTALLER_START_CMD="${netdata}"
+ if [ -n "${NETDATA_START_CMD}" ]; then
+ NETDATA_INSTALLER_START_CMD="${NETDATA_START_CMD}"
+ else
+ NETDATA_INSTALLER_START_CMD="${netdata}"
+ fi
fi
if [ "${UID}" -eq 0 ]; then
diff --git a/system/Makefile.am b/system/Makefile.am
index a88ccab654..72d123daa3 100644
--- a/system/Makefile.am
+++ b/system/Makefile.am
@@ -30,8 +30,14 @@ dist_config_DATA = \
# Explicitly install directories to avoid permission issues due to umask
install-exec-local:
$(INSTALL) -d $(DESTDIR)$(configdir)
+ $(INSTALL) -d $(DESTDIR)$(libsysdir)
-nodist_noinst_DATA = \
+libexecnetdatadir=$(libexecdir)/netdata
+nodist_libexecnetdata_SCRIPTS = \
+ install-service.sh \
+ $(NULL)
+
+nodist_libsys_DATA = \
netdata-openrc \
netdata.logrotate \
netdata.service \
@@ -44,8 +50,13 @@ nodist_noinst_DATA = \
netdata-updater.service \
$(NULL)
+dist_libsys_DATA = \
+ netdata-updater.timer \
+ $(NULL)
+
dist_noinst_DATA = \
edit-config.in \
+ install-service.sh.in \
netdata-openrc.in \
netdata.logrotate.in \
netdata.service.in \
@@ -57,5 +68,4 @@ dist_noinst_DATA = \
netdata.conf \
netdata.crontab.in \
netdata-updater.service.in \
- netdata-updater.timer \
$(NULL)
diff --git a/system/install-service.sh.in b/system/install-service.sh.in
new file mode 100755
index 0000000000..6c7c018878
--- /dev/null
+++ b/system/install-service.sh.in
@@ -0,0 +1,699 @@
+#!/usr/bin/env sh
+
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# Handle installation of the Netdata agent as a system service.
+#
+# Exit codes:
+# 0 - Successfully installed service.
+# 1 - Invalid arguments or other internal error.
+# 2 - Unable to detect system service type.
+# 3 - Detected system service type, but type not supported.
+# 4 - Detected system service type, but could not install due to other issues.
+# 5 - Platform not supported.
+
+set -e
+
+SCRIPT_SOURCE="$(
+ self=${0}
+ while [ -L "${self}" ]
+ do
+ cd "${self%/*}" || exit 1
+ self=$(readlink "${self}")
+ done
+ cd "${self%/*}" || exit 1
+ echo "$(pwd -P)/${self##*/}"
+)"
+
+DUMP_CMDS=0
+ENABLE="auto"
+EXPORT_CMDS=0
+INSTALL=1
+LINUX_INIT_TYPES="wsl systemd openrc lsb initd runit"
+PLATFORM="$(uname -s)"
+SVC_SOURCE="@libsysdir_POST@"
+SVC_TYPE="detect"
+
+# =====================================================================
+# Utility functions
+
+cleanup() {
+ ec="${?}"
+
+ if [ -n "${NETDATA_SAVE_WARNINGS}" ]; then
+ if [ -n "${NETDATA_PROPAGATE_WARNINGS}" ]; then
+ export NETDATA_WARNINGS="${NETDATA_WARNINGS}${SAVED_WARNINGS}"
+ fi
+ fi
+
+ trap - EXIT
+
+ exit "${ec}"
+}
+
+info() {
+ printf >&2 "%s\n" "${*}"
+}
+
+warning() {
+ if [ -n "${NETDATA_SAVE_WARNINGS}" ]; then
+ SAVED_WARNINGS="${SAVED_WARNINGS}\n - ${*}"
+ fi
+ printf >&2 "WARNING: %s\n" "${*}"
+}
+
+error() {
+ if [ -n "${NETDATA_SAVE_WARNINGS}" ]; then
+ SAVED_WARNINGS="${SAVED_WARNINGS}\n - ${*}"
+ fi
+ printf >&2 "ERROR: %s\n" "${*}"
+}
+
+get_os_key() {
+ if [ -f /etc/os-release ]; then
+ # shellcheck disable=SC1091
+ . /etc/os-release || return 1
+ echo "${ID}-${VERSION_ID}"
+
+ elif [ -f /etc/redhat-release ]; then
+ cat /etc/redhat-release
+ else
+ echo "unknown"
+ fi
+}
+
+valid_types() {
+ case "${PLATFORM}" in
+ Linux)
+ echo "detect systemd openrc lsb initd"
+ ;;
+ FreeBSD)
+ echo "detect freebsd"
+ ;;
+ Darwin)
+ echo "detect launchd"
+ ;;
+ *)
+ echo "detect"
+ ;;
+ esac
+}
+
+install_generic_service() {
+ svc_type="${1}"
+ svc_type_name="${2}"
+ svc_file="${3}"
+ svc_enable_hook="${4}"
+ svc_disable_hook="${5}"
+
+ info "Installing ${svc_type_name} service file."
+ if [ ! -f "${svc_file}" ] && [ "${ENABLE}" = "auto" ]; then
+ ENABLE="enable"
+ fi
+
+ if ! install -p -m 0755 -o 0 -g 0 "${SVC_SOURCE}/netdata-${svc_type}" /etc/init.d/netdata; then
+ error "Failed to install service file."
+ exit 4
+ fi
+
+ case "${ENABLE}" in
+ auto) true ;;
+ disable)
+ info "Disabling Netdata service."
+ ${svc_disable_hook}
+ ;;
+ enable)
+ info "Enabling Netdata service."
+ ${svc_enable_hook}
+ ;;
+ esac
+}
+
+dump_cmds() {
+ [ -n "${NETDATA_START_CMD}" ] && echo "NETDATA_START_CMD='${NETDATA_START_CMD}'"
+ [ -n "${NETDATA_STOP_CMD}" ] && echo "NETDATA_STOP_CMD='${NETDATA_STOP_CMD}'"
+ [ -n "${NETDATA_INSTALLER_START_CMD}" ] && echo "NETDATA_INSTALLER_START_CMD='${NETDATA_INSTALLER_START_CMD}'"
+ return 0
+}
+
+export_cmds() {
+ [ -n "${NETDATA_START_CMD}" ] && export NETDATA_START_CMD="${NETDATA_START_CMD}"
+ [ -n "${NETDATA_STOP_CMD}" ] && export NETDATA_STOP_CMD="${NETDATA_STOP_CMD}"
+ [ -n "${NETDATA_INSTALLER_START_CMD}" ] && export NETDATA_INSTALLER_START_CMD="${NETDATA_INSTALLER_START_COMMAND}"
+ return 0
+}
+
+save_cmds() {
+ dump_cmds > "${SAVE_CMDS_PATH}"
+}
+
+# =====================================================================
+# Help functions
+
+usage() {
+ cat << HEREDOC
+USAGE: install-service.sh [options]
+ where options include:
+
+ --source Specify where to find the service files to install (default ${SVC_SOURCE}).
+ --type Specify the type of service file to install. Specify a type of 'help' to get a list of valid types for your platform.
+ --cmds Additionally print a list of commands for starting and stopping the agent with the detected service type.
+ --export-cmds Export the variables that would be printed by the --cmds option.
+ --cmds-only Don't install, just handle the --cmds or --export-cmds option.
+ --enable Explicitly enable the service on install (default is to enable if not already installed).
+ --disable Explicitly disable the service on install.
+ --help Print this help information.
+HEREDOC
+}
+
+help_types() {
+ cat << HEREDOC
+Valid service types for ${PLATFORM} are:
+$(valid_types)
+HEREDOC
+}
+
+# =====================================================================
+# systemd support functions
+
+issystemd() {
+ pids=''
+ p=''
+ myns=''
+ ns=''
+ systemctl=''
+
+ # if the directory /lib/systemd/system OR /usr/lib/systemd/system (SLES 12.x) does not exit, it is not systemd
+ if [ ! -d /lib/systemd/system ] && [ ! -d /usr/lib/systemd/system ]; then
+ return 1
+ fi
+
+ # if there is no systemctl command, it is not systemd
+ systemctl=$(command -v systemctl 2> /dev/null)
+ if [ -z "${systemctl}" ] || [ ! -x "${systemctl}" ]; then
+ return 1
+ fi
+
+ # if pid 1 is systemd, it is systemd
+ [ "$(basename "$(readlink /proc/1/exe)" 2> /dev/null)" = "systemd" ] && return 0
+
+ # if systemd is not running, it is not systemd
+ pids=$(safe_pidof systemd 2> /dev/null)
+ [ -z "${pids}" ] && return 1
+
+ # check if the running systemd processes are not in our namespace
+ myns="$(readlink /proc/self/ns/pid 2> /dev/null)"
+ for p in ${pids}; do
+ ns="$(readlink "/proc/${p}/ns/pid" 2> /dev/null)"
+
+ # if pid of systemd is in our namespace, it is systemd
+ [ -n "${myns}" ] && [ "${myns}" = "${ns}" ] && return 0
+ done
+
+ # else, it is not systemd
+ return 1
+}
+
+check_systemd() {
+ if [ -z "${IS_SYSTEMD}" ]; then
+ issystemd
+ IS_SYSTEMD="$?"
+ fi
+
+ return "${IS_SYSTEMD}"
+}
+
+get_systemd_service_dir() {
+ if [ -w "/lib/systemd/system" ]; then
+ echo "/lib/systemd/system"
+ elif [ -w "/usr/lib/systemd/system" ]; then
+ echo "/usr/lib/systemd/system"
+ elif [ -w "/etc/systemd/system" ]; then
+ echo "/etc/systemd/system"
+ else
+ error "Unable to detect systemd service directory."
+ exit 4
+ fi
+}
+
+install_systemd_service() {
+ SRCFILE="${SVC_SOURCE}/netdata.service"
+
+ if [ "$(systemctl --version | head -n 1 | cut -f 2 -d ' ')" -le 235 ]; then
+ SRCFILE="${SVC_SOURCE}/netdata.service.v235"
+ fi
+
+ if [ "${ENABLE}" = "auto" ]; then
+ IS_NETDATA_ENABLED="$(systemctl is-enabled netdata 2> /dev/null || echo "Netdata not there")"
+
+ if [ "${IS_NETDATA_ENABLED}" = "disabled" ]; then
+ ENABLE="disable"
+ else
+ ENABLE="enable"
+ fi
+ fi
+
+ info "Installing systemd service..."
+ if ! install -p -m 0644 -o 0 -g 0 "${SRCFILE}" "$(get_systemd_service_dir)/netdata.service"; then
+ error "Failed to install systemd service file."
+ exit 4
+ fi
+
+ if ! systemctl daemon-reload; then
+ warning "Failed to reload systemd unit files."
+ fi
+
+ if ! systemctl ${ENABLE} netdata; then
+ warning "Failed to ${ENABLE} Netdata service."
+ fi
+}
+
+systemd_cmds() {
+ NETDATA_START_CMD='systemctl start netdata'
+ NETDATA_STOP_CMD='systemctl stop netdata'
+}
+
+# =====================================================================
+# OpenRC support functions
+
+isopenrc() {
+ # if /lib/rc/sh/functions.sh does not exist, it's not OpenRC
+ [ ! -f /lib/rc/sh/functions.sh ] && return 1
+
+ # if there is no /etc/init.d, it's not OpenRC
+ [ ! -d /etc/init.d ] && return 1
+
+ # if PID 1 is openrc-init, it's OpenRC
+ [ "$(basename "$(readlink /proc/1/exe)" 2> /dev/null)" = "openrc-init" ] && return 0
+
+ # If /run/openrc/softlevel exists, it's OpenRC
+ [ -f /run/openrc/softlevel ] && return 0
+
+ # if there is an openrc command, it's OpenRC
+ command -v openrc > /dev/null 2>&1 && return 0
+
+ # Otherwise, it’s not OpenRC
+ return 1
+}
+
+check_openrc() {
+ if [ -z "${IS_OPENRC}" ]; then
+ isopenrc
+ IS_OPENRC="$?"
+ fi
+
+ return "${IS_OPENRC}"
+}
+
+enable_openrc() {
+ runlevel="$(rc-status -r)"
+ runlevel="${runlevel:-default}"
+ if ! rc-update add netdata "${runlevel}"; then
+ warning "Failed to enable Netdata service in runlevel ${runlevel}."
+ fi
+}
+
+disable_openrc() {
+ for runlevel in /etc/runlevels/*; do
+ if [ -e "${runlevel}/netdata" ]; then
+ runlevel="$(basename "${runlevel}")"
+ if ! rc-update del netdata "${runlevel}"; then
+ warning "Failed to disable Netdata service in runlevel ${runlevel}."
+ fi
+ fi
+ done
+}
+
+install_openrc_service() {
+ install_generic_service openrc OpenRC /etc/init.d/netdata enable_openrc disable_openrc
+}
+
+openrc_cmds() {
+ NETDATA_START_CMD='rc-service netdata start'
+ NETDATA_STOP_CMD='rc-service netdata stop'
+}
+
+# =====================================================================
+# LSB init script support functions
+
+islsb() {
+ # if there is no /etc/init.d directory, it’s not an LSB system
+ [ ! -d /etc/init.d ] && return 1
+
+ # If it's an OpenRC system, then it's not an LSB system
+ check_openrc && return 1
+
+ # If /lib/lsb/init-functions exists, it’s an LSB system
+ [ -f /lib/lsb/init-functions ] && return 0
+
+ return 1
+}
+
+check_lsb() {
+ if [ -z "${IS_LSB}" ]; then
+ islsb
+ IS_LSB="$?"
+ fi
+
+ return "${IS_LSB}"
+}
+
+enable_lsb() {
+ if ! update-rc.d netdata defaults; then
+ warning "Failed to enable Netdata service."
+ elif ! update-rc.d netdata defaults-disable; then
+ warning "Failed to fully enable Netdata service."
+ fi
+}
+
+disable_lsb() {
+ if ! update-rc.d netdata remove; then
+ warning "Failed to disable Netdata service."
+ fi
+}
+
+install_lsb_service() {
+ install_generic_service lsb LSB /etc/init.d/netdata enable_lsb disable_lsb
+}
+
+lsb_cmds() {
+ if command -v service >/dev/null 2>&1; then
+ NETDATA_START_CMD='service netdata start'
+ NETDATA_STOP_CMD='service netdata stop'
+ else
+ NETDATA_START_CMD='/etc/init.d/netdata start'
+ NETDATA_STOP_CMD='/etc/init.d/netdata stop'
+ fi
+}
+
+# =====================================================================
+# init.d init script support functions
+
+isinitd() {
+ # if there is no /etc/init.d directory, it’s not an init.d system
+ [ ! -d /etc/init.d ] && return 1
+
+ # if there is no chkconfig command, it's not a (usable) init.d system
+ command -v chkconfig >/dev/null 2>&1 || return 1
+
+ # if it's not an LSB setup, it’s init.d
+ check_initd || return 0
+
+ return 1
+}
+
+check_initd() {
+ if [ -z "${IS_INITD}" ]; then
+ isinitd
+ IS_INITD="$?"
+ fi
+
+ return "${IS_INITD}"
+}
+
+enable_initd() {
+ if ! chkconfig netdata on; then
+ warning "Failed to enable Netdata service."
+ fi
+}
+
+disable_initd() {
+ if ! chkconfig netdata off; then
+ warning "Failed to disable Netdata service."
+ fi
+}
+
+install_initd_service() {
+ install_generic_service init-d init.d /etc/init.d/netdata enable_initd disable_initd
+}
+
+initd_cmds() {
+ if command -v service >/dev/null 2>&1; then
+ NETDATA_START_CMD='service netdata start'
+ NETDATA_STOP_CMD='service netdata stop'
+ else
+ NETDATA_START_CMD='/etc/init.d/netdata start'
+ NETDATA_STOP_CMD='/etc/init.d/netdata stop'
+ fi
+}
+
+# =====================================================================
+# runit support functions
+#
+# Currently not supported, this exists to provide useful error messages.
+
+isrunit() {
+ # if there is no /lib/rc/sv.d, then it's not runit
+ [ ! -d /lib/rc/sv.d ] && return 1
+
+ # if there is no runit command, then it's not runit
+ command -v runit >/dev/null 2>&1 || return 1
+
+ # if /run/runit exists, then it's runit
+ [ -d /run/runit ] && return 0
+
+ # if /etc/runit/1 exists and is executable, then it's runit
+ [ -x /etc/runit/1 ] && return 0
+
+ return 1
+}
+
+check_runit() {
+ if [ -z "${IS_RUNIT}" ]; then
+ isrunit
+ IS_RUNIT="$?"
+ fi
+
+ return "${IS_RUNIT}"
+}
+
+install_runit_service() {
+ error "Detected runit, which we do not currently support."
+ exit 3
+}
+
+runit_cmds() {
+ error "Detected runit, which we do not currently support."
+ exit 3
+}
+
+# =====================================================================
+# WSL support functions
+#
+# Cannot be supported, this exists to provide useful error messages.
+
+iswsl() {
+ # If uname -r contains the string WSL, then it's WSL.
+ uname -r | grep -q 'WSL' && return 0
+
+ # If uname -r contains the string Microsoft, then it's WSL.
+ # This probably throws a false positive on CBL-Mariner, but it's part of what MS officially recommends for
+ # detecting if you're running under WSL.
+ uname -r | grep -q "Microsoft" && return 0
+
+ return 1
+}
+
+check_wsl() {
+ if [ -z "${IS_WSL}" ]; then
+ iswsl
+ IS_WSL="$?"
+ fi
+
+ return "${IS_WSL}"
+}
+
+install_wsl_service() {
+ error "We appear to be running in WSL. Netdata cannot be automatically installed as a service under WSL."
+ exit 3
+}
+
+wsl_cmds() {
+ error "We appear to be running in WSL. Netdata cannot be automatically installed as a service under WSL."
+ exit 3
+}
+
+# =====================================================================
+# FreeBSD support functions
+
+enable_freebsd() {
+ if ! sysrc netdata_enable=YES; then
+ warning "Failed to enable netdata service."
+ fi
+}
+
+disable_freebsd() {
+ if ! sysrc netdata_enable=NO; then
+ warning "Failed to disable netdata service."
+ fi
+}
+
+install_freebsd_service() {
+ install_generic_service freebsd "FreeBSD rc.d" /usr/local/etc/rc.d/netdata enable_freebsd disable_freebsd
+}
+
+freebsd_cmds() {
+ NETDATA_START_CMD='service netdata start'
+ NETDATA_STOP_CMD='service netdata stop'
+ NETDATA_INSTALLER_START_CMD='service netdata onestart'
+}
+
+# =====================================================================
+# macOS support functions
+
+install_darwin_service() {
+ info "Installing macOS plist file for launchd."
+ if ! install -C -S -p -m 0644 -o 0 -g 0 system/netdata.plist /Library/LaunchDaemons/com.github.netdata.plist; then
+ error "Failed to copy plist file."
+ exit 4
+ fi
+
+ if ! launchctl load /Library/LaunchDaemons/com.github.netdata.plist; then
+ error "Failed to load plist file."
+ exit 4
+ fi
+}
+
+darwin_cmds() {
+ NETDATA_START_CMD='launchctl start com.github.netdata'
+ NETDATA_STOP_CMD='launchctl stop com.github.netdata'
+}
+
+# =====================================================================
+# Linux support functions
+
+detect_linux_svc_type() {
+ if [ "${SVC_TYPE}" = "detect" ]; then
+ for t in ${LINUX_INIT_TYPES}; do
+ if "check_${t}"; then
+ SVC_TYPE="${t}"
+ break
+ fi
+ done
+
+ if [ "${SVC_TYPE}" = "detect" ]; then
+ error "Failed to detect what type of service manager is in use."
+ else
+ echo "${SVC_TYPE}"
+ fi
+ else
+ echo "${SVC_TYPE}"
+ fi
+}
+
+install_linux_service() {
+ t="$(detect_linux_svc_type)"
+
+ if [ -z "${t}" ]; then
+ exit 2
+ fi
+
+ "install_${t}_service"
+}
+
+linux_cmds() {
+ t="$(detect_linux_svc_type)"
+
+ if [ -z "${t}" ]; then
+ exit 2
+ fi
+
+ "${t}_cmds"
+}
+
+# =====================================================================
+# Argument handling
+
+parse_args() {
+ while [ -n "${1}" ]; do
+ case "${1}" in
+ "--source" | "-s")
+ SVC_SOURCE="${2}"
+ shift 1
+ ;;
+ "--type" | "-t")
+ if [ "${2}" = "help" ]; then
+ help_types
+ exit 0
+ else
+ SVC_TYPE="${2}"
+ shift 1
+ fi
+ ;;
+ "--save-cmds")
+ if [ -z "${2}" ]; then
+ info "No path specified to save command variables."
+ exit 1
+ else
+ SAVE_CMDS_PATH="${2}"
+ shift 1
+ fi
+ ;;
+ "--cmds" | "-c") DUMP_CMDS=1 ;;
+ "--cmds-only") INSTALL=0 ;;
+ "--export-cmds") EXPORT_CMDS=1 ;;
+ "--enable" | "-e") ENABLE="enable" ;;
+ "--disable" | "-d") ENABLE="disable" ;;
+ "--help" | "-h")
+ usage
+ exit 0
+ ;;
+ *)
+ info "Unrecognized option '${1}'."
+ exit 1
+ ;;
+ esac
+ shift 1
+ done
+
+ if [ "${SVC_SOURCE#@}" = "libsysdir_POST@" ]; then
+ SVC_SOURCE="$(dirname "${SCRIPT_SOURCE}")/../../lib/netdata/system"
+ warning "SVC_SOURCE not templated, using ${SVC_SOURCE} as source directory."
+ fi
+
+ if [ ! -d "${SVC_SOURCE}" ] && [ "${INSTALL}" -eq 1 ]; then
+ error "${SVC_SOURCE} does not appear to be a directory. Please specify a valid source for service files with the --source option."
+ exit 1
+ fi
+
+ if valid_types | grep -vw "${SVC_TYPE}"; then
+ error "${SVC_TYPE} is not supported on this platform."
+ help_types
+ exit 1
+ fi
+}
+
+# =====================================================================
+# Core logic
+
+main() {
+ trap "cleanup" EXIT
+
+ parse_args "${@}"
+
+ case "${PLATFORM}" in
+ FreeBSD)
+ [ "${INSTALL}" -eq 1 ] && install_freebsd_service
+ freebsd_cmds
+ ;;
+ Darwin)
+ [ "${INSTALL}" -eq 1 ] && install_darwin_service
+ darwin_cmds
+ ;;
+ Linux)
+ [ "${INSTALL}" -eq 1 ] && install_linux_service
+ linux_cmds
+ ;;
+ *)
+ error "${PLATFORM} is not supported by this script."
+ exit 5
+ ;;
+ esac
+
+ [ "${DUMP_CMDS}" -eq 1 ] && dump_cmds
+ [ "${EXPORT_CMDS}" -eq 1 ] && export_cmds
+ [ -n "${SAVE_CMDS_PATH}" ] && save_cmds
+ exit 0
+}
+
+main "${@}"