install-service.sh.in 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923
  1. #!/usr/bin/env sh
  2. # SPDX-License-Identifier: GPL-3.0-or-later
  3. # Handle installation of the Netdata agent as a system service.
  4. #
  5. # Exit codes:
  6. # 0 - Successfully installed service.
  7. # 1 - Invalid arguments or other internal error.
  8. # 2 - Unable to detect system service type.
  9. # 3 - Detected system service type, but type not supported.
  10. # 4 - Detected system service type, but could not install due to other issues.
  11. # 5 - Platform not supported.
  12. set -e
  13. SCRIPT_SOURCE="$(
  14. self=${0}
  15. while [ -L "${self}" ]
  16. do
  17. cd "${self%/*}" || exit 1
  18. self=$(readlink "${self}")
  19. done
  20. cd "${self%/*}" || exit 1
  21. echo "$(pwd -P)/${self##*/}"
  22. )"
  23. DUMP_CMDS=0
  24. ENABLE="auto"
  25. EXPORT_CMDS=0
  26. INSTALL=1
  27. LINUX_INIT_TYPES="systemd openrc lsb initd runit dinit"
  28. PLATFORM="$(uname -s)"
  29. SHOW_SVC_TYPE=0
  30. SVC_SOURCE="@libsysdir_POST@"
  31. SVC_TYPE="detect"
  32. 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."
  33. # =====================================================================
  34. # Utility functions
  35. cleanup() {
  36. ec="${?}"
  37. if [ -n "${NETDATA_SAVE_WARNINGS}" ]; then
  38. if [ -n "${NETDATA_PROPAGATE_WARNINGS}" ]; then
  39. export NETDATA_WARNINGS="${NETDATA_WARNINGS}${SAVED_WARNINGS}"
  40. fi
  41. fi
  42. trap - EXIT
  43. exit "${ec}"
  44. }
  45. info() {
  46. printf >&2 "%s\n" "${*}"
  47. }
  48. warning() {
  49. if [ -n "${NETDATA_SAVE_WARNINGS}" ]; then
  50. SAVED_WARNINGS="${SAVED_WARNINGS}\n - ${*}"
  51. fi
  52. printf >&2 "WARNING: %s\n" "${*}"
  53. }
  54. error() {
  55. if [ -n "${NETDATA_SAVE_WARNINGS}" ]; then
  56. SAVED_WARNINGS="${SAVED_WARNINGS}\n - ${*}"
  57. fi
  58. printf >&2 "ERROR: %s\n" "${*}"
  59. }
  60. get_os_key() {
  61. if [ -f /etc/os-release ]; then
  62. # shellcheck disable=SC1091
  63. . /etc/os-release || return 1
  64. echo "${ID}-${VERSION_ID}"
  65. elif [ -f /etc/redhat-release ]; then
  66. cat /etc/redhat-release
  67. else
  68. echo "unknown"
  69. fi
  70. }
  71. valid_types() {
  72. case "${PLATFORM}" in
  73. Linux)
  74. echo "detect ${LINUX_INIT_TYPES}"
  75. ;;
  76. FreeBSD)
  77. echo "detect freebsd"
  78. ;;
  79. Darwin)
  80. echo "detect launchd"
  81. ;;
  82. *)
  83. echo "detect"
  84. ;;
  85. esac
  86. }
  87. install_generic_service() {
  88. svc_path="${1}"
  89. svc_type_name="${2}"
  90. svc_file="${3}"
  91. svc_enable_hook="${4}"
  92. svc_disable_hook="${5}"
  93. info "Installing ${svc_type_name} service file."
  94. if [ ! -f "${svc_file}" ] && [ "${ENABLE}" = "auto" ]; then
  95. ENABLE="enable"
  96. fi
  97. if ! install -p -m 0755 -o 0 -g 0 "${SVC_SOURCE}/${svc_path}/netdata" "${svc_file}"; then
  98. error "Failed to install service file."
  99. exit 4
  100. fi
  101. case "${ENABLE}" in
  102. auto) true ;;
  103. disable)
  104. info "Disabling Netdata service."
  105. ${svc_disable_hook}
  106. ;;
  107. enable)
  108. info "Enabling Netdata service."
  109. ${svc_enable_hook}
  110. ;;
  111. esac
  112. }
  113. dump_cmds() {
  114. [ -n "${NETDATA_START_CMD}" ] && echo "NETDATA_START_CMD='${NETDATA_START_CMD}'"
  115. [ -n "${NETDATA_STOP_CMD}" ] && echo "NETDATA_STOP_CMD='${NETDATA_STOP_CMD}'"
  116. [ -n "${NETDATA_INSTALLER_START_CMD}" ] && echo "NETDATA_INSTALLER_START_CMD='${NETDATA_INSTALLER_START_CMD}'"
  117. return 0
  118. }
  119. export_cmds() {
  120. [ -n "${NETDATA_START_CMD}" ] && export NETDATA_START_CMD="${NETDATA_START_CMD}"
  121. [ -n "${NETDATA_STOP_CMD}" ] && export NETDATA_STOP_CMD="${NETDATA_STOP_CMD}"
  122. [ -n "${NETDATA_INSTALLER_START_CMD}" ] && export NETDATA_INSTALLER_START_CMD="${NETDATA_INSTALLER_START_COMMAND}"
  123. return 0
  124. }
  125. save_cmds() {
  126. dump_cmds > "${SAVE_CMDS_PATH}"
  127. }
  128. # =====================================================================
  129. # Help functions
  130. usage() {
  131. cat << HEREDOC
  132. USAGE: install-service.sh [options]
  133. where options include:
  134. --source Specify where to find the service files to install (default ${SVC_SOURCE}).
  135. --type Specify the type of service file to install. Specify a type of 'help' to get a list of valid types for your platform.
  136. --show-type Display information about what service managers are detected.
  137. --cmds Additionally print a list of commands for starting and stopping the agent with the detected service type.
  138. --export-cmds Export the variables that would be printed by the --cmds option.
  139. --cmds-only Don't install, just handle the --cmds or --export-cmds option.
  140. --enable Explicitly enable the service on install (default is to enable if not already installed).
  141. --disable Explicitly disable the service on install.
  142. --help Print this help information.
  143. HEREDOC
  144. }
  145. help_types() {
  146. cat << HEREDOC
  147. Valid service types for ${PLATFORM} are:
  148. $(valid_types)
  149. HEREDOC
  150. }
  151. # =====================================================================
  152. # systemd support functions
  153. _check_systemd() {
  154. pids=''
  155. p=''
  156. myns=''
  157. ns=''
  158. # if there is no systemctl command, it is not systemd
  159. [ -z "$(command -v systemctl 2>/dev/null || true)" ] && echo "NO" && return 0
  160. # Check the output of systemctl is-system-running.
  161. #
  162. # This may return a non-zero exit status in cases when it actually
  163. # succeeded for our purposes, so we need to toggle set -e off here.
  164. set +e
  165. systemd_state="$(systemctl is-system-running)"
  166. set -e
  167. case "${systemd_state}" in
  168. offline) echo "OFFLINE" && return 0 ;;
  169. unknown) : ;;
  170. "") : ;;
  171. *) echo "YES" && return 0 ;;
  172. esac
  173. # if pid 1 is systemd, it is systemd
  174. [ "$(basename "$(readlink /proc/1/exe)" 2> /dev/null)" = "systemd" ] && echo "YES" && return 0
  175. # check if the running systemd processes are not in our namespace
  176. myns="$(readlink /proc/self/ns/pid 2> /dev/null)"
  177. for p in ${pids}; do
  178. ns="$(readlink "/proc/${p}/ns/pid" 2> /dev/null)"
  179. # if pid of systemd is in our namespace, it is systemd
  180. [ -n "${myns}" ] && [ "${myns}" = "${ns}" ] && echo "YES" && return 0
  181. done
  182. # At this point, we know it’s a systemd system because systemctl
  183. # exists, but systemd does not appear to be running, so indicate as such
  184. echo "OFFLINE"
  185. }
  186. check_systemd() {
  187. if [ -z "${IS_SYSTEMD}" ]; then
  188. IS_SYSTEMD="$(_check_systemd)"
  189. fi
  190. echo "${IS_SYSTEMD}"
  191. }
  192. get_systemd_service_dir() {
  193. set +e
  194. unit_paths="$(systemctl show -p UnitPath | cut -f 2- -d '=' | tr ' ' '\n')"
  195. set -e
  196. if [ -n "${unit_paths}" ]; then
  197. lib_paths="$(echo "${unit_paths}" | grep -vE '^/(run|etc)' | awk '{line[NR] = $0} END {for (i = NR; i > 0; i--) print line[i]}')"
  198. etc_paths="$(echo "${unit_paths}" | grep -E '^/etc' | grep -vE '(attached|control)$')"
  199. else
  200. lib_paths="/usr/lib/systemd/system /lib/systemd/system /usr/local/lib/systemd/system"
  201. etc_paths="/etc/systemd/system"
  202. fi
  203. for path in ${lib_paths} ${etc_paths}; do
  204. if [ -d "${path}" ] && [ -w "${path}" ]; then
  205. echo "${path}"
  206. return 0
  207. fi
  208. done
  209. error "Unable to detect usable systemd service directory."
  210. exit 4
  211. }
  212. install_systemd_service() {
  213. SRCFILE="${SVC_SOURCE}/systemd/netdata.service"
  214. PRESET_FILE="${SVC_SOURCE}/systemd/50-netdata.preset"
  215. SVCDIR="$(get_systemd_service_dir)"
  216. if [ "$(systemctl --version | head -n 1 | cut -f 2 -d ' ')" -le 235 ]; then
  217. SRCFILE="${SVC_SOURCE}/systemd/netdata.service.v235"
  218. fi
  219. if [ "${ENABLE}" = "auto" ]; then
  220. if [ "$(check_systemd)" = "YES" ]; then
  221. IS_NETDATA_ENABLED="$(systemctl is-enabled netdata 2> /dev/null || echo "Netdata not there")"
  222. fi
  223. if [ "${IS_NETDATA_ENABLED}" = "disabled" ]; then
  224. ENABLE="disable"
  225. else
  226. ENABLE="enable"
  227. fi
  228. fi
  229. info "Installing systemd service..."
  230. if ! install -p -m 0644 -o 0 -g 0 "${SRCFILE}" "${SVCDIR}/netdata.service"; then
  231. error "Failed to install systemd service file."
  232. exit 4
  233. fi
  234. if [ -f "${PRESET_FILE}" ]; then
  235. if ! install -p -m 0644 -o 0 -g 0 "${PRESET_FILE}" "${SVCDIR}-preset/50-netdata.preset"; then
  236. warning "Failed to install netdata preset file."
  237. fi
  238. fi
  239. if [ "$(check_systemd)" = "YES" ]; then
  240. if ! systemctl daemon-reload; then
  241. warning "Failed to reload systemd unit files."
  242. fi
  243. if ! systemctl "${ENABLE}" netdata; then
  244. warning "Failed to ${ENABLE} Netdata service."
  245. fi
  246. fi
  247. }
  248. systemd_cmds() {
  249. if [ "$(check_systemd)" = "YES" ]; then
  250. NETDATA_START_CMD='systemctl start netdata'
  251. NETDATA_STOP_CMD='systemctl stop netdata'
  252. else # systemd is not running, use external defaults by providing no commands
  253. warning "Detected systemd, but not booted using systemd. Unable to provide commands to start or stop Netdata using the service manager."
  254. fi
  255. }
  256. # =====================================================================
  257. # OpenRC support functions
  258. _check_openrc() {
  259. # if /lib/rc/sh/functions.sh does not exist, it's not OpenRC
  260. [ ! -f /lib/rc/sh/functions.sh ] && echo "NO" && return 0
  261. # if there is no /etc/init.d, it's not OpenRC
  262. [ ! -d /etc/init.d ] && echo "NO" && return 0
  263. # if there is no /etc/conf.d, it's not OpenRC
  264. [ ! -d /etc/conf.d ] && echo "NO" && return 0
  265. # if there is no rc-update command, it's not OpenRC
  266. [ -z "$(command -v rc-update 2>/dev/null || true)" ] && echo "NO" && return 0
  267. # If /run/openrc/softlevel exists, it's OpenRC
  268. [ -f /run/openrc/softlevel ] && echo "YES" && return 0
  269. # if PID 1 is openrc-init, it's OpenRC
  270. [ "$(basename "$(readlink /proc/1/exe)" 2> /dev/null)" = "openrc-init" ] && echo "YES" && return 0
  271. # if there is an openrc command, it's OpenRC, but not booted as such
  272. [ -n "$(command -v openrc 2>/dev/null || true)" ] && echo "OFFLINE" && return 0
  273. # if /etc/init.d/local exists and has `openrc-run` in it's shebang line, it’s OpenRC, but not booted as such
  274. [ -r /etc/init.d/local ] && head -n 1 /etc/init.d/local | grep -q openrc-run && echo "OFFLINE" && return 0
  275. # Otherwise, it’s not OpenRC
  276. echo "NO" && return 0
  277. }
  278. check_openrc() {
  279. if [ -z "${IS_OPENRC}" ]; then
  280. IS_OPENRC="$(_check_openrc)"
  281. fi
  282. echo "${IS_OPENRC}"
  283. }
  284. enable_openrc() {
  285. if [ "$(check_openrc)" = "YES" ]; then
  286. runlevel="$(rc-status -r)"
  287. fi
  288. runlevel="${runlevel:-default}"
  289. if ! rc-update add netdata "${runlevel}"; then
  290. warning "Failed to enable Netdata service in runlevel ${runlevel}."
  291. fi
  292. }
  293. disable_openrc() {
  294. for runlevel in /etc/runlevels/*; do
  295. if [ -e "${runlevel}/netdata" ]; then
  296. runlevel="$(basename "${runlevel}")"
  297. if ! rc-update del netdata "${runlevel}"; then
  298. warning "Failed to disable Netdata service in runlevel ${runlevel}."
  299. fi
  300. fi
  301. done
  302. }
  303. install_openrc_service() {
  304. install_generic_service openrc/init.d OpenRC /etc/init.d/netdata enable_openrc disable_openrc
  305. if [ ! -f /etc/conf.d/netdata ]; then
  306. info "Installing OpenRC configuration file."
  307. if ! install -p -m 0755 -o 0 -g 0 "${SVC_SOURCE}/openrc/conf.d/netdata" "/etc/conf.d/netdata"; then
  308. warning "Failed to install configuration file, however the service will still work."
  309. fi
  310. fi
  311. }
  312. openrc_cmds() {
  313. if [ "$(check_openrc)" = "YES" ]; then
  314. NETDATA_START_CMD='rc-service netdata start'
  315. NETDATA_STOP_CMD='rc-service netdata stop'
  316. else # Not booted using OpenRC, use external defaults by not providing commands.
  317. warning "Detected OpenRC, but the system is not booted using OpenRC. Unable to provide commands to start or stop Netdata using the service manager."
  318. fi
  319. }
  320. # =====================================================================
  321. # LSB init script support functions
  322. _check_lsb_ignore_systemd() {
  323. # if there is no /etc/init.d directory, it’s not an LSB system
  324. [ ! -d /etc/init.d ] && echo "NO" && return 0
  325. # If it's an OpenRC system, then it's not an LSB system
  326. [ "$(check_openrc)" != "NO" ] && echo "NO" && return 0
  327. # If /lib/lsb/init-functions exists, it’s an LSB system
  328. [ -f /lib/lsb/init-functions ] && echo "YES" && return 0
  329. echo "NO" && return 0
  330. }
  331. _check_lsb() {
  332. # if there is _any_ systemd, it’s not an LSB system
  333. [ "$(check_systemd)" != "NO" ] && echo "NO" && return 0
  334. _check_lsb_ignore_systemd
  335. }
  336. check_lsb() {
  337. if [ -z "${IS_LSB}" ]; then
  338. IS_LSB="$(_check_lsb)"
  339. fi
  340. echo "${IS_LSB}"
  341. }
  342. enable_lsb() {
  343. if ! update-rc.d netdata defaults; then
  344. warning "Failed to enable Netdata service."
  345. elif ! update-rc.d netdata defaults-disabled; then
  346. warning "Failed to fully enable Netdata service."
  347. fi
  348. }
  349. disable_lsb() {
  350. if ! update-rc.d netdata remove; then
  351. warning "Failed to disable Netdata service."
  352. fi
  353. }
  354. install_lsb_service() {
  355. install_generic_service lsb/init.d LSB /etc/init.d/netdata enable_lsb disable_lsb
  356. }
  357. lsb_cmds() {
  358. NETDATA_START_CMD='/etc/init.d/netdata start'
  359. NETDATA_STOP_CMD='/etc/init.d/netdata stop'
  360. }
  361. # =====================================================================
  362. # init.d init script support functions
  363. _check_initd_ignore_systemd() {
  364. # if there is no /etc/init.d directory, it’s not an init.d system
  365. [ ! -d /etc/init.d ] && echo "NO" && return 1
  366. # if there is no chkconfig command, it's not a (usable) init.d system
  367. [ -z "$(command -v chkconfig 2>/dev/null || true)" ] && echo "NO" && return 0
  368. # if there is _any_ openrc, it’s not init.d
  369. [ "$(check_openrc)" != "NO" ] && echo "NO" && return 0
  370. # if it's not an LSB setup, it’s init.d
  371. [ "$(check_lsb)" != "NO" ] && echo "NO" && return 0
  372. echo "YES" && return 0
  373. }
  374. _check_initd() {
  375. # if there is _any_ systemd, it’s not init.d
  376. [ "$(check_systemd)" != "NO" ] && echo "NO" && return 0
  377. _check_initd_ignore_systemd
  378. }
  379. check_initd() {
  380. if [ -z "${IS_INITD}" ]; then
  381. IS_INITD="$(_check_initd)"
  382. fi
  383. echo "${IS_INITD}"
  384. }
  385. enable_initd() {
  386. if ! chkconfig netdata on; then
  387. warning "Failed to enable Netdata service."
  388. fi
  389. }
  390. disable_initd() {
  391. if ! chkconfig netdata off; then
  392. warning "Failed to disable Netdata service."
  393. fi
  394. }
  395. install_initd_service() {
  396. install_generic_service initd/init.d init.d /etc/init.d/netdata enable_initd disable_initd
  397. }
  398. initd_cmds() {
  399. NETDATA_START_CMD='/etc/init.d/netdata start'
  400. NETDATA_STOP_CMD='/etc/init.d/netdata stop'
  401. }
  402. # =====================================================================
  403. # runit support functions
  404. _check_runit() {
  405. # if there is no runsvdir command, then it's not runit
  406. [ -z "$(command -v runsvdir 2>/dev/null || true)" ] && echo "NO" && return 0
  407. # if there is no runit command, then it's not runit
  408. [ -z "$(command -v runit 2>/dev/null || true)" ] && echo "NO" && return 0
  409. # if /run/runit exists, then it's runit
  410. [ -d /run/runit ] && echo "YES" && return 0
  411. # if /etc/runit/1 exists and is executable, then it's runit
  412. [ -x /etc/runit/1 ] && echo "YES" && return 0
  413. echo "NO" && return 0
  414. }
  415. check_runit() {
  416. if [ -z "${IS_RUNIT}" ]; then
  417. IS_RUNIT="$(_check_runit)"
  418. fi
  419. echo "${IS_RUNIT}"
  420. }
  421. install_runit_service() {
  422. if [ -d /etc/sv ]; then
  423. svc_dir="/etc/sv/netdata"
  424. elif [ -d /etc/runit/sv ]; then
  425. svc_dir="/etc/runit/sv/netdata"
  426. else
  427. error "Failed to locate service directory"
  428. exit 4
  429. fi
  430. if [ -d /service ]; then
  431. live_svc_dir="/service"
  432. elif [ -d /var/service ]; then
  433. live_svc_dir="/var/service"
  434. elif [ -d /run/runit/service ]; then
  435. live_svc_dir="/run/runit/service"
  436. elif [ -d /etc/runit/runsvdir/default ]; then
  437. live_svc_dir="/etc/runit/runsvdir/default"
  438. else
  439. error "Failed to locate live service directory"
  440. exit 4
  441. fi
  442. svc_file="${svc_dir}/run"
  443. info "Installing runit service file."
  444. if [ ! -f "${svc_file}" ] && [ "${ENABLE}" = "auto" ]; then
  445. ENABLE="enable"
  446. fi
  447. if ! install -D -p -m 0755 -o 0 -g 0 "${SVC_SOURCE}/runit/run" "${svc_file}"; then
  448. error "Failed to install service file."
  449. exit 4
  450. fi
  451. case ${ENABLE} in
  452. enable)
  453. if ! ln -s "${svc_dir}" "${live_svc_dir}"; then
  454. warning "Failed to enable the Netdata service."
  455. fi
  456. ;;
  457. disable)
  458. if ! rm "${live_svc_dir}/netdata"; then
  459. warning "Failed to disable the Netdata service."
  460. fi
  461. ;;
  462. esac
  463. }
  464. runit_cmds() {
  465. NETDATA_START_CMD="sv start netdata"
  466. NETDATA_STOP_CMD="sv stop netdata"
  467. }
  468. # =====================================================================
  469. # dinit support functions
  470. _check_dinit() {
  471. # if /etc/dinit.d does not exist, it’s not dinit
  472. [ ! -d /etc/dinit.d ] && echo "NO" && return 0
  473. # if PID 1 is dinit, it’s dinit
  474. [ "$(basename "$(readlink /proc/1/exe)" 2> /dev/null)" = "dinit" ] && echo "YES" && return 0
  475. # if /run/dinitctl exists and is a socket, it’s dinit
  476. [ -S /run/dinitctl ] && echo "YES" && return 0
  477. # if the dinitctl command exists despite getting to this point, it’s dinit, but not booted as such
  478. [ -n "$(command -v dinitctl 2>/dev/null || true)" ] && echo "OFFLINE" && return 0
  479. echo "NO" && return 0
  480. }
  481. check_dinit() {
  482. if [ -z "${IS_DINIT}" ]; then
  483. IS_DINIT="$(_check_dinit)"
  484. fi
  485. echo "${IS_DINIT}"
  486. }
  487. _run_dinitctl() {
  488. opts=''
  489. if [ "$(check_dinit)" = "OFFLINE" ]; then
  490. opts="-o"
  491. fi
  492. # shellcheck disable=SC2086
  493. dinitctl ${opts} "${@}"
  494. }
  495. enable_dinit() {
  496. _run_dinitctl enable netdata
  497. }
  498. enable_dinit() {
  499. _run_dinitctl disable netdata
  500. }
  501. install_dinit_service() {
  502. install_generic_service dinit/netdata "dinit" /etc/dinit.d enable_dinit disable_dinit
  503. }
  504. dinit_cmds() {
  505. if [ "$(check_dinit)" = "YES" ]; then
  506. NETDATA_START_CMD='dinitctl start netdata'
  507. NETDATA_STOP_CMD='dinitct stop netdata'
  508. else # Not booted using dinit, use external defaults by not providing commands.
  509. warning "Detected dinit, but the system is not booted using dinit. Unable to provide commands to start or stop Netdata using the service manager."
  510. fi
  511. }
  512. # =====================================================================
  513. # WSL support functions
  514. _check_wsl() {
  515. # If uname -r contains the string WSL, then it's WSL.
  516. uname -r | grep -q 'WSL' && echo "YES" && return 0
  517. # If uname -r contains the string Microsoft, then it's WSL.
  518. # This probably throws a false positive on CBL-Mariner, but it's part of what MS officially recommends for
  519. # detecting if you're running under WSL.
  520. uname -r | grep -q "Microsoft" && echo "YES" && return 0
  521. echo "NO" && return 0
  522. }
  523. check_wsl() {
  524. if [ -z "${IS_WSL}" ]; then
  525. IS_WSL="$(_check_wsl)"
  526. fi
  527. echo "${IS_WSL}"
  528. }
  529. install_wsl_service() {
  530. error "${WSL_ERROR_MSG}"
  531. exit 3
  532. }
  533. wsl_cmds() {
  534. error "${WSL_ERROR_MSG}"
  535. exit 3
  536. }
  537. # =====================================================================
  538. # FreeBSD support functions
  539. enable_freebsd() {
  540. if ! sysrc netdata_enable=YES; then
  541. warning "Failed to enable netdata service."
  542. fi
  543. }
  544. disable_freebsd() {
  545. if ! sysrc netdata_enable=NO; then
  546. warning "Failed to disable netdata service."
  547. fi
  548. }
  549. install_freebsd_service() {
  550. install_generic_service freebsd/rc.d "FreeBSD rc.d" /usr/local/etc/rc.d/netdata enable_freebsd disable_freebsd
  551. }
  552. freebsd_cmds() {
  553. NETDATA_START_CMD='service netdata start'
  554. NETDATA_STOP_CMD='service netdata stop'
  555. NETDATA_INSTALLER_START_CMD='service netdata onestart'
  556. }
  557. # =====================================================================
  558. # macOS support functions
  559. install_darwin_service() {
  560. info "Installing macOS plist file for launchd."
  561. if ! install -C -S -p -m 0644 -o 0 -g 0 "${SVC_SOURCE}/launchd/netdata.plist" /Library/LaunchDaemons/com.github.netdata.plist; then
  562. error "Failed to copy plist file."
  563. exit 4
  564. fi
  565. launchctl unload /Library/LaunchDaemons/com.github.netdata.plist 2>/dev/null
  566. if ! launchctl load /Library/LaunchDaemons/com.github.netdata.plist; then
  567. error "Failed to load plist file."
  568. exit 4
  569. fi
  570. }
  571. darwin_cmds() {
  572. NETDATA_START_CMD='launchctl start com.github.netdata'
  573. NETDATA_STOP_CMD='launchctl stop com.github.netdata'
  574. }
  575. # =====================================================================
  576. # Linux support functions
  577. detect_linux_svc_type() {
  578. if [ "${SVC_TYPE}" = "detect" ]; then
  579. found_types=''
  580. for t in wsl ${LINUX_INIT_TYPES}; do
  581. case "$("check_${t}")" in
  582. YES)
  583. SVC_TYPE="${t}"
  584. break
  585. ;;
  586. NO) continue ;;
  587. OFFLINE)
  588. if [ -z "${found_types}" ]; then
  589. found_types="${t}"
  590. else
  591. found_types="${found_types} ${t}"
  592. fi
  593. ;;
  594. esac
  595. done
  596. if [ "${SVC_TYPE}" = "detect" ]; then
  597. if [ -z "${found_types}" ]; then
  598. error "Failed to detect what type of service manager is in use."
  599. else
  600. SVC_TYPE="$(echo "${found_types}" | cut -f 1 -d ' ')"
  601. warning "Failed to detect a running service manager, using detected (but not running) ${SVC_TYPE}."
  602. fi
  603. elif [ "${SVC_TYPE}" = "wsl" ]; then
  604. if [ "$(check_systemd)" = "YES" ]; then
  605. # Support for systemd in WSL.
  606. SVC_TYPE="systemd"
  607. elif [ "$(_check_lsb_ignore_systemd)" = "YES" ]; then
  608. # Support for LSB init.d in WSL.
  609. SVC_TYPE="lsb"
  610. elif [ "$(_check_initd_ignore_systemd)" = "YES" ]; then
  611. # Support for ‘generic’ init.d in WSL.
  612. SVC_TYPE="initd"
  613. fi
  614. fi
  615. fi
  616. echo "${SVC_TYPE}"
  617. }
  618. install_linux_service() {
  619. t="$(detect_linux_svc_type)"
  620. if [ -z "${t}" ] || [ "${t}" = 'detect' ]; then
  621. exit 2
  622. fi
  623. "install_${t}_service"
  624. }
  625. linux_cmds() {
  626. t="$(detect_linux_svc_type)"
  627. if [ -z "${t}" ] || [ "${t}" = 'detect' ]; then
  628. exit 2
  629. fi
  630. "${t}_cmds"
  631. }
  632. # =====================================================================
  633. # Service type display function
  634. show_service_type() {
  635. info "Detected platform: ${PLATFORM}"
  636. case "${PLATFORM}" in
  637. FreeBSD)
  638. info "Detected service managers:"
  639. info " - freebsd: YES"
  640. info "Would use freebsd service management."
  641. ;;
  642. Darwin)
  643. info "Detected service managers:"
  644. info " - launchd: YES"
  645. info "Would use launchd service management."
  646. ;;
  647. Linux)
  648. [ "$(check_wsl)" = "YES" ] && info "Detected WSL environment."
  649. info "Detected service managers:"
  650. for t in ${LINUX_INIT_TYPES}; do
  651. info " - ${t}: $("check_${t}")"
  652. done
  653. info "Would use $(detect_linux_svc_type) service management."
  654. ;;
  655. *)
  656. info "${PLATFORM} is not supported by this script. No service file would be installed."
  657. esac
  658. exit 0
  659. }
  660. # =====================================================================
  661. # Argument handling
  662. parse_args() {
  663. while [ -n "${1}" ]; do
  664. case "${1}" in
  665. "--source" | "-s")
  666. SVC_SOURCE="${2}"
  667. shift 1
  668. ;;
  669. "--type" | "-t")
  670. if [ "${2}" = "help" ]; then
  671. help_types
  672. exit 0
  673. else
  674. SVC_TYPE="${2}"
  675. shift 1
  676. fi
  677. ;;
  678. "--show-type") SHOW_SVC_TYPE=1 ; INSTALL=0 ;;
  679. "--save-cmds")
  680. if [ -z "${2}" ]; then
  681. info "No path specified to save command variables."
  682. exit 1
  683. else
  684. SAVE_CMDS_PATH="${2}"
  685. shift 1
  686. fi
  687. ;;
  688. "--cmds" | "-c") DUMP_CMDS=1 ;;
  689. "--cmds-only") INSTALL=0 ;;
  690. "--export-cmds") EXPORT_CMDS=1 ;;
  691. "--enable" | "-e") ENABLE="enable" ;;
  692. "--disable" | "-d") ENABLE="disable" ;;
  693. "--help" | "-h")
  694. usage
  695. exit 0
  696. ;;
  697. *)
  698. info "Unrecognized option '${1}'."
  699. exit 1
  700. ;;
  701. esac
  702. shift 1
  703. done
  704. if [ "${SVC_SOURCE#@}" = "libsysdir_POST@" ]; then
  705. SVC_SOURCE="$(dirname "${SCRIPT_SOURCE}")/../../lib/netdata/system"
  706. warning "SVC_SOURCE not templated, using ${SVC_SOURCE} as source directory."
  707. fi
  708. if [ ! -d "${SVC_SOURCE}" ] && [ "${INSTALL}" -eq 1 ]; then
  709. error "${SVC_SOURCE} does not appear to be a directory. Please specify a valid source for service files with the --source option."
  710. exit 1
  711. fi
  712. if valid_types | grep -vw "${SVC_TYPE}"; then
  713. error "${SVC_TYPE} is not supported on this platform."
  714. help_types
  715. exit 1
  716. fi
  717. }
  718. # =====================================================================
  719. # Core logic
  720. main() {
  721. trap "cleanup" EXIT
  722. parse_args "${@}"
  723. if [ "${SHOW_SVC_TYPE}" -eq 1 ]; then
  724. show_service_type
  725. else
  726. case "${PLATFORM}" in
  727. FreeBSD)
  728. [ "${INSTALL}" -eq 1 ] && install_freebsd_service
  729. freebsd_cmds
  730. ;;
  731. Darwin)
  732. [ "${INSTALL}" -eq 1 ] && install_darwin_service
  733. darwin_cmds
  734. ;;
  735. Linux)
  736. [ "${INSTALL}" -eq 1 ] && install_linux_service
  737. linux_cmds
  738. ;;
  739. *)
  740. error "${PLATFORM} is not supported by this script."
  741. exit 5
  742. ;;
  743. esac
  744. [ "${DUMP_CMDS}" -eq 1 ] && dump_cmds
  745. [ "${EXPORT_CMDS}" -eq 1 ] && export_cmds
  746. [ -n "${SAVE_CMDS_PATH}" ] && save_cmds
  747. fi
  748. exit 0
  749. }
  750. main "${@}"