@cryptotaxi247 / netdata-1 / commits / d1eafad8b

Attempt to use system service manager to shut down Netdata. (#7814)

* Shellcheck cleanups for netdata-uninstaller.sh * Shellcheck cleanups for packaging/installer/functions.sh * Attempt to use service managers for shutdown. This attempts to use whatever the system service management interface is to shutdown Netdata before trying anything more drastic. * Properly continue if shutdown via service manager fails. * Fix typos. * Re-add TPUT definitions. As requested by @knatsakis and @prologic. * Reduce the wait time after attempting shutdown with service managers.

Austin S. Hemmelgarn committed Jan 24, 2020 at 08:16 UTC d1eafad8b02fdef2f4ddcbfa6c35ec5594b248b3
2 files changed +188 -57
packaging/installer/functions.sh
+84 -38
@@ -1,7 +1,6 @@
1 #!/bin/bash
2
3 # SPDX-License-Identifier: GPL-3.0-or-later
4 -# shellcheck disable=SC1091,SC1117,SC2002,SC2004,SC2034,SC2046,SC2059,SC2086,SC2129,SC2148,SC2154,SC2155,SC2162,SC2166,SC2181,SC2193
4
5 # make sure we have a UID
6 [ -z "${UID}" ] && UID="$(id -u)"
@@ -42,29 +41,45 @@ setup_terminal() {
41 if [ $(($(tput colors 2>/dev/null))) -ge 8 ]; then
42 # Enable colors
43 TPUT_RESET="$(tput sgr 0)"
44 + # shellcheck disable=SC2034
45 TPUT_BLACK="$(tput setaf 0)"
46 TPUT_RED="$(tput setaf 1)"
47 TPUT_GREEN="$(tput setaf 2)"
48 + # shellcheck disable=SC2034
49 TPUT_YELLOW="$(tput setaf 3)"
50 + # shellcheck disable=SC2034
51 TPUT_BLUE="$(tput setaf 4)"
52 + # shellcheck disable=SC2034
53 TPUT_PURPLE="$(tput setaf 5)"
54 TPUT_CYAN="$(tput setaf 6)"
55 TPUT_WHITE="$(tput setaf 7)"
56 + # shellcheck disable=SC2034
57 TPUT_BGBLACK="$(tput setab 0)"
58 TPUT_BGRED="$(tput setab 1)"
59 TPUT_BGGREEN="$(tput setab 2)"
60 + # shellcheck disable=SC2034
61 TPUT_BGYELLOW="$(tput setab 3)"
62 + # shellcheck disable=SC2034
63 TPUT_BGBLUE="$(tput setab 4)"
64 + # shellcheck disable=SC2034
65 TPUT_BGPURPLE="$(tput setab 5)"
66 + # shellcheck disable=SC2034
67 TPUT_BGCYAN="$(tput setab 6)"
68 + # shellcheck disable=SC2034
69 TPUT_BGWHITE="$(tput setab 7)"
70 TPUT_BOLD="$(tput bold)"
71 TPUT_DIM="$(tput dim)"
72 + # shellcheck disable=SC2034
73 TPUT_UNDERLINED="$(tput smul)"
74 + # shellcheck disable=SC2034
75 TPUT_BLINK="$(tput blink)"
76 + # shellcheck disable=SC2034
77 TPUT_INVERTED="$(tput rev)"
78 + # shellcheck disable=SC2034
79 TPUT_STANDOUT="$(tput smso)"
80 + # shellcheck disable=SC2034
81 TPUT_BELL="$(tput bel)"
82 + # shellcheck disable=SC2034
83 TPUT_CLEAR="$(tput clear)"
84 fi
85 fi
@@ -129,7 +144,8 @@ service() {
144 # portable pidof
145
146 safe_pidof() {
132 - local pidof_cmd="$(command -v pidof 2>/dev/null)"
147 + local pidof_cmd
148 + pidof_cmd="$(command -v pidof 2>/dev/null)"
149 if [ -n "${pidof_cmd}" ]; then
150 ${pidof_cmd} "${@}"
151 return $?
@@ -161,21 +177,22 @@ find_processors() {
177
178 # -----------------------------------------------------------------------------
179 fatal() {
164 - printf >&2 "${TPUT_BGRED}${TPUT_WHITE}${TPUT_BOLD} ABORTED ${TPUT_RESET} ${*} \n\n"
180 + printf >&2 "%s ABORTED %s %s \n\n" "${TPUT_BGRED}${TPUT_WHITE}${TPUT_BOLD}" "${TPUT_RESET}" "${*}"
181 exit 1
182 }
183
184 run_ok() {
169 - printf >&2 "${TPUT_BGGREEN}${TPUT_WHITE}${TPUT_BOLD} OK ${TPUT_RESET} ${*} \n\n"
185 + printf >&2 "%s OK %s %s \n\n" "${TPUT_BGGREEN}${TPUT_WHITE}${TPUT_BOLD}" "${TPUT_RESET}" "${*}"
186 }
187
188 run_failed() {
173 - printf >&2 "${TPUT_BGRED}${TPUT_WHITE}${TPUT_BOLD} FAILED ${TPUT_RESET} ${*} \n\n"
189 + printf >&2 "%s FAILED %s %s \n\n" "${TPUT_BGRED}${TPUT_WHITE}${TPUT_BOLD}" "${TPUT_RESET}" "${*}"
190 }
191
192 ESCAPED_PRINT_METHOD=
177 -printf "%q " test >/dev/null 2>&1
178 -[ $? -eq 0 ] && ESCAPED_PRINT_METHOD="printfq"
193 +if printf "%q " test >/dev/null 2>&1; then
194 + ESCAPED_PRINT_METHOD="printfq"
195 +fi
196 escaped_print() {
197 if [ "${ESCAPED_PRINT_METHOD}" = "printfq" ]; then
198 printf "%q " "${@}"
@@ -197,20 +214,22 @@ run() {
214 info_console="[${TPUT_DIM}${dir}${TPUT_RESET}]$ "
215 fi
216
200 - printf >>"${run_logfile}" "${info}"
201 - escaped_print >>"${run_logfile}" "${@}"
202 - printf >>"${run_logfile}" " ... "
217 + {
218 + printf "%s" "${info}"
219 + escaped_print "${@}"
220 + printf "%s" " ... "
221 + } >> "${run_logfile}"
222
204 - printf >&2 "${info_console}${TPUT_BOLD}${TPUT_YELLOW}"
223 + printf >&2 "%s" "${info_console}${TPUT_BOLD}${TPUT_YELLOW}"
224 escaped_print >&2 "${@}"
206 - printf >&2 "${TPUT_RESET}\n"
225 + printf >&2 "%s" "${TPUT_RESET}\n"
226
227 "${@}"
228
229 local ret=$?
230 if [ ${ret} -ne 0 ]; then
231 run_failed
213 - printf >>"${run_logfile}" "FAILED with exit code ${ret}\n"
232 + printf >>"${run_logfile}" "FAILED with exit code %s\n" "${ret}"
233 else
234 run_ok
235 printf >>"${run_logfile}" "OK\n"
@@ -221,15 +240,18 @@ run() {
240
241 iscontainer() {
242 # man systemd-detect-virt
224 - local cmd=$(command -v systemd-detect-virt 2>/dev/null)
243 + local cmd
244 + cmd=$(command -v systemd-detect-virt 2>/dev/null)
245 if [ -n "${cmd}" ] && [ -x "${cmd}" ]; then
246 "${cmd}" --container >/dev/null 2>&1 && return 0
247 fi
248
249 # /proc/1/sched exposes the host's pid of our init !
250 # http://stackoverflow.com/a/37016302
231 - local pid=$(cat /proc/1/sched 2>/dev/null | head -n 1 | {
232 - IFS='(),#:' read name pid th threads
251 + local pid
252 + pid=$(head -n 1 /proc/1/sched 2>/dev/null | {
253 + # shellcheck disable=SC2034
254 + IFS='(),#:' read -r name pid th threads
255 echo "$pid"
256 })
257 if [ -n "${pid}" ]; then
@@ -238,6 +260,7 @@ iscontainer() {
260 fi
261
262 # lxc sets environment variable 'container'
263 + # shellcheck disable=SC2154
264 [ -n "${container}" ] && return 0
265
266 # docker creates /.dockerenv
@@ -257,15 +280,18 @@ issystemd() {
280 local pids p myns ns systemctl
281
282 # if the directory /lib/systemd/system OR /usr/lib/systemd/system (SLES 12.x) does not exit, it is not systemd
260 - [ ! -d /lib/systemd/system -a ! -d /usr/lib/systemd/system ] && return 1
283 + if [ ! -d /lib/systemd/system ] && [ ! -d /usr/lib/systemd/system ] ; then
284 + return 1
285 + fi
286
287 # if there is no systemctl command, it is not systemd
263 - # shellcheck disable=SC2230
288 systemctl=$(command -v systemctl 2>/dev/null)
265 - [ -z "${systemctl}" -o ! -x "${systemctl}" ] && return 1
289 + if [ -z "${systemctl}" ] || [ ! -x "${systemctl}" ] ; then
290 + return 1
291 + fi
292
293 # if pid 1 is systemd, it is systemd
268 - [ "$(basename $(readlink /proc/1/exe) 2>/dev/null)" = "systemd" ] && return 0
294 + [ "$(basename "$(readlink /proc/1/exe)" 2>/dev/null)" = "systemd" ] && return 0
295
296 # if systemd is not running, it is not systemd
297 pids=$(safe_pidof systemd 2>/dev/null)
@@ -289,6 +315,7 @@ install_non_systemd_init() {
315
316 local key="unknown"
317 if [ -f /etc/os-release ]; then
318 + # shellcheck disable=SC1091
319 source /etc/os-release || return 1
320 key="${ID}-${VERSION_ID}"
321
@@ -332,12 +359,11 @@ install_non_systemd_init() {
359 }
360
361 NETDATA_START_CMD="netdata"
335 -NETDATA_STOP_CMD="killall netdata"
362 NETDATA_INSTALLER_START_CMD=""
337 -NETDATA_INSTALLER_STOP_CMD="${NETDATA_STOP_CMD}"
363
364 install_netdata_service() {
340 - local uname="$(uname 2>/dev/null)"
365 + local uname
366 + uname="$(uname 2>/dev/null)"
367
368 if [ "${UID}" -eq 0 ]; then
369 if [ "${uname}" = "Darwin" ]; then
@@ -355,9 +381,7 @@ install_netdata_service() {
381 elif [ "${uname}" = "FreeBSD" ]; then
382
383 run cp system/netdata-freebsd /etc/rc.d/netdata && NETDATA_START_CMD="service netdata start" &&
358 - NETDATA_STOP_CMD="service netdata stop" &&
384 NETDATA_INSTALLER_START_CMD="service netdata onestart" &&
360 - NETDATA_INSTALLER_STOP_CMD="${NETDATA_STOP_CMD}"
385 myret=$?
386
387 echo >&2 "Note: To explicitly enable netdata automatic start, set 'netdata_enable' to 'YES' in /etc/rc.conf"
@@ -368,9 +392,7 @@ install_netdata_service() {
392 elif issystemd; then
393 # systemd is running on this system
394 NETDATA_START_CMD="systemctl start netdata"
371 - NETDATA_STOP_CMD="systemctl stop netdata"
395 NETDATA_INSTALLER_START_CMD="${NETDATA_START_CMD}"
373 - NETDATA_INSTALLER_STOP_CMD="${NETDATA_STOP_CMD}"
396
397 SYSTEMD_DIRECTORY=""
398
@@ -379,7 +401,7 @@ install_netdata_service() {
401 elif [ -w "/usr/lib/systemd/system" ]; then
402 SYSTEMD_DIRECTORY="/usr/lib/systemd/system"
403 elif [ -w "/etc/systemd/system" ]; then
382 - SYSTEM_DIRECTORY="/etc/systemd/system"
404 + SYSTEMD_DIRECTORY="/etc/systemd/system"
405 fi
406
407 if [ "${SYSTEMD_DIRECTORY}x" != "x" ]; then
@@ -405,13 +427,10 @@ install_netdata_service() {
427 if [ ${ret} -eq 0 ]; then
428 if [ -n "${service_cmd}" ]; then
429 NETDATA_START_CMD="service netdata start"
408 - NETDATA_STOP_CMD="service netdata stop"
430 elif [ -n "${rcservice_cmd}" ]; then
431 NETDATA_START_CMD="rc-service netdata start"
411 - NETDATA_STOP_CMD="rc-service netdata stop"
432 fi
433 NETDATA_INSTALLER_START_CMD="${NETDATA_START_CMD}"
414 - NETDATA_INSTALLER_STOP_CMD="${NETDATA_STOP_CMD}"
434 fi
435
436 return ${ret}
@@ -426,7 +445,9 @@ install_netdata_service() {
445
446 pidisnetdata() {
447 if [ -d /proc/self ]; then
429 - [ -z "$1" -o ! -f "/proc/$1/stat" ] && return 1
448 + if [ -z "$1" ] || [ ! -f "/proc/$1/stat" ] ; then
449 + return 1
450 + fi
451 [ "$(cut -d '(' -f 2 "/proc/$1/stat" | cut -d ')' -f 1)" = "netdata" ] && return 0
452 return 1
453 fi
@@ -492,9 +513,32 @@ netdata_pids() {
513 }
514
515 stop_all_netdata() {
495 - local p
516 + local p uname
517 +
518 + if [ "${UID}" -eq 0 ] ; then
519 + uname="$(uname 2>/dev/null)"
520
497 - if [ -n "$(netdata_pids)" -a -n "$(builtin type -P netdatacli)" ]; then
521 + # Any of these may fail, but we need to not bail if they do.
522 + if issystemd; then
523 + if systemctl stop netdata ; then
524 + sleep 5
525 + fi
526 + elif [ "${uname}" = "Darwin" ]; then
527 + if launchctl stop netdata ; then
528 + sleep 5
529 + fi
530 + elif [ "${uname}" = "FreeBSD" ]; then
531 + if /etc/rc.d/netdata stop ; then
532 + sleep 5
533 + fi
534 + else
535 + if service netdata stop ; then
536 + sleep 5
537 + fi
538 + fi
539 + fi
540 +
541 + if [ -n "$(netdata_pids)" ] || [ -n "$(builtin type -P netdatacli)" ]; then
542 netdatacli shutdown-agent
543 sleep 20
544 fi
@@ -526,6 +570,7 @@ restart_netdata() {
570 run stop_all_netdata
571
572 echo >&2 "Starting netdata using command '${NETDATA_INSTALLER_START_CMD}'"
573 + # shellcheck disable=SC2086
574 run ${NETDATA_INSTALLER_START_CMD} && started=1
575
576 if [ ${started} -eq 1 ] && [ -z "$(netdata_pids)" ]; then
@@ -535,6 +580,7 @@ restart_netdata() {
580
581 if [ ${started} -eq 0 ]; then
582 echo >&2 "Attempting another netdata start using command '${NETDATA_INSTALLER_START_CMD}'"
583 + # shellcheck disable=SC2086
584 run ${NETDATA_INSTALLER_START_CMD} && started=1
585 fi
586 fi
@@ -633,8 +679,8 @@ portable_add_user() {
679
680 echo >&2 "Adding ${username} user account with home ${homedir} ..."
681
636 - # shellcheck disable=SC2230
637 - local nologin="$(command -v nologin || echo '/bin/false')"
682 + local nologin
683 + nologin="$(command -v nologin || echo '/bin/false')"
684
685 # Linux
686 if command -v useradd 1>/dev/null 2>&1; then
@@ -653,7 +699,7 @@ portable_add_user() {
699
700 # mac OS
701 if command -v sysadminctl 1>/dev/null 2>&1; then
656 - run sysadminctl -addUser ${username} && return 0
702 + run sysadminctl -addUser "${username}" && return 0
703 fi
704
705 echo >&2 "Failed to add ${username} user account !"
@@ -784,7 +830,7 @@ install_netdata_updater() {
830
831 sed -i -e "s|THIS_SHOULD_BE_REPLACED_BY_INSTALLER_SCRIPT|${NETDATA_USER_CONFIG_DIR}/.environment|" "${NETDATA_PREFIX}/usr/libexec/netdata/netdata-updater.sh" || return 1
832
787 - chmod 0755 ${NETDATA_PREFIX}/usr/libexec/netdata/netdata-updater.sh
833 + chmod 0755 "${NETDATA_PREFIX}/usr/libexec/netdata/netdata-updater.sh"
834 echo >&2 "Update script is located at ${TPUT_GREEN}${TPUT_BOLD}${NETDATA_PREFIX}/usr/libexec/netdata/netdata-updater.sh${TPUT_RESET}"
835 echo >&2
836
packaging/installer/netdata-uninstaller.sh
+104 -19
@@ -1,5 +1,4 @@
1 #!/usr/bin/env bash
2 -#shellcheck disable=SC2181
2 #
3 # This is the netdata uninstaller script
4 #
@@ -65,6 +64,29 @@ if [[ $EUID -ne 0 ]]; then
64 fi
65 fi
66
67 +# -----------------------------------------------------------------------------
68 +# portable service command
69 +
70 +service_cmd="$(command -v service 2>/dev/null)"
71 +rcservice_cmd="$(command -v rc-service 2>/dev/null)"
72 +systemctl_cmd="$(command -v systemctl 2>/dev/null)"
73 +service() {
74 +
75 + local cmd="${1}" action="${2}"
76 +
77 + if [ -n "${systemctl_cmd}" ]; then
78 + run "${systemctl_cmd}" "${action}" "${cmd}"
79 + return $?
80 + elif [ -n "${service_cmd}" ]; then
81 + run "${service_cmd}" "${cmd}" "${action}"
82 + return $?
83 + elif [ -n "${rcservice_cmd}" ]; then
84 + run "${rcservice_cmd}" "${cmd}" "${action}"
85 + return $?
86 + fi
87 + return 1
88 +}
89 +
90 # -----------------------------------------------------------------------------
91
92 setup_terminal() {
@@ -97,16 +119,17 @@ setup_terminal() {
119 setup_terminal || echo >/dev/null
120
121 run_ok() {
100 - printf >&2 "${TPUT_BGGREEN}${TPUT_WHITE}${TPUT_BOLD} OK ${TPUT_RESET} ${*} \n\n"
122 + printf >&2 "%s OK %s %s \n\n" "${TPUT_BGGREEN}${TPUT_WHITE}${TPUT_BOLD}" "${TPUT_RESET}" "${*}"
123 }
124
125 run_failed() {
104 - printf >&2 "${TPUT_BGRED}${TPUT_WHITE}${TPUT_BOLD} FAILED ${TPUT_RESET} ${*} \n\n"
126 + printf >&2 "%s FAILED %s %s \n\n" "${TPUT_BGRED}${TPUT_WHITE}${TPUT_BOLD}" "${TPUT_RESET}" "${*}"
127 }
128
129 ESCAPED_PRINT_METHOD=
108 -printf "%q " test >/dev/null 2>&1
109 -[ $? -eq 0 ] && ESCAPED_PRINT_METHOD="printfq"
130 +if printf "%q " test >/dev/null 2>&1; then
131 + ESCAPED_PRINT_METHOD="printfq"
132 +fi
133 escaped_print() {
134 if [ "${ESCAPED_PRINT_METHOD}" = "printfq" ]; then
135 printf "%q " "${@}"
@@ -128,22 +151,24 @@ run() {
151 info_console="[${TPUT_DIM}${dir}${TPUT_RESET}]$ "
152 fi
153
131 - printf >>"${run_logfile}" "${info}"
132 - escaped_print >>"${run_logfile}" "${@}"
133 - printf >>"${run_logfile}" " ... "
154 + {
155 + printf "%s" "${info}"
156 + escaped_print "${@}"
157 + printf "%s" " ... "
158 + } >> "${run_logfile}"
159
135 - printf >&2 "${info_console}${TPUT_BOLD}${TPUT_YELLOW}"
160 + printf "%s" >&2 "${info_console}${TPUT_BOLD}${TPUT_YELLOW}"
161 escaped_print >&2 "${@}"
137 - printf >&2 "${TPUT_RESET}\n"
162 + printf "%s" >&2 "${TPUT_RESET}\n"
163
164 "${@}"
165
166 local ret=$?
167 if [ ${ret} -ne 0 ]; then
143 - run_failed
144 - printf >>"${run_logfile}" "FAILED with exit code ${ret}\n"
168 + run_failed "${*}"
169 + printf >>"${run_logfile}" "FAILED with exit code %s\n" "${ret}"
170 else
146 - run_ok
171 + run_ok "${*}"
172 printf >>"${run_logfile}" "OK\n"
173 fi
174
@@ -159,10 +184,10 @@ portable_del_group() {
184 # Linux
185 if command -v groupdel 1>/dev/null 2>&1; then
186 if grep -q "${groupname}" /etc/group; then
162 - run groupdel "${groupname}" && return 0
187 + run groupdel "${groupname}" && return 0
188 else
164 - echo >&2 "Group ${groupname} already removed in a previous step."
165 - run_ok
189 + echo >&2 "Group ${groupname} already removed in a previous step."
190 + run_ok "${*}"
191 fi
192 fi
193
@@ -179,6 +204,40 @@ portable_del_group() {
204 return 1
205 }
206
207 +issystemd() {
208 + local pids p myns ns systemctl
209 +
210 + # if the directory /lib/systemd/system OR /usr/lib/systemd/system (SLES 12.x) does not exit, it is not systemd
211 + if [ ! -d /lib/systemd/system ] && [ ! -d /usr/lib/systemd/system ] ; then
212 + return 1
213 + fi
214 +
215 + # if there is no systemctl command, it is not systemd
216 + systemctl=$(command -v systemctl 2>/dev/null)
217 + if [ -z "${systemctl}" ] || [ ! -x "${systemctl}" ] ; then
218 + return 1
219 + fi
220 +
221 + # if pid 1 is systemd, it is systemd
222 + [ "$(basename "$(readlink /proc/1/exe)" 2>/dev/null)" = "systemd" ] && return 0
223 +
224 + # if systemd is not running, it is not systemd
225 + pids=$(safe_pidof systemd 2>/dev/null)
226 + [ -z "${pids}" ] && return 1
227 +
228 + # check if the running systemd processes are not in our namespace
229 + myns="$(readlink /proc/self/ns/pid 2>/dev/null)"
230 + for p in ${pids}; do
231 + ns="$(readlink "/proc/${p}/ns/pid" 2>/dev/null)"
232 +
233 + # if pid of systemd is in our namespace, it is systemd
234 + [ -n "${myns}" ] && [ "${myns}" = "${ns}" ] && return 0
235 + done
236 +
237 + # else, it is not systemd
238 + return 1
239 +}
240 +
241 portable_del_user() {
242 local username="${1}"
243 echo >&2 "Deleting ${username} user account ..."
@@ -259,7 +318,8 @@ rm_dir() {
318 }
319
320 safe_pidof() {
262 - local pidof_cmd="$(command -v pidof 2>/dev/null)"
321 + local pidof_cmd
322 + pidof_cmd="$(command -v pidof 2>/dev/null)"
323 if [ -n "${pidof_cmd}" ]; then
324 ${pidof_cmd} "${@}"
325 return $?
@@ -274,7 +334,9 @@ safe_pidof() {
334
335 pidisnetdata() {
336 if [ -d /proc/self ]; then
277 - [ -z "$1" -o ! -f "/proc/$1/stat" ] && return 1
337 + if [ -z "$1" ] || [ ! -f "/proc/$1/stat" ] ; then
338 + return 1
339 + fi
340 [ "$(cut -d '(' -f 2 "/proc/$1/stat" | cut -d ')' -f 1)" = "netdata" ] && return 0
341 return 1
342 fi
@@ -342,7 +404,30 @@ netdata_pids() {
404 stop_all_netdata() {
405 local p
406
345 - if [ -n "$(netdata_pids)" -a -n "$(builtin type -P netdatacli)" ] ; then
407 + if [ "${UID}" -eq 0 ] ; then
408 + uname="$(uname 2>/dev/null)"
409 +
410 + # Any of these may fail, but we need to not bail if they do.
411 + if issystemd; then
412 + if systemctl stop netdata ; then
413 + sleep 5
414 + fi
415 + elif [ "${uname}" = "Darwin" ]; then
416 + if launchctl stop netdata ; then
417 + sleep 5
418 + fi
419 + elif [ "${uname}" = "FreeBSD" ]; then
420 + if /etc/rc.d/netdata stop ; then
421 + sleep 5
422 + fi
423 + else
424 + if service netdata stop ; then
425 + sleep 5
426 + fi
427 + fi
428 + fi
429 +
430 + if [ -n "$(netdata_pids)" ] && [ -n "$(builtin type -P netdatacli)" ] ; then
431 netdatacli shutdown-agent
432 sleep 20
433 fi