mirror of
https://github.com/netdata/netdata.git
synced 2025-02-11 00:12:34 +00:00
![Austin S. Hemmelgarn](/assets/img/avatar_default.png)
* Query systemd for unit file paths on install/uninstall. This makes our installation code more portable and more concise, and should make the uninstallation code significantly more robust. Also includes a number of other improvements to systemd handling and updater handling in the uninstaller that should make it much more thorough and reliable. * Fix issues brought up in code review, and better support old systemd versions. * Replace sed with AWK for readability. * Fix uninstaller loop. * Fix unit file detection in updater code.
923 lines
24 KiB
Bash
Executable file
923 lines
24 KiB
Bash
Executable file
#!/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 dinit"
|
||
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 there is no systemctl command, it is not systemd
|
||
[ -z "$(command -v systemctl 2>/dev/null || true)" ] && echo "NO" && return 0
|
||
|
||
# Check the output of systemctl is-system-running.
|
||
#
|
||
# This may return a non-zero exit status in cases when it actually
|
||
# succeeded for our purposes, so we need to toggle set -e off here.
|
||
set +e
|
||
systemd_state="$(systemctl is-system-running)"
|
||
set -e
|
||
|
||
case "${systemd_state}" in
|
||
offline) echo "OFFLINE" && return 0 ;;
|
||
unknown) : ;;
|
||
"") : ;;
|
||
*) echo "YES" && return 0 ;;
|
||
esac
|
||
|
||
# if pid 1 is systemd, it is systemd
|
||
[ "$(basename "$(readlink /proc/1/exe)" 2> /dev/null)" = "systemd" ] && echo "YES" && 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
|
||
|
||
# At this point, we know it’s a systemd system because systemctl
|
||
# exists, but systemd does not appear to be running, so indicate as such
|
||
echo "OFFLINE"
|
||
}
|
||
|
||
check_systemd() {
|
||
if [ -z "${IS_SYSTEMD}" ]; then
|
||
IS_SYSTEMD="$(_check_systemd)"
|
||
fi
|
||
|
||
echo "${IS_SYSTEMD}"
|
||
}
|
||
|
||
get_systemd_service_dir() {
|
||
set +e
|
||
unit_paths="$(systemctl show -p UnitPath | cut -f 2- -d '=' | tr ' ' '\n')"
|
||
set -e
|
||
|
||
if [ -n "${unit_paths}" ]; then
|
||
lib_paths="$(echo "${unit_paths}" | grep -vE '^/(run|etc)' | awk '{line[NR] = $0} END {for (i = NR; i > 0; i--) print line[i]}')"
|
||
etc_paths="$(echo "${unit_paths}" | grep -E '^/etc' | grep -vE '(attached|control)$')"
|
||
else
|
||
lib_paths="/usr/lib/systemd/system /lib/systemd/system /usr/local/lib/systemd/system"
|
||
etc_paths="/etc/systemd/system"
|
||
fi
|
||
|
||
for path in ${lib_paths} ${etc_paths}; do
|
||
if [ -d "${path}" ] && [ -w "${path}" ]; then
|
||
echo "${path}"
|
||
return 0
|
||
fi
|
||
done
|
||
|
||
error "Unable to detect usable systemd service directory."
|
||
exit 4
|
||
}
|
||
|
||
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"
|
||
}
|
||
|
||
# =====================================================================
|
||
# dinit support functions
|
||
|
||
_check_dinit() {
|
||
# if /etc/dinit.d does not exist, it’s not dinit
|
||
[ ! -d /etc/dinit.d ] && echo "NO" && return 0
|
||
|
||
# if PID 1 is dinit, it’s dinit
|
||
[ "$(basename "$(readlink /proc/1/exe)" 2> /dev/null)" = "dinit" ] && echo "YES" && return 0
|
||
|
||
# if /run/dinitctl exists and is a socket, it’s dinit
|
||
[ -S /run/dinitctl ] && echo "YES" && return 0
|
||
|
||
# if the dinitctl command exists despite getting to this point, it’s dinit, but not booted as such
|
||
[ -n "$(command -v dinitctl 2>/dev/null || true)" ] && echo "OFFLINE" && return 0
|
||
|
||
echo "NO" && return 0
|
||
}
|
||
|
||
check_dinit() {
|
||
if [ -z "${IS_DINIT}" ]; then
|
||
IS_DINIT="$(_check_dinit)"
|
||
fi
|
||
|
||
echo "${IS_DINIT}"
|
||
}
|
||
|
||
_run_dinitctl() {
|
||
opts=''
|
||
|
||
if [ "$(check_dinit)" = "OFFLINE" ]; then
|
||
opts="-o"
|
||
fi
|
||
|
||
# shellcheck disable=SC2086
|
||
dinitctl ${opts} "${@}"
|
||
}
|
||
|
||
enable_dinit() {
|
||
_run_dinitctl enable netdata
|
||
}
|
||
|
||
enable_dinit() {
|
||
_run_dinitctl disable netdata
|
||
}
|
||
|
||
install_dinit_service() {
|
||
install_generic_service dinit/netdata "dinit" /etc/dinit.d enable_dinit disable_dinit
|
||
}
|
||
|
||
dinit_cmds() {
|
||
if [ "$(check_dinit)" = "YES" ]; then
|
||
NETDATA_START_CMD='dinitctl start netdata'
|
||
NETDATA_STOP_CMD='dinitct stop netdata'
|
||
else # Not booted using dinit, use external defaults by not providing commands.
|
||
warning "Detected dinit, but the system is not booted using dinit. Unable to provide commands to start or stop Netdata using the service manager."
|
||
fi
|
||
}
|
||
|
||
# =====================================================================
|
||
# 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
|
||
|
||
launchctl unload /Library/LaunchDaemons/com.github.netdata.plist 2>/dev/null
|
||
|
||
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 "${@}"
|