summaryrefslogtreecommitdiffstats
path: root/system
diff options
context:
space:
mode:
Diffstat (limited to 'system')
-rw-r--r--system/.install-type1
-rw-r--r--system/Makefile.am136
-rw-r--r--system/cron/netdata-updater-daily.in1
-rwxr-xr-xsystem/edit-config327
-rw-r--r--system/freebsd/rc.d/netdata.in53
-rw-r--r--system/initd/init.d/netdata.in95
-rwxr-xr-xsystem/install-service.sh.in845
-rw-r--r--system/launchd/netdata.plist.in16
-rw-r--r--system/logrotate/netdata.in12
-rw-r--r--system/lsb/init.d/netdata.in116
-rw-r--r--system/netdata-updater.conf21
-rw-r--r--system/netdata.conf23
-rw-r--r--system/openrc/conf.d/netdata.in24
-rw-r--r--system/openrc/init.d/netdata.in79
-rw-r--r--system/runit/run.in12
-rw-r--r--system/systemd/50-netdata.preset1
-rw-r--r--system/systemd/netdata-updater.service.in8
-rw-r--r--system/systemd/netdata-updater.timer12
-rw-r--r--system/systemd/netdata.service.in84
-rw-r--r--system/systemd/netdata.service.v235.in34
-rw-r--r--system/vnodes/vnodes.conf23
21 files changed, 1923 insertions, 0 deletions
diff --git a/system/.install-type b/system/.install-type
new file mode 100644
index 00000000..ebac7be5
--- /dev/null
+++ b/system/.install-type
@@ -0,0 +1 @@
+INSTALL_TYPE='custom'
diff --git a/system/Makefile.am b/system/Makefile.am
new file mode 100644
index 00000000..1e96f6f4
--- /dev/null
+++ b/system/Makefile.am
@@ -0,0 +1,136 @@
+# Copyright (C) 2015 Alon Bar-Lev <alon.barlev@gmail.com>
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+MAINTAINERCLEANFILES = $(srcdir)/Makefile.in
+CLEANFILES = \
+ install-service.sh \
+ cron/netdata-updater-daily \
+ freebsd/rc.d/netdata \
+ initd/init.d/netdata \
+ launchd/netdata.plist \
+ logrotate/netdata \
+ lsb/init.d/netdata \
+ openrc/conf.d/netdata \
+ openrc/init.d/netdata \
+ runit/run \
+ systemd/netdata.service \
+ systemd/netdata.service.v235 \
+ systemd/netdata-updater.service \
+ $(NULL)
+
+include $(top_srcdir)/build/subst.inc
+SUFFIXES = .in
+
+dist_config_SCRIPTS = \
+ edit-config \
+ $(NULL)
+
+dist_config_DATA = \
+ .install-type \
+ netdata-updater.conf \
+ $(NULL)
+
+libconfigvnodesdir=$(libconfigdir)/vnodes
+libsyscrondir=$(libsysdir)/cron
+libsysfreebsddir=$(libsysdir)/freebsd
+libsysfreebsdrcddir=$(libsysfreebsddir)/rc.d
+libsysinitddir=$(libsysdir)/initd
+libsysinitdinitddir=$(libsysinitddir)/init.d
+libsyslaunchddir=$(libsysdir)/launchd
+libsyslogrotatedir=$(libsysdir)/logrotate
+libsyslsbdir=$(libsysdir)/lsb
+libsyslsbinitddir=$(libsyslsbdir)/init.d
+libsysopenrcdir=$(libsysdir)/openrc
+libsysopenrcinitddir=$(libsysopenrcdir)/init.d
+libsysopenrcconfddir=$(libsysopenrcdir)/conf.d
+libsysrunitdir=$(libsysdir)/runit
+libsyssystemddir=$(libsysdir)/systemd
+
+# Explicitly install directories to avoid permission issues due to umask
+install-exec-local:
+ $(INSTALL) -d $(DESTDIR)$(configdir)
+ $(INSTALL) -d $(DESTDIR)$(libsysdir)
+ $(INSTALL) -d $(DESTDIR)$(libsyscrondir)
+ $(INSTALL) -d $(DESTDIR)$(libsysfreebsdrcddir)
+ $(INSTALL) -d $(DESTDIR)$(libsysinitdinitddir)
+ $(INSTALL) -d $(DESTDIR)$(libsyslaunchddir)
+ $(INSTALL) -d $(DESTDIR)$(libsyslogrotatedir)
+ $(INSTALL) -d $(DESTDIR)$(libsyslsbinitddir)
+ $(INSTALL) -d $(DESTDIR)$(libsyssystemddir)
+ $(INSTALL) -d $(DESTDIR)$(libsysopenrcinitddir)
+ $(INSTALL) -d $(DESTDIR)$(libsysopenrcconfddir)
+ $(INSTALL) -d $(DESTDIR)$(libsysrunitdir)
+ $(INSTALL) -d $(DESTDIR)$(libconfigvnodesdir)
+
+dist_libconfigvnodes_DATA = \
+ vnodes/vnodes.conf
+ $(NULL)
+
+libexecnetdatadir=$(libexecdir)/netdata
+nodist_libexecnetdata_SCRIPTS = \
+ install-service.sh \
+ $(NULL)
+
+nodist_libsyscron_DATA = \
+ cron/netdata-updater-daily \
+ $(NULL)
+
+nodist_libsysfreebsdrcd_DATA = \
+ freebsd/rc.d/netdata \
+ $(NULL)
+
+nodist_libsysinitdinitd_DATA = \
+ initd/init.d/netdata \
+ $(NULL)
+
+nodist_libsyslaunchd_DATA = \
+ launchd/netdata.plist \
+ $(NULL)
+
+nodist_libsyslogrotate_DATA = \
+ logrotate/netdata \
+ $(NULL)
+
+nodist_libsyslsbinitd_DATA = \
+ lsb/init.d/netdata \
+ $(NULL)
+
+nodist_libsysopenrcinitd_DATA = \
+ openrc/init.d/netdata \
+ $(NULL)
+
+nodist_libsysopenrcconfd_DATA = \
+ openrc/conf.d/netdata \
+ $(NULL)
+
+nodist_libsysrunit_DATA = \
+ runit/run \
+ $(NULL)
+
+nodist_libsyssystemd_DATA = \
+ systemd/netdata.service \
+ systemd/netdata.service.v235 \
+ systemd/netdata-updater.service \
+ $(NULL)
+
+dist_libsyssystemd_DATA = \
+ systemd/netdata-updater.timer \
+ systemd/50-netdata.preset
+ $(NULL)
+
+dist_noinst_DATA = \
+ install-service.sh.in \
+ netdata.conf \
+ cron/netdata-updater-daily.in \
+ freebsd/rc.d/netdata.in \
+ initd/init.d/netdata.in \
+ launchd/netdata.plist.in \
+ logrotate/netdata.in \
+ lsb/init.d/netdata.in \
+ openrc/conf.d/netdata.in \
+ openrc/init.d/netdata.in \
+ runit/run.in \
+ systemd/netdata.service.in \
+ systemd/netdata.service.v235.in \
+ systemd/netdata-updater.service.in \
+ $(NULL)
diff --git a/system/cron/netdata-updater-daily.in b/system/cron/netdata-updater-daily.in
new file mode 100644
index 00000000..8f0527e0
--- /dev/null
+++ b/system/cron/netdata-updater-daily.in
@@ -0,0 +1 @@
+2 57 * * * root @pkglibexecdir_POST@/netdata-updater.sh
diff --git a/system/edit-config b/system/edit-config
new file mode 100755
index 00000000..3944810d
--- /dev/null
+++ b/system/edit-config
@@ -0,0 +1,327 @@
+#!/usr/bin/env sh
+
+# shellcheck disable=SC1091
+[ -f /etc/profile ] && . /etc/profile
+
+set -e
+
+script_dir="$(CDPATH="" cd -- "$(dirname -- "$0")" && pwd -P)"
+
+usage() {
+ check_directories
+ cat <<EOF
+USAGE:
+ ${0} [options] FILENAME
+
+ Copy and edit the stock config file named: FILENAME
+ if FILENAME is already copied, it will be edited as-is.
+
+ Stock config files at: '${NETDATA_STOCK_CONFIG_DIR}'
+ User config files at: '${NETDATA_USER_CONFIG_DIR}'
+
+ The editor to use can be specified either by setting the EDITOR
+ environment variable, or by using the --editor option.
+
+ The file to edit can also be specified using the --file option.
+
+ For a list of known config files, run '${0} --list'
+EOF
+ exit 0
+}
+
+error() {
+ echo >&2 "ERROR: ${1}"
+}
+
+abspath() {
+ if [ -d "${1}/" ]; then
+ echo "$(cd "${1}" && /usr/bin/env PWD= pwd -P)/"
+ elif [ -f "${1}" ]; then
+ echo "$(cd "$(dirname "${1}")" && /usr/bin/env PWD= pwd -P)/$(basename "${1}")"
+ elif echo "${1}" | grep -q '/'; then
+ if echo "${1}" | grep -q '^/'; then
+ mkdir -p "$(dirname "${1}")"
+ echo "$(cd "$(dirname "${1}")" && /usr/bin/env PWD= pwd -P)/$(basename "${1}")"
+ else
+ mkdir -p "${script_dir}/$(dirname "${1}")"
+ echo "${script_dir}/${1}"
+ fi
+ else
+ echo "${script_dir}/${1}"
+ fi
+}
+
+is_prefix() {
+ echo "${2}" | grep -qE "^${1}"
+ return $?
+}
+
+check_directories() {
+ if [ -f "${script_dir}/.container-hostname" ]; then
+ NETDATA_USER_CONFIG_DIR="${script_dir}"
+ NETDATA_STOCK_CONFIG_DIR="/usr/lib/netdata/conf.d"
+ return
+ fi
+
+ if [ -e "${script_dir}/.environment" ]; then
+ OLDPATH="${PATH}"
+ # shellcheck disable=SC1091
+ . "${script_dir}/.environment"
+ PATH="${OLDPATH}"
+ fi
+
+ if [ -n "${NETDATA_PREFIX}" ] && [ -d "${NETDATA_PREFIX}/usr/lib/netdata/conf.d" ]; then
+ stock_dir="${NETDATA_PREFIX}/usr/lib/netdata/conf.d"
+ elif [ -n "${NETDATA_PREFIX}" ] && [ -d "${NETDATA_PREFIX}/lib/netdata/conf.d" ]; then
+ stock_dir="${NETDATA_PREFIX}/lib/netdata/conf.d"
+ elif [ -d "${script_dir}/../../usr/lib/netdata/conf.d" ]; then
+ stock_dir="${script_dir}/../../usr/lib/netdata/conf.d"
+ elif [ -d "${script_dir}/../../lib/netdata/conf.d" ]; then
+ stock_dir="${script_dir}/../../lib/netdata/conf.d"
+ elif [ -d "/usr/lib/netdata/conf.d" ]; then
+ stock_dir="/usr/lib/netdata/conf.d"
+ fi
+
+ [ -z "${NETDATA_USER_CONFIG_DIR}" ] && NETDATA_USER_CONFIG_DIR="${script_dir}"
+ [ -z "${NETDATA_STOCK_CONFIG_DIR}" ] && NETDATA_STOCK_CONFIG_DIR="${stock_dir}"
+
+ if [ -z "${NETDATA_STOCK_CONFIG_DIR}" ]; then
+ error "Unable to find stock config directory."
+ exit 1
+ fi
+}
+
+check_editor() {
+ if [ -z "${editor}" ]; then
+ if [ -n "${EDITOR}" ] && command -v "${EDITOR}" >/dev/null 2>&1; then
+ editor="${EDITOR}"
+ elif command -v editor >/dev/null 2>&1; then
+ editor="editor"
+ elif command -v vi >/dev/null 2>&1; then
+ editor="vi"
+ else
+ error "Unable to find a usable editor, tried \${EDITOR} (${EDITOR}), editor, and vi."
+ exit 1
+ fi
+ elif ! command -v "${editor}" >/dev/null 2>&1; then
+ error "Unable to locate user specified editor ${editor}, is it in your PATH?"
+ exit 1
+ fi
+}
+
+running_in_container() {
+ [ -e /.dockerenv ] && return 0
+ [ -e /.dockerinit ] && return 0
+ [ -e /run/.containerenv ] && return 0
+ [ -r /proc/1/environ ] && tr '\000' '\n' </proc/1/environ | grep -Eiq 'container=' && return 0
+ grep -qF -e /docker/ -e /libpod- /proc/self/cgroup 2>/dev/null && return 0
+ return 1
+}
+
+get_docker_command() {
+ if [ -x "${docker}" ]; then
+ return 0
+ elif command -v docker >/dev/null 2>&1; then
+ docker="$(command -v docker)"
+ elif command -v podman >/dev/null 2>&1; then
+ docker="$(command -v podman)"
+ else
+ error "Unable to find a usable container tool stack. I support Docker and Podman."
+ exit 1
+ fi
+}
+
+run_in_container() {
+ ${docker} exec "${1}" /bin/sh -c "${2}" || return 1
+ return 0
+}
+
+check_for_container() {
+ get_docker_command
+ ${docker} container inspect "${1}" >/dev/null 2>&1 || return 1
+ run_in_container "${1}" "[ -d \"${NETDATA_STOCK_CONFIG_DIR}\" ]" >/dev/null 2>&1 || return 1
+ return 0
+}
+
+handle_container() {
+ if running_in_container; then
+ return 0
+ elif [ -z "${container}" ] && [ -f "${script_dir}/.container-hostname" ]; then
+ echo >&2 "Autodetected containerized Netdata instance. Attempting to autodetect container ID."
+ possible_container="$(cat "${script_dir}/.container-hostname")"
+ if check_for_container "${possible_container}"; then
+ container="${possible_container}"
+ elif check_for_container netdata; then
+ container="netdata"
+ else
+ error "Could not autodetect container ID. It must be supplied on the command line with the --container option."
+ exit 1
+ fi
+
+ echo >&2 "Found Netdata container with ID or name ${container}"
+ elif [ -n "${container}" ]; then
+ if ! check_for_container "${container}"; then
+ error "No container with ID or name ${container} exists."
+ exit 1
+ fi
+ fi
+}
+
+list_files() {
+ check_directories
+ handle_container
+
+ if test -t && command -v tput > /dev/null 2>&1; then
+ width="$(tput cols)"
+ fi
+
+ if [ -z "${container}" ]; then
+ if [ "$(uname -s)" = "Linux" ]; then
+ # shellcheck disable=SC2046,SC2086
+ files="$(cd "${NETDATA_STOCK_CONFIG_DIR}" && ls ${width:+-C} ${width:+-w ${width}} $(find . -type f | cut -d '/' -f 2-))"
+ elif [ "$(uname -s)" = "FreeBSD" ]; then
+ if [ -n "${width}" ]; then
+ export COLUMNS="${width}"
+ fi
+
+ # shellcheck disable=SC2046
+ files="$(cd "${NETDATA_STOCK_CONFIG_DIR}" && ls ${width:+-C} $(find . -type f | cut -d '/' -f 2-))"
+ else
+ # shellcheck disable=SC2046
+ files="$(cd "${NETDATA_STOCK_CONFIG_DIR}" && ls $(find . -type f | cut -d '/' -f 2-))"
+ fi
+ else
+ files="$(run_in_container "${container}" "cd /usr/lib/netdata/conf.d && ls ${width:+-C} ${width:+-w ${width}} \$(find . -type f | cut -d '/' -f 2-)")"
+ fi
+
+ if [ -z "${files}" ]; then
+ error "Failed to find any configuration files."
+ exit 1
+ fi
+
+ cat <<EOF
+The following configuration files are known to this script:
+
+${files}
+EOF
+ exit 0
+}
+
+parse_args() {
+ while [ -n "${1}" ]; do
+ case "${1}" in
+ "--help") usage ;;
+ "--list") list_files ;;
+ "--file")
+ if [ -n "${2}" ]; then
+ file="${2}"
+ shift 1
+ else
+ error "No file specified to edit."
+ exit 1
+ fi
+ ;;
+ "--container")
+ if [ -n "${2}" ]; then
+ container="${2}"
+ shift 1
+ else
+ error "No container ID or name specified with the --container option."
+ exit 1
+ fi
+ ;;
+ "--editor")
+ if [ -n "${2}" ]; then
+ editor="${2}"
+ shift 1
+ else
+ error "No editor specified with the --editor option."
+ exit 1
+ fi
+ ;;
+ *)
+ if [ -z "${2}" ]; then
+ file="${1}"
+ else
+ error "Unrecognized option ${1}."
+ exit 1
+ fi
+ ;;
+ esac
+ shift 1
+ done
+
+ [ -z "${file}" ] && usage
+
+ absfile="$(abspath "${file}")"
+ if ! is_prefix "${script_dir}" "${absfile}"; then
+ error "${file} is not located under ${script_dir}"
+ exit 1
+ fi
+
+ file="${absfile##"${script_dir}"}"
+}
+
+copy_native() {
+ if [ ! -w "${NETDATA_USER_CONFIG_DIR}" ]; then
+ error "Cannot write to ${NETDATA_USER_CONFIG_DIR}!"
+ exit 1
+ fi
+
+ if [ -f "${NETDATA_STOCK_CONFIG_DIR}/${1}" ]; then
+ echo >&2 "Copying '${NETDATA_STOCK_CONFIG_DIR}/${1}' to '${NETDATA_USER_CONFIG_DIR}/${1}' ... "
+ cp -p "${NETDATA_STOCK_CONFIG_DIR}/${1}" "${NETDATA_USER_CONFIG_DIR}/${1}" || exit 1
+ else
+ echo >&2 "Creating empty '${NETDATA_USER_CONFIG_DIR}/${1}' ... "
+ touch "${NETDATA_USER_CONFIG_DIR}/${1}" || exit 1
+ fi
+}
+
+copy_container() {
+ if [ ! -w "${NETDATA_USER_CONFIG_DIR}" ]; then
+ error "Cannot write to ${NETDATA_USER_CONFIG_DIR}!"
+ exit 1
+ fi
+
+ if run_in_container "${container}" "[ -f \"${NETDATA_STOCK_CONFIG_DIR}/${1}\" ]"; then
+ echo >&2 "Copying '${NETDATA_STOCK_CONFIG_DIR}/${1}' to '${NETDATA_USER_CONFIG_DIR}/${1}' ... "
+ ${docker} cp -a "${container}:${NETDATA_STOCK_CONFIG_DIR}/${1}" "${NETDATA_USER_CONFIG_DIR}/${1}" || exit 1
+ else
+ echo >&2 "Creating empty '${NETDATA_USER_CONFIG_DIR}/${1}' ... "
+ touch "${NETDATA_USER_CONFIG_DIR}/${1}" || exit 1
+ fi
+}
+
+copy() {
+ if [ -f "${NETDATA_USER_CONFIG_DIR}/${1}" ]; then
+ return 0
+ elif [ -n "${container}" ]; then
+ copy_container "${1}"
+ else
+ copy_native "${1}"
+ fi
+}
+
+edit() {
+ echo >&2 "Editing '${1}' ..."
+
+ # check we can edit
+ if [ ! -w "${1}" ]; then
+ error "Cannot write to ${1}!"
+ exit 1
+ fi
+
+ "${editor}" "${1}"
+ exit $?
+}
+
+main() {
+ parse_args "${@}"
+ check_directories
+ check_editor
+ handle_container
+ copy "${file}"
+ edit "${absfile}"
+}
+
+main "${@}"
diff --git a/system/freebsd/rc.d/netdata.in b/system/freebsd/rc.d/netdata.in
new file mode 100644
index 00000000..fd544c86
--- /dev/null
+++ b/system/freebsd/rc.d/netdata.in
@@ -0,0 +1,53 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+. /etc/rc.subr
+
+name=netdata
+rcvar=netdata_enable
+
+piddir="@localstatedir_POST@/run/netdata"
+pidfile="${piddir}/netdata.pid"
+
+command="@sbindir_POST@/netdata"
+command_args="-P ${pidfile}"
+
+required_files="@configdir_POST@/netdata.conf"
+
+start_precmd="netdata_prestart"
+stop_postcmd="netdata_poststop"
+
+extra_commands="reloadhealth savedb"
+
+reloadhealth_cmd="netdata_reloadhealth"
+savedb_cmd="netdata_savedb"
+
+netdata_prestart()
+{
+ [ ! -d "${piddir}" ] && mkdir -p "${piddir}"
+ chown @netdata_user_POST@:@netdata_user_POST@ "${piddir}"
+ return 0
+}
+
+netdata_poststop()
+{
+ [ -f "${pidfile}" ] && rm "${pidfile}"
+ return 0
+}
+
+netdata_reloadhealth()
+{
+ p=`cat ${pidfile}`
+ kill -USR2 ${p} && echo "Sent USR2 (reload health) to pid ${p}"
+ return 0
+}
+
+netdata_savedb()
+{
+ p=`cat ${pidfile}`
+ kill -USR2 ${p} && echo "Sent USR1 (save db) to pid ${p}"
+ return 0
+}
+
+load_rc_config $name
+run_rc_command "$1"
diff --git a/system/initd/init.d/netdata.in b/system/initd/init.d/netdata.in
new file mode 100644
index 00000000..c0257ffa
--- /dev/null
+++ b/system/initd/init.d/netdata.in
@@ -0,0 +1,95 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# netdata Real-time performance monitoring, done right
+# chkconfig: 345 99 01
+# description: Netdata is a daemon that collects data in real-time (per second)
+# and presents a web site to view and analyze them. The presentation
+# is also real-time and full of interactive charts that precisely
+# render all collected values.
+# processname: netdata
+
+# Source functions
+. /etc/rc.d/init.d/functions
+
+DAEMON="netdata"
+DAEMON_PATH=@sbindir_POST@
+PIDFILE_PATH=@localstatedir_POST@/run/netdata
+PIDFILE=$PIDFILE_PATH/$DAEMON.pid
+DAEMONOPTS="-P $PIDFILE"
+STOP_TIMEOUT="60"
+
+[ -e /etc/sysconfig/$DAEMON ] && . /etc/sysconfig/$DAEMON
+
+LOCKFILE=/var/lock/subsys/$DAEMON
+
+service_start()
+{
+ [ -x $DAEMON_PATH ] || exit 5
+ [ ! -d $PIDFILE_PATH ] && mkdir -p $PIDFILE_PATH
+ chown @netdata_user_POST@:@netdata_user_POST@ $PIDFILE_PATH
+ echo -n "Starting $DAEMON..."
+ daemon $DAEMON_PATH/$DAEMON $DAEMONOPTS
+ RETVAL=$?
+ echo
+ [ $RETVAL -eq 0 ] && touch $LOCKFILE
+ return $RETVAL
+}
+
+service_stop()
+{
+ printf "%-50s" "Stopping $DAEMON..."
+ killproc -p ${PIDFILE} -d ${STOP_TIMEOUT} $DAEMON
+ RETVAL=$?
+ echo
+ [ $RETVAL -eq 0 ] && rm -f ${PIDFILE} ${LOCKFILE}
+ return $RETVAL
+}
+
+condrestart()
+{
+ if ! service_status > /dev/null; then
+ RETVAL=$1
+ return $RETVAL
+ fi
+
+ service_stop
+ service_start
+}
+
+service_status()
+{
+ status -p ${PIDFILE} $DAEMON_PATH/$DAEMON
+}
+
+service_status_quiet()
+{
+ status -p ${PIDFILE} $DAEMON_PATH/$DAEMON >/dev/null 2>&1
+}
+
+case "$1" in
+start)
+ service_status_quiet && exit 0
+ service_start
+;;
+stop)
+ service_status_quiet || exit 0
+ service_stop
+;;
+restart)
+ service_stop
+ service_start
+;;
+try-restart)
+ condrestart 0
+ ;;
+force-reload)
+ condrestart 7
+;;
+status)
+ service_status
+;;
+*)
+ echo "Usage: $0 {start|stop|restart|try-restart|force-reload|status}"
+ exit 3
+esac
diff --git a/system/install-service.sh.in b/system/install-service.sh.in
new file mode 100755
index 00000000..cdd1bf52
--- /dev/null
+++ b/system/install-service.sh.in
@@ -0,0 +1,845 @@
+#!/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="systemd openrc lsb initd runit"
+PLATFORM="$(uname -s)"
+SHOW_SVC_TYPE=0
+SVC_SOURCE="@libsysdir_POST@"
+SVC_TYPE="detect"
+WSL_ERROR_MSG="We appear to be running in WSL and were unable to find a usable service manager. We currently support systemd, LSB init scripts, and traditional init.d style init scripts when running under WSL."
+
+# =====================================================================
+# 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 ${LINUX_INIT_TYPES}"
+ ;;
+ FreeBSD)
+ echo "detect freebsd"
+ ;;
+ Darwin)
+ echo "detect launchd"
+ ;;
+ *)
+ echo "detect"
+ ;;
+ esac
+}
+
+install_generic_service() {
+ svc_path="${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}/${svc_path}/netdata" "${svc_file}"; 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.
+ --show-type Display information about what service managers are detected.
+ --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
+
+_check_systemd() {
+ pids=''
+ p=''
+ myns=''
+ ns=''
+
+ # 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
+ echo "NO" && return 0
+ fi
+
+ # if there is no systemctl command, it is not systemd
+ [ -z "$(command -v systemctl 2>/dev/null || true)" ] && echo "NO" && return 0
+
+ # if pid 1 is systemd, it is systemd
+ [ "$(basename "$(readlink /proc/1/exe)" 2> /dev/null)" = "systemd" ] && echo "YES" && return 0
+
+ # it ‘is’ systemd at this point, but systemd might not be running
+ # if not, return 2 to indicate ‘systemd, but not running’
+ pids=$(safe_pidof systemd 2> /dev/null)
+ [ -z "${pids}" ] && echo "OFFLINE" && return 0
+
+ # 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}" ] && echo "YES" && return 0
+ done
+
+ # else, it is not systemd
+ echo "NO"
+}
+
+check_systemd() {
+ if [ -z "${IS_SYSTEMD}" ]; then
+ IS_SYSTEMD="$(_check_systemd)"
+ fi
+
+ echo "${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}/systemd/netdata.service"
+ PRESET_FILE="${SVC_SOURCE}/systemd/50-netdata.preset"
+ SVCDIR="$(get_systemd_service_dir)"
+
+ if [ "$(systemctl --version | head -n 1 | cut -f 2 -d ' ')" -le 235 ]; then
+ SRCFILE="${SVC_SOURCE}/systemd/netdata.service.v235"
+ fi
+
+ if [ "${ENABLE}" = "auto" ]; then
+ if [ "$(check_systemd)" = "YES" ]; then
+ IS_NETDATA_ENABLED="$(systemctl is-enabled netdata 2> /dev/null || echo "Netdata not there")"
+ fi
+
+ 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}" "${SVCDIR}/netdata.service"; then
+ error "Failed to install systemd service file."
+ exit 4
+ fi
+
+ if [ -f "${PRESET_FILE}" ]; then
+ if ! install -p -m 0644 -o 0 -g 0 "${PRESET_FILE}" "${SVCDIR}-preset/50-netdata.preset"; then
+ warning "Failed to install netdata preset file."
+ fi
+ fi
+
+ if [ "$(check_systemd)" = "YES" ]; then
+ 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
+ fi
+}
+
+systemd_cmds() {
+ if [ "$(check_systemd)" = "YES" ]; then
+ NETDATA_START_CMD='systemctl start netdata'
+ NETDATA_STOP_CMD='systemctl stop netdata'
+ else # systemd is not running, use external defaults by providing no commands
+ warning "Detected systemd, but not booted using systemd. Unable to provide commands to start or stop Netdata using the service manager."
+ fi
+}
+
+# =====================================================================
+# OpenRC support functions
+
+_check_openrc() {
+ # if /lib/rc/sh/functions.sh does not exist, it's not OpenRC
+ [ ! -f /lib/rc/sh/functions.sh ] && echo "NO" && return 0
+
+ # if there is no /etc/init.d, it's not OpenRC
+ [ ! -d /etc/init.d ] && echo "NO" && return 0
+
+ # if there is no /etc/conf.d, it's not OpenRC
+ [ ! -d /etc/conf.d ] && echo "NO" && return 0
+
+ # if there is no rc-update command, it's not OpenRC
+ [ -z "$(command -v rc-update 2>/dev/null || true)" ] && echo "NO" && return 0
+
+ # If /run/openrc/softlevel exists, it's OpenRC
+ [ -f /run/openrc/softlevel ] && echo "YES" && return 0
+
+ # if PID 1 is openrc-init, it's OpenRC
+ [ "$(basename "$(readlink /proc/1/exe)" 2> /dev/null)" = "openrc-init" ] && echo "YES" && return 0
+
+ # if there is an openrc command, it's OpenRC, but not booted as such
+ [ -n "$(command -v openrc 2>/dev/null || true)" ] && echo "OFFLINE" && return 0
+
+ # if /etc/init.d/local exists and has `openrc-run` in it's shebang line, it’s OpenRC, but not booted as such
+ [ -r /etc/init.d/local ] && head -n 1 /etc/init.d/local | grep -q openrc-run && echo "OFFLINE" && return 0
+
+ # Otherwise, it’s not OpenRC
+ echo "NO" && return 0
+}
+
+check_openrc() {
+ if [ -z "${IS_OPENRC}" ]; then
+ IS_OPENRC="$(_check_openrc)"
+ fi
+
+ echo "${IS_OPENRC}"
+}
+
+enable_openrc() {
+ if [ "$(check_openrc)" = "YES" ]; then
+ runlevel="$(rc-status -r)"
+ fi
+
+ 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/init.d OpenRC /etc/init.d/netdata enable_openrc disable_openrc
+
+ if [ ! -f /etc/conf.d/netdata ]; then
+ info "Installing OpenRC configuration file."
+
+ if ! install -p -m 0755 -o 0 -g 0 "${SVC_SOURCE}/openrc/conf.d/netdata" "/etc/conf.d/netdata"; then
+ warning "Failed to install configuration file, however the service will still work."
+ fi
+ fi
+}
+
+openrc_cmds() {
+ if [ "$(check_openrc)" = "YES" ]; then
+ NETDATA_START_CMD='rc-service netdata start'
+ NETDATA_STOP_CMD='rc-service netdata stop'
+ else # Not booted using OpenRC, use external defaults by not providing commands.
+ warning "Detected OpenRC, but the system is not booted using OpenRC. Unable to provide commands to start or stop Netdata using the service manager."
+ fi
+}
+
+# =====================================================================
+# LSB init script support functions
+
+_check_lsb_ignore_systemd() {
+ # if there is no /etc/init.d directory, it’s not an LSB system
+ [ ! -d /etc/init.d ] && echo "NO" && return 0
+
+ # If it's an OpenRC system, then it's not an LSB system
+ [ "$(check_openrc)" != "NO" ] && echo "NO" && return 0
+
+ # If /lib/lsb/init-functions exists, it’s an LSB system
+ [ -f /lib/lsb/init-functions ] && echo "YES" && return 0
+
+ echo "NO" && return 0
+}
+
+_check_lsb() {
+ # if there is _any_ systemd, it’s not an LSB system
+ [ "$(check_systemd)" != "NO" ] && echo "NO" && return 0
+
+ _check_lsb_ignore_systemd
+}
+
+check_lsb() {
+ if [ -z "${IS_LSB}" ]; then
+ IS_LSB="$(_check_lsb)"
+ fi
+
+ echo "${IS_LSB}"
+}
+
+enable_lsb() {
+ if ! update-rc.d netdata defaults; then
+ warning "Failed to enable Netdata service."
+ elif ! update-rc.d netdata defaults-disabled; 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/init.d LSB /etc/init.d/netdata enable_lsb disable_lsb
+}
+
+lsb_cmds() {
+ NETDATA_START_CMD='/etc/init.d/netdata start'
+ NETDATA_STOP_CMD='/etc/init.d/netdata stop'
+}
+
+# =====================================================================
+# init.d init script support functions
+
+_check_initd_ignore_systemd() {
+ # if there is no /etc/init.d directory, it’s not an init.d system
+ [ ! -d /etc/init.d ] && echo "NO" && return 1
+
+ # if there is no chkconfig command, it's not a (usable) init.d system
+ [ -z "$(command -v chkconfig 2>/dev/null || true)" ] && echo "NO" && return 0
+
+ # if there is _any_ openrc, it’s not init.d
+ [ "$(check_openrc)" != "NO" ] && echo "NO" && return 0
+
+ # if it's not an LSB setup, it’s init.d
+ [ "$(check_lsb)" != "NO" ] && echo "NO" && return 0
+
+ echo "YES" && return 0
+}
+
+_check_initd() {
+ # if there is _any_ systemd, it’s not init.d
+ [ "$(check_systemd)" != "NO" ] && echo "NO" && return 0
+
+ _check_initd_ignore_systemd
+}
+
+check_initd() {
+ if [ -z "${IS_INITD}" ]; then
+ IS_INITD="$(_check_initd)"
+ fi
+
+ echo "${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 initd/init.d init.d /etc/init.d/netdata enable_initd disable_initd
+}
+
+initd_cmds() {
+ NETDATA_START_CMD='/etc/init.d/netdata start'
+ NETDATA_STOP_CMD='/etc/init.d/netdata stop'
+}
+
+# =====================================================================
+# runit support functions
+
+_check_runit() {
+ # if there is no runsvdir command, then it's not runit
+ [ -z "$(command -v runsvdir 2>/dev/null || true)" ] && echo "NO" && return 0
+
+ # if there is no runit command, then it's not runit
+ [ -z "$(command -v runit 2>/dev/null || true)" ] && echo "NO" && return 0
+
+ # if /run/runit exists, then it's runit
+ [ -d /run/runit ] && echo "YES" && return 0
+
+ # if /etc/runit/1 exists and is executable, then it's runit
+ [ -x /etc/runit/1 ] && echo "YES" && return 0
+
+ echo "NO" && return 0
+}
+
+check_runit() {
+ if [ -z "${IS_RUNIT}" ]; then
+ IS_RUNIT="$(_check_runit)"
+ fi
+
+ echo "${IS_RUNIT}"
+}
+
+install_runit_service() {
+ if [ -d /etc/sv ]; then
+ svc_dir="/etc/sv/netdata"
+ elif [ -d /etc/runit/sv ]; then
+ svc_dir="/etc/runit/sv/netdata"
+ else
+ error "Failed to locate service directory"
+ exit 4
+ fi
+
+ if [ -d /service ]; then
+ live_svc_dir="/service"
+ elif [ -d /var/service ]; then
+ live_svc_dir="/var/service"
+ elif [ -d /run/runit/service ]; then
+ live_svc_dir="/run/runit/service"
+ elif [ -d /etc/runit/runsvdir/default ]; then
+ live_svc_dir="/etc/runit/runsvdir/default"
+ else
+ error "Failed to locate live service directory"
+ exit 4
+ fi
+
+ svc_file="${svc_dir}/run"
+
+ info "Installing runit service file."
+ if [ ! -f "${svc_file}" ] && [ "${ENABLE}" = "auto" ]; then
+ ENABLE="enable"
+ fi
+
+ if ! install -D -p -m 0755 -o 0 -g 0 "${SVC_SOURCE}/runit/run" "${svc_file}"; then
+ error "Failed to install service file."
+ exit 4
+ fi
+
+ case ${ENABLE} in
+ enable)
+ if ! ln -s "${svc_dir}" "${live_svc_dir}"; then
+ warning "Failed to enable the Netdata service."
+ fi
+ ;;
+ disable)
+ if ! rm "${live_svc_dir}/netdata"; then
+ warning "Failed to disable the Netdata service."
+ fi
+ ;;
+ esac
+}
+
+runit_cmds() {
+ NETDATA_START_CMD="sv start netdata"
+ NETDATA_STOP_CMD="sv stop netdata"
+}
+
+# =====================================================================
+# WSL support functions
+
+_check_wsl() {
+ # If uname -r contains the string WSL, then it's WSL.
+ uname -r | grep -q 'WSL' && echo "YES" && 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" && echo "YES" && return 0
+
+ echo "NO" && return 0
+}
+
+check_wsl() {
+ if [ -z "${IS_WSL}" ]; then
+ IS_WSL="$(_check_wsl)"
+ fi
+
+ echo "${IS_WSL}"
+}
+
+install_wsl_service() {
+ error "${WSL_ERROR_MSG}"
+ exit 3
+}
+
+wsl_cmds() {
+ error "${WSL_ERROR_MSG}"
+ 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/rc.d "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 "${SVC_SOURCE}/launchd/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
+ found_types=''
+
+ for t in wsl ${LINUX_INIT_TYPES}; do
+ case "$("check_${t}")" in
+ YES)
+ SVC_TYPE="${t}"
+ break
+ ;;
+ NO) continue ;;
+ OFFLINE)
+ if [ -z "${found_types}" ]; then
+ found_types="${t}"
+ else
+ found_types="${found_types} ${t}"
+ fi
+ ;;
+ esac
+ done
+
+ if [ "${SVC_TYPE}" = "detect" ]; then
+ if [ -z "${found_types}" ]; then
+ error "Failed to detect what type of service manager is in use."
+ else
+ SVC_TYPE="$(echo "${found_types}" | cut -f 1 -d ' ')"
+ warning "Failed to detect a running service manager, using detected (but not running) ${SVC_TYPE}."
+ fi
+ elif [ "${SVC_TYPE}" = "wsl" ]; then
+ if [ "$(check_systemd)" = "YES" ]; then
+ # Support for systemd in WSL.
+ SVC_TYPE="systemd"
+ elif [ "$(_check_lsb_ignore_systemd)" = "YES" ]; then
+ # Support for LSB init.d in WSL.
+ SVC_TYPE="lsb"
+ elif [ "$(_check_initd_ignore_systemd)" = "YES" ]; then
+ # Support for ‘generic’ init.d in WSL.
+ SVC_TYPE="initd"
+ fi
+ fi
+ fi
+
+ echo "${SVC_TYPE}"
+}
+
+install_linux_service() {
+ t="$(detect_linux_svc_type)"
+
+ if [ -z "${t}" ] || [ "${t}" = 'detect' ]; then
+ exit 2
+ fi
+
+ "install_${t}_service"
+}
+
+linux_cmds() {
+ t="$(detect_linux_svc_type)"
+
+ if [ -z "${t}" ] || [ "${t}" = 'detect' ]; then
+ exit 2
+ fi
+
+ "${t}_cmds"
+}
+
+# =====================================================================
+# Service type display function
+
+show_service_type() {
+ info "Detected platform: ${PLATFORM}"
+
+ case "${PLATFORM}" in
+ FreeBSD)
+ info "Detected service managers:"
+ info " - freebsd: YES"
+ info "Would use freebsd service management."
+ ;;
+ Darwin)
+ info "Detected service managers:"
+ info " - launchd: YES"
+ info "Would use launchd service management."
+ ;;
+ Linux)
+ [ "$(check_wsl)" = "YES" ] && info "Detected WSL environment."
+ info "Detected service managers:"
+ for t in ${LINUX_INIT_TYPES}; do
+ info " - ${t}: $("check_${t}")"
+ done
+ info "Would use $(detect_linux_svc_type) service management."
+ ;;
+ *)
+ info "${PLATFORM} is not supported by this script. No service file would be installed."
+ esac
+
+ exit 0
+}
+
+# =====================================================================
+# 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
+ ;;
+ "--show-type") SHOW_SVC_TYPE=1 ; INSTALL=0 ;;
+ "--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 "${@}"
+
+ if [ "${SHOW_SVC_TYPE}" -eq 1 ]; then
+ show_service_type
+ else
+ 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
+ fi
+
+ exit 0
+}
+
+main "${@}"
diff --git a/system/launchd/netdata.plist.in b/system/launchd/netdata.plist.in
new file mode 100644
index 00000000..bce489ef
--- /dev/null
+++ b/system/launchd/netdata.plist.in
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<!-- SPDX-License-Identifier: GPL-3.0-or-later -->
+<plist version="1.0">
+<dict>
+ <key>Label</key>
+ <string>com.github.netdata</string>
+ <key>ProgramArguments</key>
+ <array>
+ <string>@sbindir_POST@/netdata</string>
+ <string>-D</string>
+ </array>
+ <key>RunAtLoad</key>
+ <true/>
+</dict>
+</plist>
diff --git a/system/logrotate/netdata.in b/system/logrotate/netdata.in
new file mode 100644
index 00000000..2c4949e5
--- /dev/null
+++ b/system/logrotate/netdata.in
@@ -0,0 +1,12 @@
+@localstatedir_POST@/log/netdata/*.log {
+ daily
+ missingok
+ rotate 14
+ compress
+ delaycompress
+ notifempty
+ sharedscripts
+ postrotate
+ /bin/kill -HUP `cat /run/netdata/netdata.pid 2>/dev/null` 2>/dev/null || true
+ endscript
+}
diff --git a/system/lsb/init.d/netdata.in b/system/lsb/init.d/netdata.in
new file mode 100644
index 00000000..e429ad1c
--- /dev/null
+++ b/system/lsb/init.d/netdata.in
@@ -0,0 +1,116 @@
+#!/usr/bin/env bash
+#
+# Netdata LSB start script
+#
+# Copyright:
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# Author:
+# Costa Tsaousis <costa@netdata.cloud>
+# Pavlos Emm. Katsoulakis <paul@netdata.cloud>
+
+### BEGIN INIT INFO
+# Provides: netdata
+# Required-Start: $local_fs $remote_fs $network $named $time
+# Required-Stop: $local_fs $remote_fs $network $named $time
+# Should-Start: $local_fs $network $named $remote_fs $time $all
+# Should-Stop: $local_fs $network $named $remote_fs $time $all
+# Default-Start: 2 3 4 5
+# Default-Stop: 0 1 6
+# Short-Description: Start and stop the netdata real-time monitoring server daemon
+# Description: Controls the main netdata monitoring server daemon "netdata".
+# and all its plugins.
+### END INIT INFO
+#
+set -e
+set -u
+${DEBIAN_SCRIPT_DEBUG:+ set -v -x}
+
+DAEMON="netdata"
+DAEMON_PATH=@sbindir_POST@
+PIDFILE_PATH=@localstatedir_POST@/run/netdata
+PIDFILE=$PIDFILE_PATH/$DAEMON.pid
+DAEMONOPTS="-P $PIDFILE"
+
+test -x $DAEMON_PATH/$DAEMON || exit 0
+
+. /lib/lsb/init-functions
+
+# Safeguard (relative paths, core dumps..)
+cd /
+umask 022
+
+service_start() {
+ if [ ! -d $PIDFILE_PATH ]; then
+ mkdir -p $PIDFILE_PATH
+ fi
+
+ chown @netdata_user_POST@:@netdata_user_POST@ $PIDFILE_PATH
+
+ log_daemon_msg "Starting real-time performance monitoring" "netdata"
+ start_daemon -p $PIDFILE $DAEMON_PATH/$DAEMON $DAEMONOPTS
+ RETVAL=$?
+ log_end_msg $RETVAL
+ return $RETVAL
+}
+
+service_stop() {
+ log_daemon_msg "Stopping real-time performance monitoring" "netdata"
+ killproc -p ${PIDFILE} $DAEMON_PATH/$DAEMON
+ RETVAL=$?
+ log_end_msg $RETVAL
+
+ if [ $RETVAL -eq 0 ]; then
+ rm -f ${PIDFILE}
+ fi
+ return $RETVAL
+}
+
+condrestart() {
+ if ! service_status > /dev/null; then
+ RETVAL=$1
+ return
+ fi
+
+ service_stop
+ service_start
+}
+
+service_status() {
+ status_of_proc -p $PIDFILE $DAEMON_PATH/$DAEMON netdata
+}
+
+
+#
+# main()
+#
+
+case "${1:-''}" in
+ 'start')
+ service_start
+ ;;
+
+ 'stop')
+ service_stop
+ ;;
+
+ 'restart')
+ service_stop
+ service_start
+ ;;
+
+ 'try-restart')
+ condrestart 0
+ ;;
+
+ 'force-reload')
+ condrestart 7
+ ;;
+
+ 'status')
+ service_status && exit 0 || exit $?
+ ;;
+ *)
+ echo "Usage: $0 {start|stop|restart|try-restart|force-reload|status}"
+ exit 1
+esac
diff --git a/system/netdata-updater.conf b/system/netdata-updater.conf
new file mode 100644
index 00000000..09af046b
--- /dev/null
+++ b/system/netdata-updater.conf
@@ -0,0 +1,21 @@
+# Configuration for netdata-updater.sh script.
+#
+# When run non-interactively, the updater script will delay some
+# random number of seconds up to NETDATA_UPDATER_JITTER before
+# actually running the update. The default is 3600 (one
+# hour). Most users should not need to change this.
+#NETDATA_UPDATER_JITTER="3600"
+
+# On systems using our native packages, the updater will by default
+# attempt to install optional plugin packages that would be installed by
+# default on clean installs if those packages are supported on the system.
+#
+# This behavior can be disabled on a per-package basis using the below
+# variables. Setting the variable to a value other than 0 will disable
+# the corresponding package (note that you still need to remove the package
+# yourself if you don0t want it, this just controls whether the updater
+# will try to ensure it’s installed or not).
+#
+# NETDATA_NO_SYSTEMD_JOURNAL controls the `netdata-plugin-systemd-journal`
+# package, which provides the systemd journal plugin for Netdata.
+#NETDATA_NO_SYSTEMD_JOURNAL="0"
diff --git a/system/netdata.conf b/system/netdata.conf
new file mode 100644
index 00000000..94d9ab82
--- /dev/null
+++ b/system/netdata.conf
@@ -0,0 +1,23 @@
+# netdata configuration
+#
+# You can get the latest version of this file, using:
+#
+# netdatacli dumpconfig > /etc/netdata/netdata.conf
+#
+# You can also download it using:
+#
+# wget -O /etc/netdata/netdata.conf http://localhost:19999/netdata.conf
+# or
+# curl -o /etc/netdata/netdata.conf http://localhost:19999/netdata.conf
+#
+# You can uncomment and change any of the options below.
+# The value shown in the commented settings, is the default value.
+#
+
+[global]
+ run as user = netdata
+
+ # default storage size - increase for longer data retention
+ page cache size = 32
+ dbengine multihost disk space = 256
+
diff --git a/system/openrc/conf.d/netdata.in b/system/openrc/conf.d/netdata.in
new file mode 100644
index 00000000..92f88260
--- /dev/null
+++ b/system/openrc/conf.d/netdata.in
@@ -0,0 +1,24 @@
+# The user netdata is configured to run as.
+# If you edit its configuration file to set a different user, set it
+# here too, to have its files switch ownership
+NETDATA_OWNER="@netdata_user_POST@:@netdata_user_POST@"
+
+# How long to wait for the agent to save it's database during shutdown.
+NETDATA_WAIT_EXIT_TIMEOUT=60
+
+# If set to 1, force an exit if we time out waiting for the agent to
+# save it's database during shutdown.
+NETDATA_FORCE_EXIT=0
+
+# If set to 1, use netdatacli when sending commands to the agent.
+# This should not be needed in most cases, but it can sometimes help
+# work around issues.
+#NETDATA_USE_NETDATACLI=1
+
+# Specify the path to the pidfile to be used when running in the
+# background.
+NETDATA_PIDFILE="@localstatedir_POST@/run/netdata/netdata.pid"
+
+# Uncomment the below line to run Netdata under OpenRC's native process
+# supervision.
+#supervisor="supervise-daemon"
diff --git a/system/openrc/init.d/netdata.in b/system/openrc/init.d/netdata.in
new file mode 100644
index 00000000..8dede179
--- /dev/null
+++ b/system/openrc/init.d/netdata.in
@@ -0,0 +1,79 @@
+#!/sbin/openrc-run
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+NETDATA_OWNER="@netdata_user_POST@:@netdata_user_POST@"
+NETDATA_PIDFILE="@localstatedir_POST@/run/netdata/netdata.pid"
+
+description="Run the Netdata system monitoring agent."
+
+extra_started_commands="reload rotate save"
+description_reload="Reload health configuration."
+description_rotate="Reopen log files."
+description_save="Force sync of database to disk."
+
+command_prefix="@sbindir_POST@"
+command="${command_prefix}/netdata"
+command_args="-P ${NETDATA_PIDFILE} ${NETDATA_EXTRA_ARGS}"
+command_args_foreground="-D"
+
+depend() {
+ use logger
+ need net
+ after apache2 squid nginx mysql named opensips upsd hostapd postfix lm_sensors
+}
+
+start_pre() {
+ checkpath -o ${NETDATA_OWNER} -d @localstatedir_POST@/run/netdata
+
+ if [ -z "${supervisor}" ]; then
+ pidfile="${NETDATA_PIDFILE}"
+ fi
+}
+
+stop_pre() {
+ if [ "0${NETDATA_FORCE_EXIT}" -eq 1 ]; then
+ retry="TERM/${NETDATA_WAIT_EXIT_TIMEOUT:-60}/KILL/1"
+ else
+ retry="TERM/${NETDATA_WAIT_EXIT_TIMEOUT:-60}"
+ fi
+}
+
+run_cmd() {
+ cmd="${1}"
+ msg="${2}"
+ failmsg="${3}"
+ signal="${4}"
+
+ ebegin "${msg}"
+ if [ "${NETDATA_USE_NETDATACLI}" = 1 ]; then
+ "${command_prefix}/netdatacli" "${cmd}" >/dev/null
+ eend $? "${failmsg}"
+ elif [ "${supervisor}" = "supervise-daemon" ]; then
+ supervise-daemon "${RC_SVCNAME}" --signal "${signal}"
+ eend $? "${failmsg}"
+ else
+ start-stop-daemon --signal "${signal}" --pidfile "${pidfile}"
+ eend $? "${failmsg}"
+ fi
+}
+
+reload() {
+ run_cmd reload-health \
+ "Reloading Netdata health configuration" \
+ "Failed to reload Netdata health configuration" \
+ SIGUSR2
+}
+
+rotate() {
+ run_cmd reopen-logs \
+ "Reopening Netdata log files" \
+ "Failed to reopen Netdata log files" \
+ SIGHUP
+}
+
+save() {
+ run_cmd save-database \
+ "Saving Netdata database" \
+ "Failed to save Netdata database" \
+ SIGUSR1
+}
diff --git a/system/runit/run.in b/system/runit/run.in
new file mode 100644
index 00000000..d7f39fb6
--- /dev/null
+++ b/system/runit/run.in
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+piddir="@localstatedir_POST@/run/netdata/netdata.pid"
+pidfile="${piddir}/netdata.pid"
+
+command="@sbindir_POST@/netdata"
+command_args="-P ${pidfile} -D"
+
+[ ! -d "${piddir}" ] && mkdir -p "${piddir}"
+chown -R @netdata_user_POST@ "${piddir}"
+
+exec ${command} ${command_args}
diff --git a/system/systemd/50-netdata.preset b/system/systemd/50-netdata.preset
new file mode 100644
index 00000000..fe4e5a19
--- /dev/null
+++ b/system/systemd/50-netdata.preset
@@ -0,0 +1 @@
+enable netdata.service
diff --git a/system/systemd/netdata-updater.service.in b/system/systemd/netdata-updater.service.in
new file mode 100644
index 00000000..d0bd4994
--- /dev/null
+++ b/system/systemd/netdata-updater.service.in
@@ -0,0 +1,8 @@
+[Unit]
+Description=Daily auto-updates for Netdata
+RefuseManualStart=no
+RefuseManualStop=yes
+
+[Service]
+Type=oneshot
+ExecStart=@pkglibexecdir_POST@/netdata-updater.sh
diff --git a/system/systemd/netdata-updater.timer b/system/systemd/netdata-updater.timer
new file mode 100644
index 00000000..8b36e46f
--- /dev/null
+++ b/system/systemd/netdata-updater.timer
@@ -0,0 +1,12 @@
+[Unit]
+Description=Daily auto-updates for Netdata
+RefuseManualStart=no
+RefuseManualStop=no
+
+[Timer]
+Persistent=false
+OnCalendar=daily
+Unit=netdata-updater.service
+
+[Install]
+WantedBy=timers.target
diff --git a/system/systemd/netdata.service.in b/system/systemd/netdata.service.in
new file mode 100644
index 00000000..7d15dad7
--- /dev/null
+++ b/system/systemd/netdata.service.in
@@ -0,0 +1,84 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+[Unit]
+Description=Real time performance monitoring
+
+# append here other services you want netdata to wait for them to start
+After=network.target
+
+[Service]
+LogNamespace=netdata
+Type=simple
+User=root
+RuntimeDirectory=netdata
+RuntimeDirectoryMode=0775
+PIDFile=/run/netdata/netdata.pid
+ExecStart=@sbindir_POST@/netdata -P /run/netdata/netdata.pid -D
+ExecStartPre=/bin/mkdir -p @localstatedir_POST@/cache/netdata
+ExecStartPre=/bin/chown -R @netdata_user_POST@ @localstatedir_POST@/cache/netdata
+ExecStartPre=/bin/mkdir -p /run/netdata
+ExecStartPre=/bin/chown -R @netdata_user_POST@ /run/netdata
+PermissionsStartOnly=true
+
+# saving a big db on slow disks may need some time
+TimeoutStopSec=150
+
+# restart netdata if it crashes
+Restart=on-failure
+RestartSec=30
+
+# Valid policies: other (the system default) | batch | idle | fifo | rr
+# To give netdata the max priority, set CPUSchedulingPolicy=rr and CPUSchedulingPriority=99
+CPUSchedulingPolicy=batch
+
+# This sets the scheduling priority (for policies: rr and fifo).
+# Priority gets values 1 (lowest) to 99 (highest).
+#CPUSchedulingPriority=1
+
+# For scheduling policy 'other' and 'batch', this sets the lowest niceness of netdata (-20 highest to 19 lowest).
+Nice=0
+
+# Capabilities
+# is required for freeipmi and slabinfo plugins
+CapabilityBoundingSet=CAP_DAC_OVERRIDE
+# is required for apps plugin
+CapabilityBoundingSet=CAP_DAC_READ_SEARCH
+# is required for freeipmi plugin
+CapabilityBoundingSet=CAP_FOWNER CAP_SYS_RAWIO
+# is required for apps, perf and slabinfo plugins
+CapabilityBoundingSet=CAP_SETPCAP
+# is required for perf plugin
+CapabilityBoundingSet=CAP_SYS_ADMIN CAP_PERFMON
+# is required for apps plugin
+CapabilityBoundingSet=CAP_SYS_PTRACE
+# is required for ebpf plugin
+CapabilityBoundingSet=CAP_SYS_RESOURCE
+# is required for go.d/ping app
+CapabilityBoundingSet=CAP_NET_RAW
+# is required for cgroups plugin
+CapabilityBoundingSet=CAP_SYS_CHROOT
+# is required for nfacct plugin (bandwidth accounting)
+CapabilityBoundingSet=CAP_NET_ADMIN
+# is required for plugins that use sudo
+CapabilityBoundingSet=CAP_SETGID CAP_SETUID
+# is required to change file ownership
+CapabilityBoundingSet=CAP_CHOWN
+# is required for logs-management.plugin
+CapabilityBoundingSet=CAP_SYSLOG
+
+# Sandboxing
+ProtectSystem=full
+ProtectHome=read-only
+# PrivateTmp break netdatacli functionality. See - https://github.com/netdata/netdata/issues/7587
+#PrivateTmp=true
+ProtectControlGroups=on
+# We whitelist this because it's the standard location to listen on a UNIX socket.
+ReadWriteDirectories=/run/netdata
+# This is needed to make email-based alert deliver work if Postfix is the email provider on the system.
+ReadWriteDirectories=-/var/spool/postfix/maildrop
+# LXCFS directories (https://github.com/lxc/lxcfs#lxcfs)
+# If we don't set them explicitly, systemd mounts procfs from the host. See https://github.com/netdata/netdata/issues/14238.
+BindReadOnlyPaths=-/proc/cpuinfo -/proc/diskstats -/proc/loadavg -/proc/meminfo
+BindReadOnlyPaths=-/proc/stat -/proc/swaps -/proc/uptime -/proc/slabinfo
+
+[Install]
+WantedBy=multi-user.target
diff --git a/system/systemd/netdata.service.v235.in b/system/systemd/netdata.service.v235.in
new file mode 100644
index 00000000..06f03b26
--- /dev/null
+++ b/system/systemd/netdata.service.v235.in
@@ -0,0 +1,34 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+[Unit]
+Description=Real time performance monitoring
+
+# append here other services you want netdata to wait for them to start
+After=network.target
+
+[Service]
+LogNamespace=netdata
+Type=simple
+User=root
+EnvironmentFile=-/etc/default/netdata
+ExecStart=@sbindir_POST@/netdata -D $EXTRA_OPTS
+
+# saving a big db on slow disks may need some time
+TimeoutStopSec=150
+
+# restart netdata if it crashes
+Restart=on-failure
+RestartSec=30
+
+# Valid policies: other (the system default) | batch | idle | fifo | rr
+# To give netdata the max priority, set CPUSchedulingPolicy=rr and CPUSchedulingPriority=99
+CPUSchedulingPolicy=batch
+
+# This sets the scheduling priority (for policies: rr and fifo).
+# Priority gets values 1 (lowest) to 99 (highest).
+#CPUSchedulingPriority=1
+
+# For scheduling policy 'other' and 'batch', this sets the lowest niceness of netdata (-20 highest to 19 lowest).
+Nice=0
+
+[Install]
+WantedBy=multi-user.target
diff --git a/system/vnodes/vnodes.conf b/system/vnodes/vnodes.conf
new file mode 100644
index 00000000..abcd5784
--- /dev/null
+++ b/system/vnodes/vnodes.conf
@@ -0,0 +1,23 @@
+## This file is in YAML format.
+##
+## It contains a list of virtual nodes. Virtual node, defined with the following parameters:
+##
+## 1. hostname
+## The hostname of the virtual node. String. Required.
+## 2. guid
+## Uniquely identifies the node. String. Required.
+## 3. labels
+## The virtual node host labels. Dictionary in the form key: value. Optional.
+## Special labels that are used to set virtual host system information:
+## https://learn.netdata.cloud/docs/improving-netdata---developers/external-plugins#host_label
+##
+## You can create GUIDs online: https://www.guidgen.com/
+## or generate with the linux command: uuidgen
+##
+## ---------------------------------------------------------------------------------------------------------------------
+
+#- hostname: HOSTNAME1
+# guid: GUID1
+#
+#- hostname: HOSTNAME2
+# guid: GUID2