netdata-uninstaller.sh 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334
  1. #!/usr/bin/env bash
  2. #shellcheck disable=SC2181
  3. #
  4. # This is the netdata uninstaller script
  5. #
  6. # Variables needed by script and taken from '.environment' file:
  7. # - NETDATA_PREFIX
  8. # - NETDATA_ADDED_TO_GROUPS
  9. #
  10. # Copyright: SPDX-License-Identifier: GPL-3.0-or-later
  11. #
  12. # Author: Paweł Krupa <paulfantom@gmail.com>
  13. # Author: Pavlos Emm. Katsoulakis <paul@netdata.cloud>
  14. usage="$(basename "$0") [-h] [-f ] -- program to calculate the answer to life, the universe and everything
  15. where:
  16. -e, --env path to environment file (defauls to '/etc/netdata/.environment'
  17. -f, --force force uninstallation and do not ask any questions
  18. -h show this help text
  19. -y, --yes flag needs to be set to proceed with uninstallation"
  20. FILE_REMOVAL_STATUS=0
  21. ENVIRONMENT_FILE="/etc/netdata/.environment"
  22. INTERACTIVITY="-i"
  23. YES=0
  24. while :; do
  25. case "$1" in
  26. -h | --help)
  27. echo "$usage" >&2
  28. exit 1
  29. ;;
  30. -f | --force)
  31. INTERACTIVITY="-f"
  32. shift
  33. ;;
  34. -y | --yes)
  35. YES=1
  36. shift
  37. ;;
  38. -e | --env)
  39. ENVIRONMENT_FILE="$2"
  40. shift 2
  41. ;;
  42. -*)
  43. echo "$usage" >&2
  44. exit 1
  45. ;;
  46. *) break ;;
  47. esac
  48. done
  49. if [ "$YES" != "1" ]; then
  50. echo >&2 "This script will REMOVE netdata from your system."
  51. echo >&2 "Run it again with --yes to do it."
  52. exit 1
  53. fi
  54. if [[ $EUID -ne 0 ]]; then
  55. echo >&2 "This script SHOULD be run as root or otherwise it won't delete all installed components."
  56. key="n"
  57. read -r -s -n 1 -p "Do you want to continue as non-root user [y/n] ? " key
  58. if [ "$key" != "y" ] && [ "$key" != "Y" ]; then
  59. exit 1
  60. fi
  61. fi
  62. # -----------------------------------------------------------------------------
  63. setup_terminal() {
  64. TPUT_RESET=""
  65. TPUT_YELLOW=""
  66. TPUT_WHITE=""
  67. TPUT_BGRED=""
  68. TPUT_BGGREEN=""
  69. TPUT_BOLD=""
  70. TPUT_DIM=""
  71. # Is stderr on the terminal? If not, then fail
  72. test -t 2 || return 1
  73. if command -v tput 1>/dev/null 2>&1; then
  74. if [ $(($(tput colors 2>/dev/null))) -ge 8 ]; then
  75. # Enable colors
  76. TPUT_RESET="$(tput sgr 0)"
  77. TPUT_YELLOW="$(tput setaf 3)"
  78. TPUT_WHITE="$(tput setaf 7)"
  79. TPUT_BGRED="$(tput setab 1)"
  80. TPUT_BGGREEN="$(tput setab 2)"
  81. TPUT_BOLD="$(tput bold)"
  82. TPUT_DIM="$(tput dim)"
  83. fi
  84. fi
  85. return 0
  86. }
  87. setup_terminal || echo >/dev/null
  88. run_ok() {
  89. printf >&2 "${TPUT_BGGREEN}${TPUT_WHITE}${TPUT_BOLD} OK ${TPUT_RESET} ${*} \n\n"
  90. }
  91. run_failed() {
  92. printf >&2 "${TPUT_BGRED}${TPUT_WHITE}${TPUT_BOLD} FAILED ${TPUT_RESET} ${*} \n\n"
  93. }
  94. ESCAPED_PRINT_METHOD=
  95. printf "%q " test >/dev/null 2>&1
  96. [ $? -eq 0 ] && ESCAPED_PRINT_METHOD="printfq"
  97. escaped_print() {
  98. if [ "${ESCAPED_PRINT_METHOD}" = "printfq" ]; then
  99. printf "%q " "${@}"
  100. else
  101. printf "%s" "${*}"
  102. fi
  103. return 0
  104. }
  105. run_logfile="/dev/null"
  106. run() {
  107. local user="${USER--}" dir="${PWD}" info info_console
  108. if [ "${UID}" = "0" ]; then
  109. info="[root ${dir}]# "
  110. info_console="[${TPUT_DIM}${dir}${TPUT_RESET}]# "
  111. else
  112. info="[${user} ${dir}]$ "
  113. info_console="[${TPUT_DIM}${dir}${TPUT_RESET}]$ "
  114. fi
  115. printf >>"${run_logfile}" "${info}"
  116. escaped_print >>"${run_logfile}" "${@}"
  117. printf >>"${run_logfile}" " ... "
  118. printf >&2 "${info_console}${TPUT_BOLD}${TPUT_YELLOW}"
  119. escaped_print >&2 "${@}"
  120. printf >&2 "${TPUT_RESET}\n"
  121. "${@}"
  122. local ret=$?
  123. if [ ${ret} -ne 0 ]; then
  124. run_failed
  125. printf >>"${run_logfile}" "FAILED with exit code ${ret}\n"
  126. else
  127. run_ok
  128. printf >>"${run_logfile}" "OK\n"
  129. fi
  130. return ${ret}
  131. }
  132. portable_del_group() {
  133. local groupname="${1}"
  134. # Check if group exist
  135. echo >&2 "Removing ${groupname} user group ..."
  136. # Linux
  137. if command -v groupdel 1>/dev/null 2>&1; then
  138. run groupdel -f "${groupname}" && return 0
  139. fi
  140. # mac OS
  141. if command -v dseditgroup 1> /dev/null 2>&1; then
  142. if dseditgroup -o read netdata 1> /dev/null 2>&1; then
  143. run dseditgroup -o delete "${groupname}" && return 0
  144. else
  145. echo >&2 "Could not find group ${groupname}, nothing to do"
  146. fi
  147. fi
  148. echo >&2 "Group ${groupname} was not automatically removed, you might have to remove it manually"
  149. return 1
  150. }
  151. portable_del_user() {
  152. local username="${1}"
  153. echo >&2 "Deleting ${username} user account ..."
  154. # Linux
  155. if command -v userdel 1>/dev/null 2>&1; then
  156. run userdel -f "${username}" && return 0
  157. fi
  158. # mac OS
  159. if command -v sysadminctl 1>/dev/null 2>&1; then
  160. run sysadminctl -deleteUser "${username}" && return 0
  161. fi
  162. echo >&2 "User ${username} could not be deleted from system, you might have to remove it manually"
  163. return 1
  164. }
  165. portable_del_user_from_group() {
  166. local groupname="${1}" username="${2}"
  167. # username is not in group
  168. echo >&2 "Deleting ${username} user from ${groupname} group ..."
  169. # Linux
  170. if command -v gpasswd 1>/dev/null 2>&1; then
  171. run gpasswd -d "netdata" "${group}" && return 0
  172. fi
  173. # FreeBSD
  174. if command -v pw 1>/dev/null 2>&1; then
  175. run pw groupmod "${groupname}" -d "${username}" && return 0
  176. fi
  177. # BusyBox
  178. if command -v delgroup 1>/dev/null 2>&1; then
  179. run delgroup "${username}" "${groupname}" && return 0
  180. fi
  181. # mac OS
  182. if command -v dseditgroup 1> /dev/null 2>&1; then
  183. run dseditgroup -o delete -u "${username}" "${groupname}" && return 0
  184. fi
  185. echo >&2 "Failed to delete user ${username} from group ${groupname} !"
  186. return 1
  187. }
  188. quit_msg() {
  189. echo
  190. if [ "$FILE_REMOVAL_STATUS" -eq 0 ]; then
  191. echo >&2 "Something went wrong :("
  192. else
  193. echo >&2 "Netdata files were successfully removed from your system"
  194. fi
  195. }
  196. user_input() {
  197. TEXT="$1"
  198. if [ "${INTERACTIVITY}" = "-i" ]; then
  199. read -r -p "$TEXT" >&2
  200. fi
  201. }
  202. rm_file() {
  203. FILE="$1"
  204. if [ -f "${FILE}" ]; then
  205. run rm -v ${INTERACTIVITY} "${FILE}"
  206. fi
  207. }
  208. rm_dir() {
  209. DIR="$1"
  210. if [ -n "$DIR" ] && [ -d "$DIR" ]; then
  211. user_input "Press ENTER to recursively delete directory '$DIR' > "
  212. run rm -v -f -R "${DIR}"
  213. fi
  214. }
  215. netdata_pids() {
  216. local p myns ns
  217. myns="$(readlink /proc/self/ns/pid 2>/dev/null)"
  218. for p in \
  219. $(cat /var/run/netdata.pid 2>/dev/null) \
  220. $(cat /var/run/netdata/netdata.pid 2>/dev/null) \
  221. $(pidof netdata 2>/dev/null); do
  222. ns="$(readlink "/proc/${p}/ns/pid" 2>/dev/null)"
  223. #shellcheck disable=SC2002
  224. if [ -z "${myns}" ] || [ -z "${ns}" ] || [ "${myns}" = "${ns}" ]; then
  225. name="$(cat "/proc/${p}/stat" 2>/dev/null | cut -d '(' -f 2 | cut -d ')' -f 1)"
  226. if [ "${name}" = "netdata" ]; then
  227. echo "${p}"
  228. fi
  229. fi
  230. done
  231. }
  232. trap quit_msg EXIT
  233. #shellcheck source=/dev/null
  234. source "${ENVIRONMENT_FILE}" || exit 1
  235. #### STOP NETDATA
  236. echo >&2 "Stopping a possibly running netdata..."
  237. for p in $(netdata_pids); do
  238. i=0
  239. while kill "${p}" 2>/dev/null; do
  240. if [ "$i" -gt 30 ]; then
  241. echo >&2 "Forcefully stopping netdata with pid ${p}"
  242. run kill -9 "${p}"
  243. run sleep 2
  244. break
  245. fi
  246. sleep 1
  247. i=$((i + 1))
  248. done
  249. done
  250. sleep 2
  251. #### REMOVE NETDATA FILES
  252. rm_file /etc/logrotate.d/netdata
  253. rm_file /etc/systemd/system/netdata.service
  254. rm_file /lib/systemd/system/netdata.service
  255. rm_file /usr/lib/systemd/system/netdata.service
  256. rm_file /etc/init.d/netdata
  257. rm_file /etc/periodic/daily/netdata-updater
  258. rm_file /etc/cron.daily/netdata-updater
  259. if [ -n "${NETDATA_PREFIX}" ] && [ -d "${NETDATA_PREFIX}" ]; then
  260. rm_dir "${NETDATA_PREFIX}"
  261. else
  262. rm_file "/usr/sbin/netdata"
  263. rm_dir "/usr/share/netdata"
  264. rm_dir "/usr/libexec/netdata"
  265. rm_dir "/var/lib/netdata"
  266. rm_dir "/var/cache/netdata"
  267. rm_dir "/var/log/netdata"
  268. rm_dir "/etc/netdata"
  269. fi
  270. FILE_REMOVAL_STATUS=1
  271. #### REMOVE NETDATA USER FROM ADDED GROUPS
  272. if [ -n "$NETDATA_ADDED_TO_GROUPS" ]; then
  273. user_input "Press ENTER to delete 'netdata' from following groups: '$NETDATA_ADDED_TO_GROUPS' > "
  274. for group in $NETDATA_ADDED_TO_GROUPS; do
  275. portable_del_user_from_group "${group}" "netdata"
  276. done
  277. fi
  278. #### REMOVE USER
  279. user_input "Press ENTER to delete 'netdata' system user > "
  280. portable_del_user "netdata" || :
  281. ### REMOVE GROUP
  282. user_input "Press ENTER to delete 'netdata' system group > "
  283. portable_del_group "netdata" || :