summaryrefslogtreecommitdiffstats
path: root/packaging/installer
diff options
context:
space:
mode:
Diffstat (limited to 'packaging/installer')
-rw-r--r--packaging/installer/README.md2
-rw-r--r--packaging/installer/UNINSTALL.md9
-rw-r--r--packaging/installer/functions.sh439
-rwxr-xr-xpackaging/installer/kickstart.sh2
-rwxr-xr-xpackaging/installer/netdata-uninstaller.sh169
-rw-r--r--packaging/installer/netdata-updater.sh53
6 files changed, 364 insertions, 310 deletions
diff --git a/packaging/installer/README.md b/packaging/installer/README.md
index edd318fb2..f9cd746a1 100644
--- a/packaging/installer/README.md
+++ b/packaging/installer/README.md
@@ -42,7 +42,7 @@ bash <(curl -Ss https://my-netdata.io/kickstart.sh)
Verify the integrity of the script with this:
```bash
-[ "b66c99c065abe1cf104c11236d4e8747" = "$(curl -Ss https://my-netdata.io/kickstart.sh | md5sum | cut -d ' ' -f 1)" ] && echo "OK, VALID" || echo "FAILED, INVALID"
+[ "e051d1baed4c69653b5d3e4588696466" = "$(curl -Ss https://my-netdata.io/kickstart.sh | md5sum | cut -d ' ' -f 1)" ] && echo "OK, VALID" || echo "FAILED, INVALID"
```
*It should print `OK, VALID` if the script is the one we ship.*
diff --git a/packaging/installer/UNINSTALL.md b/packaging/installer/UNINSTALL.md
index e86a3390e..765184d39 100644
--- a/packaging/installer/UNINSTALL.md
+++ b/packaging/installer/UNINSTALL.md
@@ -14,12 +14,19 @@ A workflow for uninstallation looks like this:
NETDATA_PREFIX="<installation prefix>" # put what you used as a parameter to shell installed `--install` flag. Otherwise it should be empty
NETDATA_ADDED_TO_GROUPS="<additional groups>" # Additional groups for a user running netdata process
```
-3. Download, chmod and run netdata-uninstaller.sh.
+3. Run `netdata-uninstaller.sh` as follows
+```
+${NETDATA_PREFIX}/usr/libexec/netdata-uninstaller.sh --yes --env <environment_file>
+```
+
+Note: Existing installations may still need to download the file if it's not present.
+To execute uninstall in that case, run the following commands:
```
wget https://raw.githubusercontent.com/netdata/netdata/master/packaging/installer/netdata-uninstaller.sh
chmod +x ./netdata-uninstaller.sh
./netdata-uninstaller.sh --yes --env <environment_file>
```
+
The default `environment_file` is `/etc/netdata/.environment`.
Note: This uninstallation method assumes previous installation with netdata-installer.sh or kickstart script. Currently using it when netdata was installed by a package manager can work or cause unexpected results.
diff --git a/packaging/installer/functions.sh b/packaging/installer/functions.sh
index 0d0450842..7016b4f34 100644
--- a/packaging/installer/functions.sh
+++ b/packaging/installer/functions.sh
@@ -6,19 +6,6 @@
[ -z "${UID}" ] && UID="$(id -u)"
# -----------------------------------------------------------------------------
-# checking the availability of commands
-
-which_cmd() {
- # shellcheck disable=SC2230
- which "${1}" 2>/dev/null || command -v "${1}" 2>/dev/null
-}
-
-check_cmd() {
- which_cmd "${1}" >/dev/null 2>&1 && return 0
- return 1
-}
-
-# -----------------------------------------------------------------------------
setup_terminal() {
TPUT_RESET=""
@@ -50,7 +37,7 @@ setup_terminal() {
# Is stderr on the terminal? If not, then fail
test -t 2 || return 1
- if check_cmd tput; then
+ if command -v tput 1>/dev/null 2>&1; then
if [ $(($(tput colors 2>/dev/null))) -ge 8 ]; then
# Enable colors
TPUT_RESET="$(tput sgr 0)"
@@ -117,19 +104,20 @@ netdata_banner() {
# -----------------------------------------------------------------------------
# portable service command
-service_cmd="$(which_cmd service)"
-rcservice_cmd="$(which_cmd rc-service)"
-systemctl_cmd="$(which_cmd systemctl)"
+service_cmd="$(command -v service 2>/dev/null)"
+rcservice_cmd="$(command -v rc-service 2>/dev/null)"
+systemctl_cmd="$(command -v systemctl 2>/dev/null)"
service() {
+
local cmd="${1}" action="${2}"
- if [ ! -z "${systemctl_cmd}" ]; then
+ if [ -n "${systemctl_cmd}" ]; then
run "${systemctl_cmd}" "${action}" "${cmd}"
return $?
- elif [ ! -z "${service_cmd}" ]; then
+ elif [ -n "${service_cmd}" ]; then
run "${service_cmd}" "${cmd}" "${action}"
return $?
- elif [ ! -z "${rcservice_cmd}" ]; then
+ elif [ -n "${rcservice_cmd}" ]; then
run "${rcservice_cmd}" "${cmd}" "${action}"
return $?
fi
@@ -139,9 +127,9 @@ service() {
# -----------------------------------------------------------------------------
# portable pidof
-pidof_cmd="$(which_cmd pidof)"
-pidof() {
- if [ ! -z "${pidof_cmd}" ]; then
+safe_pidof() {
+ local pidof_cmd="$(command -v pidof 2>/dev/null)"
+ if [ -n "${pidof_cmd}" ]; then
${pidof_cmd} "${@}"
return $?
else
@@ -154,39 +142,21 @@ pidof() {
}
# -----------------------------------------------------------------------------
-# portable delete recursively interactively
-
-portable_deletedir_recursively_interactively() {
- if [ ! -z "$1" -a -d "$1" ]; then
- if [ "$(uname -s)" = "Darwin" ]; then
- echo >&2
- read >&2 -p "Press ENTER to recursively delete directory '$1' > "
- echo >&2 "Deleting directory '$1' ..."
- run rm -R "$1"
- else
- echo >&2
- echo >&2 "Deleting directory '$1' ..."
- run rm -I -R "$1"
- fi
- else
- echo "Directory '$1' does not exist."
- fi
-}
-
-# -----------------------------------------------------------------------------
-
-export SYSTEM_CPUS=1
-portable_find_processors() {
+find_processors() {
+ local cpus
if [ -f "/proc/cpuinfo" ]; then
# linux
- SYSTEM_CPUS=$(grep -c ^processor /proc/cpuinfo)
+ cpus=$(grep -c ^processor /proc/cpuinfo)
else
# freebsd
- SYSTEM_CPUS=$(sysctl hw.ncpu 2>/dev/null | grep ^hw.ncpu | cut -d ' ' -f 2)
+ cpus=$(sysctl hw.ncpu 2>/dev/null | grep ^hw.ncpu | cut -d ' ' -f 2)
+ fi
+ if [ -z "${cpus}" ] || [ $((cpus)) -lt 1 ]; then
+ echo 1
+ else
+ echo "${cpus}"
fi
- [ -z "${SYSTEM_CPUS}" -o $((SYSTEM_CPUS)) -lt 1 ] && SYSTEM_CPUS=1
}
-portable_find_processors
# -----------------------------------------------------------------------------
fatal() {
@@ -248,145 +218,10 @@ run() {
return ${ret}
}
-getent_cmd="$(which_cmd getent)"
-portable_check_user_exists() {
- local username="${1}" found=
-
- if [ ! -z "${getent_cmd}" ]; then
- "${getent_cmd}" passwd "${username}" >/dev/null 2>&1
- return $?
- fi
-
- found="$(cut -d ':' -f 1 </etc/passwd | grep "^${username}$")"
- [ "${found}" = "${username}" ] && return 0
- return 1
-}
-
-portable_check_group_exists() {
- local groupname="${1}" found=
-
- if [ ! -z "${getent_cmd}" ]; then
- "${getent_cmd}" group "${groupname}" >/dev/null 2>&1
- return $?
- fi
-
- found="$(cut -d ':' -f 1 </etc/group | grep "^${groupname}$")"
- [ "${found}" = "${groupname}" ] && return 0
- return 1
-}
-
-portable_check_user_in_group() {
- local username="${1}" groupname="${2}" users=
-
- if [ ! -z "${getent_cmd}" ]; then
- users="$(getent group "${groupname}" | cut -d ':' -f 4)"
- else
- users="$(grep "^${groupname}:" </etc/group | cut -d ':' -f 4)"
- fi
-
- [[ ",${users}," =~ ,${username}, ]] && return 0
- return 1
-}
-
-portable_add_user() {
- local username="${1}" homedir="${2}"
-
- [ -z "${homedir}" ] && homedir="/tmp"
-
- portable_check_user_exists "${username}"
- [ $? -eq 0 ] && echo >&2 "User '${username}' already exists." && return 0
-
- echo >&2 "Adding ${username} user account with home ${homedir} ..."
-
- # shellcheck disable=SC2230
- local nologin="$(which nologin 2>/dev/null || command -v nologin 2>/dev/null || echo '/bin/false')"
-
- # Linux
- if check_cmd useradd; then
- run useradd -r -g "${username}" -c "${username}" -s "${nologin}" --no-create-home -d "${homedir}" "${username}" && return 0
- fi
-
- # FreeBSD
- if check_cmd pw; then
- run pw useradd "${username}" -d "${homedir}" -g "${username}" -s "${nologin}" && return 0
- fi
-
- # BusyBox
- if check_cmd adduser; then
- run adduser -h "${homedir}" -s "${nologin}" -D -G "${username}" "${username}" && return 0
- fi
-
- echo >&2 "Failed to add ${username} user account !"
-
- return 1
-}
-
-portable_add_group() {
- local groupname="${1}"
-
- portable_check_group_exists "${groupname}"
- [ $? -eq 0 ] && echo >&2 "Group '${groupname}' already exists." && return 0
-
- echo >&2 "Adding ${groupname} user group ..."
-
- # Linux
- if check_cmd groupadd; then
- run groupadd -r "${groupname}" && return 0
- fi
-
- # FreeBSD
- if check_cmd pw; then
- run pw groupadd "${groupname}" && return 0
- fi
-
- # BusyBox
- if check_cmd addgroup; then
- run addgroup "${groupname}" && return 0
- fi
-
- echo >&2 "Failed to add ${groupname} user group !"
- return 1
-}
-
-portable_add_user_to_group() {
- local groupname="${1}" username="${2}"
-
- portable_check_group_exists "${groupname}"
- [ $? -ne 0 ] && echo >&2 "Group '${groupname}' does not exist." && return 1
-
- # find the user is already in the group
- if portable_check_user_in_group "${username}" "${groupname}"; then
- # username is already there
- echo >&2 "User '${username}' is already in group '${groupname}'."
- return 0
- else
- # username is not in group
- echo >&2 "Adding ${username} user to the ${groupname} group ..."
-
- # Linux
- if check_cmd usermod; then
- run usermod -a -G "${groupname}" "${username}" && return 0
- fi
-
- # FreeBSD
- if check_cmd pw; then
- run pw groupmod "${groupname}" -m "${username}" && return 0
- fi
-
- # BusyBox
- if check_cmd addgroup; then
- run addgroup "${username}" "${groupname}" && return 0
- fi
-
- echo >&2 "Failed to add user ${username} to group ${groupname} !"
- return 1
- fi
-}
-
iscontainer() {
# man systemd-detect-virt
- local cmd=$(which_cmd systemd-detect-virt)
- if [ ! -z "${cmd}" -a -x "${cmd}" ]; then
+ local cmd=$(command -v systemd-detect-virt 2>/dev/null)
+ if [ -n "${cmd}" ] && [ -x "${cmd}" ]; then
"${cmd}" --container >/dev/null 2>&1 && return 0
fi
@@ -394,15 +229,15 @@ iscontainer() {
# http://stackoverflow.com/a/37016302
local pid=$(cat /proc/1/sched 2>/dev/null | head -n 1 | {
IFS='(),#:' read name pid th threads
- echo $pid
+ echo "$pid"
})
- if [ ! -z "${pid}" ]; then
+ if [ -n "${pid}" ]; then
pid=$(( pid + 0 ))
[ ${pid} -gt 1 ] && return 0
fi
# lxc sets environment variable 'container'
- [ ! -z "${container}" ] && return 0
+ [ -n "${container}" ] && return 0
# docker creates /.dockerenv
# http://stackoverflow.com/a/25518345
@@ -425,23 +260,23 @@ issystemd() {
# if there is no systemctl command, it is not systemd
# shellcheck disable=SC2230
- systemctl=$(which systemctl 2>/dev/null || command -v systemctl 2>/dev/null)
+ systemctl=$(command -v systemctl 2>/dev/null)
[ -z "${systemctl}" -o ! -x "${systemctl}" ] && return 1
# if pid 1 is systemd, it is systemd
[ "$(basename $(readlink /proc/1/exe) 2>/dev/null)" = "systemd" ] && return 0
# if systemd is not running, it is not systemd
- pids=$(pidof systemd 2>/dev/null)
+ pids=$(safe_pidof systemd 2>/dev/null)
[ -z "${pids}" ] && return 1
# 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)"
+ ns="$(readlink "/proc/${p}/ns/pid" 2>/dev/null)"
# if pid of systemd is in our namespace, it is systemd
- [ ! -z "${myns}" ] && [ "${myns}" = "${ns}" ] && return 0
+ [ -n "${myns}" ] && [ "${myns}" = "${ns}" ] && return 0
done
# else, it is not systemd
@@ -460,7 +295,7 @@ install_non_systemd_init() {
key=$(</etc/redhat-release)
fi
- if [ -d /etc/init.d -a ! -f /etc/init.d/netdata ]; then
+ if [ -d /etc/init.d ] && [ ! -f /etc/init.d/netdata ]; then
if [[ ${key} =~ ^(gentoo|alpine).* ]]; then
echo >&2 "Installing OpenRC init file..."
run cp system/netdata-openrc /etc/init.d/netdata &&
@@ -468,10 +303,7 @@ install_non_systemd_init() {
run rc-update add netdata default &&
return 0
- elif [ "${key}" = "debian-7" \
- -o "${key}" = "ubuntu-12.04" \
- -o "${key}" = "ubuntu-14.04" \
- ]; then
+ elif [ "${key}" = "debian-7" ] || [ "${key}" = "ubuntu-12.04" ] || [ "${key}" = "ubuntu-14.04" ]; then
echo >&2 "Installing LSB init file..."
run cp system/netdata-lsb /etc/init.d/netdata &&
run chmod 755 /etc/init.d/netdata &&
@@ -551,10 +383,10 @@ install_netdata_service() {
local ret=$?
if [ ${ret} -eq 0 ]; then
- if [ ! -z "${service_cmd}" ]; then
+ if [ -n "${service_cmd}" ]; then
NETDATA_START_CMD="service netdata start"
NETDATA_STOP_CMD="service netdata stop"
- elif [ ! -z "${rcservice_cmd}" ]; then
+ elif [ -n "${rcservice_cmd}" ]; then
NETDATA_START_CMD="rc-service netdata start"
NETDATA_STOP_CMD="rc-service netdata stop"
fi
@@ -582,10 +414,10 @@ pidisnetdata() {
stop_netdata_on_pid() {
local pid="${1}" ret=0 count=0
- pidisnetdata ${pid} || return 0
+ pidisnetdata "${pid}" || return 0
- printf >&2 "Stopping netdata on pid ${pid} ..."
- while [ ! -z "$pid" -a ${ret} -eq 0 ]; do
+ printf >&2 "Stopping netdata on pid %s ..." "${pid}"
+ while [ -n "$pid" ] && [ ${ret} -eq 0 ]; do
if [ ${count} -gt 45 ]; then
echo >&2 "Cannot stop the running netdata on pid ${pid}."
return 1
@@ -593,7 +425,7 @@ stop_netdata_on_pid() {
count=$((count + 1))
- run kill ${pid} 2>/dev/null
+ run kill "${pid}" 2>/dev/null
ret=$?
test ${ret} -eq 0 && printf >&2 "." && sleep 2
@@ -619,11 +451,11 @@ netdata_pids() {
for p in \
$(cat /var/run/netdata.pid 2>/dev/null) \
$(cat /var/run/netdata/netdata.pid 2>/dev/null) \
- $(pidof netdata 2>/dev/null); do
- ns="$(readlink /proc/${p}/ns/pid 2>/dev/null)"
+ $(safe_pidof netdata 2>/dev/null); do
+ ns="$(readlink "/proc/${p}/ns/pid" 2>/dev/null)"
- if [ -z "${myns}" -o -z "${ns}" -o "${myns}" = "${ns}" ]; then
- pidisnetdata ${p} && echo "${p}"
+ if [ -z "${myns}" ] || [ -z "${ns}" ] || [ "${myns}" = "${ns}" ]; then
+ pidisnetdata "${p}" && echo "${p}"
fi
done
}
@@ -631,6 +463,7 @@ netdata_pids() {
stop_all_netdata() {
local p
for p in $(netdata_pids); do
+ # shellcheck disable=SC2086
stop_netdata_on_pid ${p}
done
}
@@ -651,7 +484,7 @@ restart_netdata() {
stop_all_netdata
service netdata restart && started=1
- if [ ${started} -eq 1 -a -z "$(netdata_pids)" ]; then
+ if [ ${started} -eq 1 ] && [ -z "$(netdata_pids)" ]; then
echo >&2 "Ooops! it seems netdata is not started."
started=0
fi
@@ -661,7 +494,7 @@ restart_netdata() {
fi
fi
- if [ ${started} -eq 1 -a -z "$(netdata_pids)" ]; then
+ if [ ${started} -eq 1 ] && [ -z "$(netdata_pids)" ]; then
echo >&2 "Hm... it seems netdata is still not started."
started=0
fi
@@ -681,7 +514,7 @@ restart_netdata() {
# install netdata logrotate
install_netdata_logrotate() {
- if [ ${UID} -eq 0 ]; then
+ if [ "${UID}" -eq 0 ]; then
if [ -d /etc/logrotate.d ]; then
if [ ! -f /etc/logrotate.d/netdata ]; then
run cp system/netdata.logrotate /etc/logrotate.d/netdata
@@ -699,103 +532,149 @@ install_netdata_logrotate() {
}
# -----------------------------------------------------------------------------
-# download netdata.conf
+# create netdata.conf
-fix_netdata_conf() {
- local owner="${1}"
+create_netdata_conf() {
+ local path="${1}" url="${2}"
- if [ "${UID}" -eq 0 ]; then
- run chown "${owner}" "${filename}"
- fi
- run chmod 0664 "${filename}"
-}
-
-generate_netdata_conf() {
- local owner="${1}" filename="${2}" url="${3}"
-
- if [ ! -s "${filename}" ]; then
- cat >"${filename}" <<EOFCONF
-# netdata can generate its own config.
-# Get it with:
-#
-# wget -O ${filename} "${url}"
-#
-# or
-#
-# curl -s -o ${filename} "${url}"
-#
-EOFCONF
- fix_netdata_conf "${owner}"
+ if [ -s "${path}" ]; then
+ return 0
fi
-}
-download_netdata_conf() {
- local owner="${1}" filename="${2}" url="${3}"
-
- if [ ! -s "${filename}" ]; then
- echo >&2
- echo >&2 "-------------------------------------------------------------------------------"
- echo >&2
+ if [ -n "$url" ]; then
echo >&2 "Downloading default configuration from netdata..."
sleep 5
- # remove a possibly obsolete download
- [ -f "${filename}.new" ] && rm "${filename}.new"
+ # remove a possibly obsolete configuration file
+ [ -f "${path}.new" ] && rm "${path}.new"
# disable a proxy to get data from the local netdata
export http_proxy=
export https_proxy=
- # try curl
- run curl -s -o "${filename}.new" "${url}"
- ret=$?
-
- if [ ${ret} -ne 0 -o ! -s "${filename}.new" ]; then
- # try wget
- run wget -O "${filename}.new" "${url}"
- ret=$?
+ if command -v curl 1>/dev/null 2>&1; then
+ run curl -sSL --connect-timeout 10 --retry 3 "${url}" >"${path}.new"
+ elif command -v wget 1>/dev/null 2>&1; then
+ run wget -T 15 -O - "${url}" >"${path}.new"
fi
- if [ ${ret} -eq 0 -a -s "${filename}.new" ]; then
- run mv "${filename}.new" "${filename}"
- run_ok "New configuration saved for you to edit at ${filename}"
+ if [ -s "${path}.new" ]; then
+ run mv "${path}.new" "${path}"
+ run_ok "New configuration saved for you to edit at ${path}"
else
- [ -f "${filename}.new" ] && rm "${filename}.new"
+ [ -f "${path}.new" ] && rm "${path}.new"
run_failed "Cannnot download configuration from netdata daemon using url '${url}'"
-
- generate_netdata_conf "${owner}" "${filename}" "${url}"
+ url=''
fi
+ fi
- fix_netdata_conf "${owner}"
+ if [ -z "$url" ]; then
+ echo "# netdata can generate its own config which is available at 'http://<netdata_ip>/netdata.conf'" >"${path}"
+ echo "# You can download it with command like: 'wget -O ${path} http://localhost:19999/netdata.conf'" >>"${path}"
fi
+
}
-# -----------------------------------------------------------------------------
-# add netdata user and group
+portable_add_user() {
+ local username="${1}" homedir="${2}"
-NETDATA_WANTED_GROUPS="docker nginx varnish haproxy adm nsd proxy squid ceph nobody"
-NETDATA_ADDED_TO_GROUPS=""
-add_netdata_user_and_group() {
- local homedir="${1}" g
+ [ -z "${homedir}" ] && homedir="/tmp"
+
+ # Check if user exists
+ if cut -d ':' -f 1 </etc/passwd | grep "^${username}$" 1>/dev/null 2>&1; then
+ echo >&2 "User '${username}' already exists."
+ return 0
+ fi
- if [ ${UID} -eq 0 ]; then
- portable_add_group netdata || return 1
- portable_add_user netdata "${homedir}" || return 1
+ echo >&2 "Adding ${username} user account with home ${homedir} ..."
- for g in ${NETDATA_WANTED_GROUPS}; do
- portable_add_user_to_group ${g} netdata && NETDATA_ADDED_TO_GROUPS="${NETDATA_ADDED_TO_GROUPS} ${g}"
- done
+ # shellcheck disable=SC2230
+ local nologin="$(command -v nologin >/dev/null 2>&1 || echo '/bin/false')"
- [ ~netdata = / ] && cat <<USERMOD
+ # Linux
+ if command -v useradd 1>/dev/null 2>&1; then
+ run useradd -r -g "${username}" -c "${username}" -s "${nologin}" --no-create-home -d "${homedir}" "${username}" && return 0
+ fi
-The netdata user has its home directory set to /
-You may want to change it, using this command:
+ # FreeBSD
+ if command -v pw 1>/dev/null 2>&1; then
+ run pw useradd "${username}" -d "${homedir}" -g "${username}" -s "${nologin}" && return 0
+ fi
-# usermod -d "${homedir}" netdata
+ # BusyBox
+ if command -v adduser 1>/dev/null 2>&1; then
+ run adduser -h "${homedir}" -s "${nologin}" -D -G "${username}" "${username}" && return 0
+ fi
-USERMOD
- return 0
+ echo >&2 "Failed to add ${username} user account !"
+
+ return 1
+}
+
+portable_add_group() {
+ local groupname="${1}"
+
+ # Check if group exist
+ if cut -d ':' -f 1 </etc/group | grep "^${groupname}$" 1>/dev/null 2>&1; then
+ echo >&2 "Group '${groupname}' already exists."
+ return 0
+ fi
+
+ echo >&2 "Adding ${groupname} user group ..."
+
+ # Linux
+ if command -v groupadd 1>/dev/null 2>&1; then
+ run groupadd -r "${groupname}" && return 0
fi
+ # FreeBSD
+ if command -v pw 1>/dev/null 2>&1; then
+ run pw groupadd "${groupname}" && return 0
+ fi
+
+ # BusyBox
+ if command -v addgroup 1>/dev/null 2>&1; then
+ run addgroup "${groupname}" && return 0
+ fi
+
+ echo >&2 "Failed to add ${groupname} user group !"
return 1
}
+
+portable_add_user_to_group() {
+ local groupname="${1}" username="${2}"
+
+ # Check if group exist
+ if ! cut -d ':' -f 1 </etc/group | grep "^${groupname}$" >/dev/null 2>&1; then
+ echo >&2 "Group '${groupname}' does not exist."
+ return 1
+ fi
+
+ # Check if user is in group
+ if [[ ",$(grep "^${groupname}:" </etc/group | cut -d ':' -f 4)," =~ ,${username}, ]]; then
+ # username is already there
+ echo >&2 "User '${username}' is already in group '${groupname}'."
+ return 0
+ else
+ # username is not in group
+ echo >&2 "Adding ${username} user to the ${groupname} group ..."
+
+ # Linux
+ if command -v usermod 1>/dev/null 2>&1; then
+ run usermod -a -G "${groupname}" "${username}" && return 0
+ fi
+
+ # FreeBSD
+ if command -v pw 1>/dev/null 2>&1; then
+ run pw groupmod "${groupname}" -m "${username}" && return 0
+ fi
+
+ # BusyBox
+ if command -v addgroup 1>/dev/null 2>&1; then
+ run addgroup "${username}" "${groupname}" && return 0
+ fi
+
+ echo >&2 "Failed to add user ${username} to group ${groupname} !"
+ return 1
+ fi
+}
diff --git a/packaging/installer/kickstart.sh b/packaging/installer/kickstart.sh
index 196b75892..f5683327a 100755
--- a/packaging/installer/kickstart.sh
+++ b/packaging/installer/kickstart.sh
@@ -83,7 +83,7 @@ run() {
escaped_print "${info_console}${TPUT_BOLD}${TPUT_YELLOW}" "${@}" "${TPUT_RESET}\n" >&2
- "${@}"
+ ${@}
local ret=$?
if [ ${ret} -ne 0 ]; then
diff --git a/packaging/installer/netdata-uninstaller.sh b/packaging/installer/netdata-uninstaller.sh
new file mode 100755
index 000000000..96dd62906
--- /dev/null
+++ b/packaging/installer/netdata-uninstaller.sh
@@ -0,0 +1,169 @@
+#!/usr/bin/env bash
+#shellcheck disable=SC2181
+
+# this script will uninstall netdata
+
+# Variables needed by script and taken from '.environment' file:
+# - NETDATA_PREFIX
+# - NETDATA_ADDED_TO_GROUPS
+
+usage="$(basename "$0") [-h] [-f ] -- program to calculate the answer to life, the universe and everything
+
+where:
+ -e, --env path to environment file (defauls to '/etc/netdata/.environment'
+ -f, --force force uninstallation and do not ask any questions
+ -h show this help text
+ -y, --yes flag needs to be set to proceed with uninstallation"
+
+FILE_REMOVAL_STATUS=0
+ENVIRONMENT_FILE="/etc/netdata/.environment"
+INTERACTIVITY="-i"
+YES=0
+while :; do
+ case "$1" in
+ -h | --help)
+ echo "$usage" >&2
+ exit 1
+ ;;
+ -f | --force)
+ INTERACTIVITY="-f"
+ shift
+ ;;
+ -y | --yes)
+ YES=1
+ shift
+ ;;
+ -e | --env)
+ ENVIRONMENT_FILE="$2"
+ shift 2
+ ;;
+ -*)
+ echo "$usage" >&2
+ exit 1
+ ;;
+ *) break ;;
+ esac
+done
+
+if [ "$YES" != "1" ]; then
+ echo "This script will REMOVE netdata from your system."
+ echo "Run it again with --yes to do it."
+ exit 1
+fi
+
+if [[ $EUID -ne 0 ]]; then
+ echo "This script SHOULD be run as root or otherwise it won't delete all installed components."
+ key="n"
+ read -r -s -n 1 -p "Do you want to continue as non-root user [y/n] ? " key
+ if [ "$key" != "y" ] && [ "$key" != "Y" ]; then
+ exit 1
+ fi
+fi
+
+function quit_msg() {
+ echo
+ if [ "$FILE_REMOVAL_STATUS" -eq 0 ]; then
+ echo "Something went wrong :("
+ else
+ echo "Netdata files were successfully removed from your system"
+ fi
+}
+
+function user_input() {
+ TEXT="$1"
+ if [ "${INTERACTIVITY}" == "-i" ]; then
+ read -r -p "$TEXT" >&2
+ fi
+}
+
+function rm_file() {
+ FILE="$1"
+ if [ -f "${FILE}" ]; then
+ rm -v ${INTERACTIVITY} "${FILE}"
+ fi
+}
+
+function rm_dir() {
+ DIR="$1"
+ if [ -n "$DIR" ] && [ -d "$DIR" ]; then
+ user_input "Press ENTER to recursively delete directory '$DIR' > "
+ rm -v -f -R "${DIR}"
+ fi
+}
+
+netdata_pids() {
+ local p myns ns
+ myns="$(readlink /proc/self/ns/pid 2>/dev/null)"
+ for p in \
+ $(cat /var/run/netdata.pid 2>/dev/null) \
+ $(cat /var/run/netdata/netdata.pid 2>/dev/null) \
+ $(pidof netdata 2>/dev/null); do
+
+ ns="$(readlink "/proc/${p}/ns/pid" 2>/dev/null)"
+ #shellcheck disable=SC2002
+ if [ -z "${myns}" ] || [ -z "${ns}" ] || [ "${myns}" = "${ns}" ]; then
+ name="$(cat "/proc/${p}/stat" 2>/dev/null | cut -d '(' -f 2 | cut -d ')' -f 1)"
+ if [ "${name}" = "netdata" ]; then
+ echo "${p}"
+ fi
+ fi
+ done
+}
+
+trap quit_msg EXIT
+
+#shellcheck source=/dev/null
+source "${ENVIRONMENT_FILE}" || exit 1
+
+#### STOP NETDATA
+echo "Stopping a possibly running netdata..."
+for p in $(netdata_pids); do
+ i=0
+ while kill "${p}" 2>/dev/null; do
+ if [ "$i" -gt 30 ]; then
+ echo "Forcefully stopping netdata with pid ${p}"
+ kill -9 "${p}"
+ sleep 2
+ break
+ fi
+ sleep 1
+ i=$((i + 1))
+ done
+done
+sleep 2
+
+#### REMOVE NETDATA FILES
+rm_file /etc/logrotate.d/netdata
+rm_file /etc/systemd/system/netdata.service
+rm_file /lib/systemd/system/netdata.service
+rm_file /usr/lib/systemd/system/netdata.service
+rm_file /etc/init.d/netdata
+rm_file /etc/periodic/daily/netdata-updater
+rm_file /etc/cron.daily/netdata-updater
+
+if [ -n "${NETDATA_PREFIX}" ] && [ -d "${NETDATA_PREFIX}" ]; then
+ rm_dir "${NETDATA_PREFIX}"
+else
+ rm_file "/usr/sbin/netdata"
+ rm_dir "/usr/share/netdata"
+ rm_dir "/usr/libexec/netdata"
+ rm_dir "/var/lib/netdata"
+ rm_dir "/var/cache/netdata"
+ rm_dir "/var/log/netdata"
+ rm_dir "/etc/netdata"
+fi
+
+FILE_REMOVAL_STATUS=1
+
+#### REMOVE NETDATA USER & GROUP
+if [ -n "$NETDATA_ADDED_TO_GROUPS" ]; then
+ user_input "Press ENTER to delete 'netdata' from following groups: '$NETDATA_ADDED_TO_GROUPS' > "
+ for group in $NETDATA_ADDED_TO_GROUPS; do
+ gpasswd -d netdata "${group}"
+ done
+fi
+
+user_input "Press ENTER to delete 'netdata' system user > "
+userdel -f netdata || :
+user_input "Press ENTER to delete 'netdata' system group > "
+groupdel -f netdata || :
diff --git a/packaging/installer/netdata-updater.sh b/packaging/installer/netdata-updater.sh
index 2dce5efc1..071198dd6 100644
--- a/packaging/installer/netdata-updater.sh
+++ b/packaging/installer/netdata-updater.sh
@@ -77,36 +77,35 @@ update() {
download "${NETDATA_TARBALL_CHECKSUM_URL}" "${dir}/sha256sum.txt" >&3 2>&3
if grep "${NETDATA_TARBALL_CHECKSUM}" sha256sum.txt >&3 2>&3; then
info "Newest version is already installed"
- exit 0
- fi
-
- download "${NETDATA_TARBALL_URL}" "${dir}/netdata-latest.tar.gz"
- if ! grep netdata-latest.tar.gz sha256sum.txt | sha256sum --check - >&3 2>&3; then
- failed "Tarball checksum validation failed. Stopping netdata upgrade and leaving tarball in ${dir}"
- fi
- NEW_CHECKSUM="$(sha256sum netdata-latest.tar.gz 2>/dev/null| cut -d' ' -f1)"
- tar -xf netdata-latest.tar.gz >&3 2>&3
- rm netdata-latest.tar.gz >&3 2>&3
- cd netdata-*
-
- # signal netdata to start saving its database
- # this is handy if your database is big
- pids=$(pidof netdata)
- do_not_start=
- if [ -n "${pids}" ]; then
- #shellcheck disable=SC2086
- kill -USR1 ${pids}
else
- # netdata is currently not running, so do not start it after updating
- do_not_start="--dont-start-it"
- fi
-
- info "Re-installing netdata..."
- eval "${REINSTALL_COMMAND} --dont-wait ${do_not_start}" >&3 2>&3 || fatal "FAILED TO COMPILE/INSTALL NETDATA"
- sed -i '/NETDATA_TARBALL/d' "${ENVIRONMENT_FILE}"
- cat <<EOF >>"${ENVIRONMENT_FILE}"
+ download "${NETDATA_TARBALL_URL}" "${dir}/netdata-latest.tar.gz"
+ if ! grep netdata-latest.tar.gz sha256sum.txt | sha256sum --check - >&3 2>&3; then
+ failed "Tarball checksum validation failed. Stopping netdata upgrade and leaving tarball in ${dir}"
+ fi
+ NEW_CHECKSUM="$(sha256sum netdata-latest.tar.gz 2>/dev/null| cut -d' ' -f1)"
+ tar -xf netdata-latest.tar.gz >&3 2>&3
+ rm netdata-latest.tar.gz >&3 2>&3
+ cd netdata-*
+
+ # signal netdata to start saving its database
+ # this is handy if your database is big
+ pids=$(pidof netdata)
+ do_not_start=
+ if [ -n "${pids}" ]; then
+ #shellcheck disable=SC2086
+ kill -USR1 ${pids}
+ else
+ # netdata is currently not running, so do not start it after updating
+ do_not_start="--dont-start-it"
+ fi
+
+ info "Re-installing netdata..."
+ eval "${REINSTALL_COMMAND} --dont-wait ${do_not_start}" >&3 2>&3 || fatal "FAILED TO COMPILE/INSTALL NETDATA"
+ sed -i '/NETDATA_TARBALL/d' "${ENVIRONMENT_FILE}"
+ cat <<EOF >>"${ENVIRONMENT_FILE}"
NETDATA_TARBALL_CHECKSUM="$NEW_CHECKSUM"
EOF
+ fi
rm -rf "${dir}" >&3 2>&3
[ -n "${logfile}" ] && rm "${logfile}" && logfile=