From a8220ab2d293bb7f4b014b79d16b2fb05090fa93 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Feb 2021 12:45:55 +0100 Subject: Adding upstream version 1.29.0. Signed-off-by: Daniel Baumann --- netdata-installer.sh | 1847 ++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 1332 insertions(+), 515 deletions(-) (limited to 'netdata-installer.sh') diff --git a/netdata-installer.sh b/netdata-installer.sh index 9f9704645..c11e1a7ec 100755 --- a/netdata-installer.sh +++ b/netdata-installer.sh @@ -1,18 +1,19 @@ #!/usr/bin/env bash + # SPDX-License-Identifier: GPL-3.0-or-later # shellcheck disable=SC2046,SC2086,SC2166 export PATH="${PATH}:/sbin:/usr/sbin:/usr/local/bin:/usr/local/sbin" uniquepath() { - local path="" - while read -r; do - if [[ ! ${path} =~ (^|:)"${REPLY}"(:|$) ]]; then - [ -n "${path}" ] && path="${path}:" - path="${path}${REPLY}" - fi - done < <(echo "${PATH}" | tr ":" "\\n") - - [ -n "${path}" ] && [[ ${PATH} =~ /bin ]] && [[ ${PATH} =~ /sbin ]] && export PATH="${path}" + local path="" + while read -r; do + if [[ ! ${path} =~ (^|:)"${REPLY}"(:|$) ]]; then + [ -n "${path}" ] && path="${path}:" + path="${path}${REPLY}" + fi + done < <(echo "${PATH}" | tr ":" "\n") + + [ -n "${path}" ] && [[ ${PATH} =~ /bin ]] && [[ ${PATH} =~ /sbin ]] && export PATH="${path}" } uniquepath @@ -21,7 +22,14 @@ NETDATA_SOURCE_DIR="$(pwd)" INSTALLER_DIR="$(dirname "${PROGRAM}")" if [ "${NETDATA_SOURCE_DIR}" != "${INSTALLER_DIR}" ] && [ "${INSTALLER_DIR}" != "." ]; then - echo >&2 "Warning: you are currently in '${NETDATA_SOURCE_DIR}' but the installer is in '${INSTALLER_DIR}'." + echo >&2 "Warning: you are currently in '${NETDATA_SOURCE_DIR}' but the installer is in '${INSTALLER_DIR}'." +fi + +# ----------------------------------------------------------------------------- +# Pull in OpenSSL properly if on macOS +if [ "$(uname -s)" = 'Darwin' ] && [ -d /usr/local/opt/openssl/include ]; then + export C_INCLUDE_PATH="/usr/local/opt/openssl/include" + export LDFLAGS="-L/usr/local/opt/openssl@1.1/lib" fi # ----------------------------------------------------------------------------- @@ -33,33 +41,78 @@ fi # make sure /etc/profile does not change our current directory cd "${NETDATA_SOURCE_DIR}" || exit 1 +# ----------------------------------------------------------------------------- +# figure out an appropriate temporary directory +_cannot_use_tmpdir() { + local testfile ret + testfile="$(TMPDIR="${1}" mktemp -q -t netdata-test.XXXXXXXXXX)" + ret=0 + + if [ -z "${testfile}" ]; then + return "${ret}" + fi + + if printf '#!/bin/sh\necho SUCCESS\n' > "${testfile}"; then + if chmod +x "${testfile}"; then + if [ "$("${testfile}")" = "SUCCESS" ]; then + ret=1 + fi + fi + fi + + rm -f "${testfile}" + return "${ret}" +} + +if [ -z "${TMPDIR}" ] || _cannot_use_tmpdir "${TMPDIR}"; then + if _cannot_use_tmpdir /tmp; then + if _cannot_use_tmpdir "${PWD}"; then + echo >&2 + echo >&2 "Unable to find a usable temprorary directory. Please set \$TMPDIR to a path that is both writable and allows execution of files and try again." + exit 1 + else + TMPDIR="${PWD}" + fi + else + TMPDIR="/tmp" + fi +fi + +# ----------------------------------------------------------------------------- +# set up handling for deferred error messages +NETDATA_DEFERRED_ERRORS="" + +defer_error() { + NETDATA_DEFERRED_ERRORS="${NETDATA_DEFERRED_ERRORS}\n* ${1}" +} + +defer_error_highlighted() { + NETDATA_DEFERRED_ERRORS="${TPUT_YELLOW}${TPUT_BOLD}${NETDATA_DEFERRED_ERRORS}\n* ${1}${TPUT_RESET}" +} + +print_deferred_errors() { + if [ -n "${NETDATA_DEFERRED_ERRORS}" ]; then + echo >&2 + echo >&2 "The following non-fatal errors were encountered during the installation process:" + # shellcheck disable=SC2059 + printf >&2 "${NETDATA_DEFERRED_ERRORS}" + echo >&2 + fi +} + # ----------------------------------------------------------------------------- # load the required functions if [ -f "${INSTALLER_DIR}/packaging/installer/functions.sh" ]; then - # shellcheck source=packaging/installer/functions.sh - source "${INSTALLER_DIR}/packaging/installer/functions.sh" || exit 1 + # shellcheck source=packaging/installer/functions.sh + source "${INSTALLER_DIR}/packaging/installer/functions.sh" || exit 1 else - # shellcheck source=packaging/installer/functions.sh - source "${NETDATA_SOURCE_DIR}/packaging/installer/functions.sh" || exit 1 + # shellcheck source=packaging/installer/functions.sh + source "${NETDATA_SOURCE_DIR}/packaging/installer/functions.sh" || exit 1 fi download_go() { - url="${1}" - dest="${2}" - - if command -v curl >/dev/null 2>&1; then - run curl -sSL --connect-timeout 10 --retry 3 "${url}" > "${dest}" - elif command -v wget >/dev/null 2>&1; then - run wget -T 15 -O - "${url}" > "${dest}" - else - echo >&2 - echo >&2 "Downloading go.d plugin from '${url}' failed because of missing mandatory packages." - echo >&2 "Either add packages or disable it by issuing '--disable-go' in the installer" - echo >&2 - - run_failed "I need curl or wget to proceed, but neither is available on this system." - fi + download_file "${1}" "${2}" "go.d plugin" "go" } # make sure we save all commands we run @@ -69,41 +122,40 @@ run_logfile="netdata-installer.log" # fix PKG_CHECK_MODULES error if [ -d /usr/share/aclocal ]; then - ACLOCAL_PATH=${ACLOCAL_PATH-/usr/share/aclocal} - export ACLOCAL_PATH + ACLOCAL_PATH=${ACLOCAL_PATH-/usr/share/aclocal} + export ACLOCAL_PATH fi export LC_ALL=C umask 002 # Be nice on production environments -renice 19 $$ >/dev/null 2>/dev/null +renice 19 $$ > /dev/null 2> /dev/null # you can set CFLAGS before running installer +LDFLAGS="${LDFLAGS}" CFLAGS="${CFLAGS--O2}" [ "z${CFLAGS}" = "z-O3" ] && CFLAGS="-O2" +ACLK="${ACLK}" # keep a log of this command # shellcheck disable=SC2129 -printf "\\n# " >>netdata-installer.log -date >>netdata-installer.log -printf 'CFLAGS="%s" ' "${CFLAGS}" >>netdata-installer.log -printf "%q " "${PROGRAM}" "${@}" >>netdata-installer.log -printf "\\n" >>netdata-installer.log - -REINSTALL_COMMAND="$( - printf "%q " "${PROGRAM}" "${@}" - printf "\\n" +printf "\n# " >> netdata-installer.log +date >> netdata-installer.log +printf 'CFLAGS="%s" ' "${CFLAGS}" >> netdata-installer.log +printf 'LDFLAGS="%s" ' "${LDFLAGS}" >> netdata-installer.log +printf "%q " "${PROGRAM}" "${@}" >> netdata-installer.log +printf "\n" >> netdata-installer.log + +REINSTALL_OPTIONS="$( + printf "%s" "${*}" + printf "\n" )" # remove options that shown not be inherited by netdata-updater.sh -REINSTALL_COMMAND="${REINSTALL_COMMAND// --dont-wait/}" -REINSTALL_COMMAND="${REINSTALL_COMMAND// --dont-start-it/}" -if [ "${REINSTALL_COMMAND:0:1}" != "." ] && [ "${REINSTALL_COMMAND:0:1}" != "/" ] && [ -f "./${PROGRAM}" ]; then - REINSTALL_COMMAND="./${REINSTALL_COMMAND}" -fi +REINSTALL_OPTIONS="$(echo "${REINSTALL_OPTIONS}" | sed 's/--dont-wait//g' | sed 's/--dont-start-it//g')" banner_nonroot_install() { - cat </dev/null)" ]; then - autoconf_maj_min() { - local maj min IFS=.- - - maj=$1 - min=$2 - - set -- $(autoreconf -V | sed -ne '1s/.* \([^ ]*\)$/\1/p') - eval $maj=\$1 $min=\$2 - } - autoconf_maj_min AMAJ AMIN - - if [ "$AMAJ" -gt 2 ]; then - have_autotools=Y - elif [ "$AMAJ" -eq 2 -a "$AMIN" -ge 60 ]; then - have_autotools=Y - else - echo "Found autotools $AMAJ.$AMIN" - fi +if [ "$(type autoreconf 2> /dev/null)" ]; then + autoconf_maj_min() { + local maj min IFS=.- + + maj=$1 + min=$2 + + set -- $(autoreconf -V | sed -ne '1s/.* \([^ ]*\)$/\1/p') + eval $maj=\$1 $min=\$2 + } + autoconf_maj_min AMAJ AMIN + + if [ "$AMAJ" -gt 2 ]; then + have_autotools=Y + elif [ "$AMAJ" -eq 2 -a "$AMIN" -ge 60 ]; then + have_autotools=Y + else + echo "Found autotools $AMAJ.$AMIN" + fi else - echo "No autotools found" + echo "No autotools found" fi if [ ! "$have_autotools" ]; then - if [ -f configure ]; then - echo "Will skip autoreconf step" - else - netdata_banner "autotools v2.60 required" - cat <<"EOF" + if [ -f configure ]; then + echo "Will skip autoreconf step" + else + netdata_banner "autotools v2.60 required" + cat << "EOF" ------------------------------------------------------------------------------- autotools 2.60 or later is required @@ -327,26 +460,26 @@ Sorry, you do not seem to have autotools 2.60 or later, which is required to build from the git sources of netdata. EOF - exit 1 - fi + exit 1 + fi fi if [ ${DONOTWAIT} -eq 0 ]; then - if [ -n "${NETDATA_PREFIX}" ]; then - echo -n "${TPUT_BOLD}${TPUT_GREEN}Press ENTER to build and install netdata to '${TPUT_CYAN}${NETDATA_PREFIX}${TPUT_YELLOW}'${TPUT_RESET} > " - else - echo -n "${TPUT_BOLD}${TPUT_GREEN}Press ENTER to build and install netdata to your system${TPUT_RESET} > " - fi - read -ern1 - if [ "$REPLY" != '' ]; then - exit 1 - fi + if [ -n "${NETDATA_PREFIX}" ]; then + echo -n "${TPUT_BOLD}${TPUT_GREEN}Press ENTER to build and install netdata to '${TPUT_CYAN}${NETDATA_PREFIX}${TPUT_YELLOW}'${TPUT_RESET} > " + else + echo -n "${TPUT_BOLD}${TPUT_GREEN}Press ENTER to build and install netdata to your system${TPUT_RESET} > " + fi + read -ern1 + if [ "$REPLY" != '' ]; then + exit 1 + fi fi build_error() { - netdata_banner "sorry, it failed to build..." - cat <&2 "ok, assuming libs are really installed." - export ZLIB_CFLAGS=" " - export ZLIB_LIBS="-lz" - export UUID_CFLAGS=" " - export UUID_LIBS="-luuid" + shift + echo >&2 "ok, assuming libs are really installed." + export ZLIB_CFLAGS=" " + export ZLIB_LIBS="-lz" + export UUID_CFLAGS=" " + export UUID_LIBS="-luuid" fi trap build_error EXIT +# ----------------------------------------------------------------------------- + +build_libmosquitto() { + local env_cmd='' + + if [ -z "${DONT_SCRUB_CFLAGS_EVEN_THOUGH_IT_MAY_BREAK_THINGS}" ]; then + env_cmd="env CFLAGS=-fPIC CXXFLAGS= LDFLAGS=" + fi + + if [ "$(uname -s)" = Linux ]; then + run ${env_cmd} make -C "${1}/lib" + else + pushd ${1} > /dev/null || return 1 + if [ "$(uname)" = "Darwin" ] && [ -d /usr/local/opt/openssl ]; then + run ${env_cmd} cmake \ + -D OPENSSL_ROOT_DIR=/usr/local/opt/openssl \ + -D OPENSSL_LIBRARIES=/usr/local/opt/openssl/lib \ + -D WITH_STATIC_LIBRARIES:boolean=YES \ + . + else + run ${env_cmd} cmake -D WITH_STATIC_LIBRARIES:boolean=YES . + fi + run ${env_cmd} make -C lib + run mv lib/libmosquitto_static.a lib/libmosquitto.a + popd || return 1 + fi +} + +copy_libmosquitto() { + target_dir="${PWD}/externaldeps/mosquitto" + + run mkdir -p "${target_dir}" + + run cp "${1}/lib/libmosquitto.a" "${target_dir}" + run cp "${1}/lib/mosquitto.h" "${target_dir}" +} + +bundle_libmosquitto() { + if [ -n "${NETDATA_DISABLE_CLOUD}" ]; then + echo "Skipping cloud" + return 0 + fi + + progress "Prepare custom libmosquitto version" + + MOSQUITTO_PACKAGE_VERSION="$(cat packaging/mosquitto.version)" + + tmp="$(mktemp -d -t netdata-mosquitto-XXXXXX)" + MOSQUITTO_PACKAGE_BASENAME="${MOSQUITTO_PACKAGE_VERSION}.tar.gz" + + if fetch_and_verify "mosquitto" \ + "https://github.com/netdata/mosquitto/archive/${MOSQUITTO_PACKAGE_BASENAME}" \ + "${MOSQUITTO_PACKAGE_BASENAME}" \ + "${tmp}" \ + "${NETDATA_LOCAL_TARBALL_OVERRIDE_MOSQUITTO}"; then + if run tar -xf "${tmp}/${MOSQUITTO_PACKAGE_BASENAME}" -C "${tmp}" && + build_libmosquitto "${tmp}/mosquitto-${MOSQUITTO_PACKAGE_VERSION}" && + copy_libmosquitto "${tmp}/mosquitto-${MOSQUITTO_PACKAGE_VERSION}" && + rm -rf "${tmp}"; then + run_ok "libmosquitto built and prepared." + else + run_failed "Failed to build libmosquitto." + if [ -n "${NETDATA_REQUIRE_CLOUD}" ]; then + exit 1 + else + defer_error_highlighted "Unable to fetch sources for libmosquitto. You will not be able to connect this node to Netdata Cloud." + fi + fi + else + run_failed "Unable to fetch sources for libmosquitto." + if [ -n "${NETDATA_REQUIRE_CLOUD}" ]; then + exit 1 + else + defer_error_highlighted "Unable to fetch sources for libmosquitto. You will not be able to connect this node to Netdata Cloud." + fi + fi +} + +bundle_libmosquitto + +# ----------------------------------------------------------------------------- + +build_libwebsockets() { + local env_cmd='' + + if [ -z "${DONT_SCRUB_CFLAGS_EVEN_THOUGH_IT_MAY_BREAK_THINGS}" ]; then + env_cmd="env CFLAGS=-fPIC CXXFLAGS= LDFLAGS=" + fi + + pushd "${1}" > /dev/null || exit 1 + + if [ "$(uname)" = "Darwin" ]; then + run patch -p1 << "EOF" +--- a/lib/plat/unix/private.h ++++ b/lib/plat/unix/private.h +@@ -164,6 +164,8 @@ delete_from_fd(const struct lws_context *context, int fd); + * but happily have something equivalent in the SO_NOSIGPIPE flag. + */ + #ifdef __APPLE__ ++/* iOS SDK 12+ seems to define it, undef it for compatibility both ways */ ++#undef MSG_NOSIGNAL + #define MSG_NOSIGNAL SO_NOSIGPIPE + #endif +EOF + + # shellcheck disable=SC2181 + if [ $? -ne 0 ]; then + return 1 + fi + fi + + if [ "$(uname)" = "Darwin" ] && [ -d /usr/local/opt/openssl ]; then + run ${env_cmd} cmake \ + -D OPENSSL_ROOT_DIR=/usr/local/opt/openssl \ + -D OPENSSL_LIBRARIES=/usr/local/opt/openssl/lib \ + -D LWS_WITH_SOCKS5:bool=ON \ + $CMAKE_FLAGS \ + . + else + run ${env_cmd} cmake -D LWS_WITH_SOCKS5:bool=ON $CMAKE_FLAGS . + fi + run ${env_cmd} make + popd > /dev/null || exit 1 +} + +copy_libwebsockets() { + target_dir="${PWD}/externaldeps/libwebsockets" + + run mkdir -p "${target_dir}" || return 1 + + run cp "${1}/lib/libwebsockets.a" "${target_dir}/libwebsockets.a" || return 1 + run cp -r "${1}/include" "${target_dir}" || return 1 +} + +bundle_libwebsockets() { + if [ -n "${NETDATA_DISABLE_CLOUD}" ] || [ -n "${USE_SYSTEM_LWS}" ]; then + return 0 + fi + + if [ -z "$(command -v cmake)" ]; then + run_failed "Could not find cmake, which is required to build libwebsockets. The install process will continue, but you may not be able to connect this node to Netdata Cloud." + defer_error_highlighted "Could not find cmake, which is required to build libwebsockets. The install process will continue, but you may not be able to connect this node to Netdata Cloud." + return 0 + fi + + progress "Prepare libwebsockets" + + LIBWEBSOCKETS_PACKAGE_VERSION="$(cat packaging/libwebsockets.version)" + + tmp="$(mktemp -d -t netdata-libwebsockets-XXXXXX)" + LIBWEBSOCKETS_PACKAGE_BASENAME="v${LIBWEBSOCKETS_PACKAGE_VERSION}.tar.gz" + + if fetch_and_verify "libwebsockets" \ + "https://github.com/warmcat/libwebsockets/archive/${LIBWEBSOCKETS_PACKAGE_BASENAME}" \ + "${LIBWEBSOCKETS_PACKAGE_BASENAME}" \ + "${tmp}" \ + "${NETDATA_LOCAL_TARBALL_OVERRIDE_LIBWEBSOCKETS}"; then + if run tar -xf "${tmp}/${LIBWEBSOCKETS_PACKAGE_BASENAME}" -C "${tmp}" && + build_libwebsockets "${tmp}/libwebsockets-${LIBWEBSOCKETS_PACKAGE_VERSION}" && + copy_libwebsockets "${tmp}/libwebsockets-${LIBWEBSOCKETS_PACKAGE_VERSION}" && + rm -rf "${tmp}"; then + run_ok "libwebsockets built and prepared." + NETDATA_CONFIGURE_OPTIONS="${NETDATA_CONFIGURE_OPTIONS} --with-bundled-lws=externaldeps/libwebsockets" + else + run_failed "Failed to build libwebsockets." + if [ -n "${NETDATA_REQUIRE_CLOUD}" ]; then + exit 1 + else + defer_error_highlighted "Failed to build libwebsockets. You may not be able to connect this node to Netdata Cloud." + fi + fi + else + run_failed "Unable to fetch sources for libwebsockets." + if [ -n "${NETDATA_REQUIRE_CLOUD}" ]; then + exit 1 + else + defer_error_highlighted "Unable to fetch sources for libwebsockets. You may not be able to connect this node to Netdata Cloud." + fi + fi +} + +bundle_libwebsockets + +# ----------------------------------------------------------------------------- + +build_judy() { + local env_cmd='' + local libtoolize="libtoolize" + + if [ -z "${DONT_SCRUB_CFLAGS_EVEN_THOUGH_IT_MAY_BREAK_THINGS}" ]; then + env_cmd="env CFLAGS=-fPIC CXXFLAGS= LDFLAGS=" + fi + + if [ "$(uname)" = "Darwin" ]; then + libtoolize="glibtoolize" + fi + + pushd "${1}" > /dev/null || return 1 + if run ${env_cmd} ${libtoolize} --force --copy && + run ${env_cmd} aclocal && + run ${env_cmd} autoheader && + run ${env_cmd} automake --add-missing --force --copy --include-deps && + run ${env_cmd} autoconf && + run ${env_cmd} ./configure && + run ${env_cmd} make -C src && + run ${env_cmd} ar -r src/libJudy.a src/Judy*/*.o; then + popd > /dev/null || return 1 + else + popd > /dev/null || return 1 + return 1 + fi +} + +copy_judy() { + target_dir="${PWD}/externaldeps/libJudy" + + run mkdir -p "${target_dir}" || return 1 + + run cp "${1}/src/libJudy.a" "${target_dir}/libJudy.a" || return 1 + run cp "${1}/src/Judy.h" "${target_dir}/Judy.h" || return 1 +} + +bundle_judy() { + # If --build-judy flag or no Judy on the system and we're building the dbengine, bundle our own libJudy. + # shellcheck disable=SC2235 + if [ -n "${NETDATA_DISABLE_DBENGINE}" ] || ([ -z "${NETDATA_BUILD_JUDY}" ] && [ -e /usr/include/Judy.h ]); then + return 0 + elif [ -n "${NETDATA_BUILD_JUDY}" ]; then + progress "User requested bundling of libJudy, building it now" + elif [ ! -e /usr/include/Judy.h ]; then + progress "/usr/include/Judy.h does not exist, but we need libJudy, building our own copy" + fi + + progress "Prepare libJudy" + + JUDY_PACKAGE_VERSION="$(cat packaging/judy.version)" + + tmp="$(mktemp -d -t netdata-judy-XXXXXX)" + JUDY_PACKAGE_BASENAME="v${JUDY_PACKAGE_VERSION}.tar.gz" + + if fetch_and_verify "judy" \ + "https://github.com/netdata/libjudy/archive/${JUDY_PACKAGE_BASENAME}" \ + "${JUDY_PACKAGE_BASENAME}" \ + "${tmp}" \ + "${NETDATA_LOCAL_TARBALL_OVERRIDE_JUDY}"; then + if run tar -xf "${tmp}/${JUDY_PACKAGE_BASENAME}" -C "${tmp}" && + build_judy "${tmp}/libjudy-${JUDY_PACKAGE_VERSION}" && + copy_judy "${tmp}/libjudy-${JUDY_PACKAGE_VERSION}" && + rm -rf "${tmp}"; then + run_ok "libJudy built and prepared." + NETDATA_CONFIGURE_OPTIONS="${NETDATA_CONFIGURE_OPTIONS} --with-libJudy=externaldeps/libJudy" + else + run_failed "Failed to build libJudy." + if [ -n "${NETDATA_BUILD_JUDY}" ]; then + exit 1 + else + defer_error_highlighted "Failed to build libJudy. dbengine support will be disabled." + fi + fi + else + run_failed "Unable to fetch sources for libJudy." + if [ -n "${NETDATA_BUILD_JUDY}" ]; then + exit 1 + else + defer_error_highlighted "Unable to fetch sources for libJudy. dbengine support will be disabled." + fi + fi +} + +bundle_judy + +# ----------------------------------------------------------------------------- + +build_jsonc() { + local env_cmd='' + + if [ -z "${DONT_SCRUB_CFLAGS_EVEN_THOUGH_IT_MAY_BREAK_THINGS}" ]; then + env_cmd="env CFLAGS=-fPIC CXXFLAGS= LDFLAGS=" + fi + + pushd "${1}" > /dev/null || exit 1 + run ${env_cmd} cmake -DBUILD_SHARED_LIBS=OFF . + run ${env_cmd} make + popd > /dev/null || exit 1 +} + +copy_jsonc() { + target_dir="${PWD}/externaldeps/jsonc" + + run mkdir -p "${target_dir}" "${target_dir}/json-c" || return 1 + + run cp "${1}/libjson-c.a" "${target_dir}/libjson-c.a" || return 1 + run cp ${1}/*.h "${target_dir}/json-c" || return 1 +} + +bundle_jsonc() { + # If --build-json-c flag or not json-c on system, then bundle our own json-c + if [ -z "${NETDATA_BUILD_JSON_C}" ] && pkg-config json-c; then + return 0 + fi + + if [ -z "$(command -v cmake)" ]; then + run_failed "Could not find cmake, which is required to build JSON-C. The install process will continue, but Netdata Cloud support will be disabled." + defer_error_highlighted "Could not find cmake, which is required to build JSON-C. The install process will continue, but Netdata Cloud support will be disabled." + return 0 + fi + + progress "Prepare JSON-C" + + JSONC_PACKAGE_VERSION="$(cat packaging/jsonc.version)" + + tmp="$(mktemp -d -t netdata-jsonc-XXXXXX)" + JSONC_PACKAGE_BASENAME="json-c-${JSONC_PACKAGE_VERSION}.tar.gz" + + if fetch_and_verify "jsonc" \ + "https://github.com/json-c/json-c/archive/${JSONC_PACKAGE_BASENAME}" \ + "${JSONC_PACKAGE_BASENAME}" \ + "${tmp}" \ + "${NETDATA_LOCAL_TARBALL_OVERRIDE_JSONC}"; then + if run tar -xf "${tmp}/${JSONC_PACKAGE_BASENAME}" -C "${tmp}" && + build_jsonc "${tmp}/json-c-json-c-${JSONC_PACKAGE_VERSION}" && + copy_jsonc "${tmp}/json-c-json-c-${JSONC_PACKAGE_VERSION}" && + rm -rf "${tmp}"; then + run_ok "JSON-C built and prepared." + else + run_failed "Failed to build JSON-C." + if [ -n "${NETDATA_REQUIRE_CLOUD}" ]; then + exit 1 + else + defer_error_highlighted "Failed to build JSON-C. Netdata Cloud support will be disabled." + fi + fi + else + run_failed "Unable to fetch sources for JSON-C." + if [ -n "${NETDATA_REQUIRE_CLOUD}" ]; then + exit 1 + else + defer_error_highlighted "Unable to fetch sources for JSON-C. Netdata Cloud support will be disabled." + fi + fi +} + +bundle_jsonc + +# ----------------------------------------------------------------------------- + +build_libbpf() { + pushd "${1}/src" > /dev/null || exit 1 + run env CFLAGS=-fPIC CXXFLAGS= LDFLAGS= BUILD_STATIC_ONLY=y OBJDIR=build DESTDIR=.. make install + popd > /dev/null || exit 1 +} + +copy_libbpf() { + target_dir="${PWD}/externaldeps/libbpf" + + if [ "$(uname -m)" = x86_64 ]; then + lib_subdir="lib64" + else + lib_subdir="lib" + fi + + run mkdir -p "${target_dir}" || return 1 + + run cp "${1}/usr/${lib_subdir}/libbpf.a" "${target_dir}/libbpf.a" || return 1 + run cp -r "${1}/usr/include" "${target_dir}" || return 1 +} + +bundle_libbpf() { + if { [ -n "${NETDATA_DISABLE_EBPF}" ] && [ ${NETDATA_DISABLE_EBPF} = 1 ]; } || [ "$(uname -s)" != Linux ]; then + return 0 + fi + + progress "Prepare libbpf" + + LIBBPF_PACKAGE_VERSION="$(cat packaging/libbpf.version)" + + tmp="$(mktemp -d -t netdata-libbpf-XXXXXX)" + LIBBPF_PACKAGE_BASENAME="v${LIBBPF_PACKAGE_VERSION}.tar.gz" + + if fetch_and_verify "libbpf" \ + "https://github.com/netdata/libbpf/archive/${LIBBPF_PACKAGE_BASENAME}" \ + "${LIBBPF_PACKAGE_BASENAME}" \ + "${tmp}" \ + "${NETDATA_LOCAL_TARBALL_OVERRIDE_LIBBPF}"; then + if run tar -xf "${tmp}/${LIBBPF_PACKAGE_BASENAME}" -C "${tmp}" && + build_libbpf "${tmp}/libbpf-${LIBBPF_PACKAGE_VERSION}" && + copy_libbpf "${tmp}/libbpf-${LIBBPF_PACKAGE_VERSION}" && + rm -rf "${tmp}"; then + run_ok "libbpf built and prepared." + else + run_failed "Failed to build libbpf." + if [ -n "${NETDATA_DISABLE_EBPF}" ] && [ ${NETDATA_DISABLE_EBPF} = 0 ]; then + exit 1 + else + defer_error_highlighted "Failed to build libbpf. You may not be able to use eBPF plugin." + fi + fi + else + run_failed "Unable to fetch sources for libbpf." + if [ -n "${NETDATA_DISABLE_EBPF}" ] && [ ${NETDATA_DISABLE_EBPF} = 0 ]; then + exit 1 + else + defer_error_highlighted "Unable to fetch sources for libbpf. You may not be able to use eBPF plugin." + fi + fi +} + +bundle_libbpf + +# ----------------------------------------------------------------------------- +# If we have the dashboard switching logic, make sure we're on the classic +# dashboard during the install (updates don't work correctly otherwise). +if [ -x "${NETDATA_PREFIX}/usr/libexec/netdata-switch-dashboard.sh" ]; then + "${NETDATA_PREFIX}/usr/libexec/netdata-switch-dashboard.sh" classic +fi + +# ----------------------------------------------------------------------------- +# By default, `git` does not update local tags based on remotes. Because +# we use the most recent tag as part of our version determination in +# our build, this can lead to strange versions that look ancient but are +# actually really recent. To avoid this, try and fetch tags if we're +# working in a git checkout. +if [ -d ./.git ] ; then + echo >&2 + progress "Updating tags in git to ensure a consistent version number" + run git fetch 'refs/tags/*:refs/tags/*' || true +fi + # ----------------------------------------------------------------------------- echo >&2 progress "Run autotools to configure the build environment" if [ "$have_autotools" ]; then - run autoreconf -ivf || exit 1 + run autoreconf -ivf || exit 1 fi run ./configure \ - --prefix="${NETDATA_PREFIX}/usr" \ - --sysconfdir="${NETDATA_PREFIX}/etc" \ - --localstatedir="${NETDATA_PREFIX}/var" \ - --libexecdir="${NETDATA_PREFIX}/usr/libexec" \ - --libdir="${NETDATA_PREFIX}/usr/lib" \ - --with-zlib \ - --with-math \ - --with-user=netdata \ - ${NETDATA_CONFIGURE_OPTIONS} \ - CFLAGS="${CFLAGS}" || exit 1 + --prefix="${NETDATA_PREFIX}/usr" \ + --sysconfdir="${NETDATA_PREFIX}/etc" \ + --localstatedir="${NETDATA_PREFIX}/var" \ + --libexecdir="${NETDATA_PREFIX}/usr/libexec" \ + --libdir="${NETDATA_PREFIX}/usr/lib" \ + --with-zlib \ + --with-math \ + --with-user=netdata \ + ${NETDATA_CONFIGURE_OPTIONS} \ + CFLAGS="${CFLAGS}" LDFLAGS="${LDFLAGS}" || exit 1 # remove the build_error hook trap - EXIT @@ -417,12 +983,12 @@ trap - EXIT # ----------------------------------------------------------------------------- progress "Cleanup compilation directory" -run make clean +run $make clean # ----------------------------------------------------------------------------- progress "Compile netdata" -run make -j$(find_processors) || exit 1 +run $make -j$(find_processors) || exit 1 # ----------------------------------------------------------------------------- progress "Migrate configuration files for node.d.plugin and charts.d.plugin" @@ -430,111 +996,111 @@ progress "Migrate configuration files for node.d.plugin and charts.d.plugin" # migrate existing configuration files # for node.d and charts.d if [ -d "${NETDATA_PREFIX}/etc/netdata" ]; then - # the configuration directory exists - - if [ ! -d "${NETDATA_PREFIX}/etc/netdata/charts.d" ]; then - run mkdir "${NETDATA_PREFIX}/etc/netdata/charts.d" - fi - - # move the charts.d config files - for x in apache ap cpu_apps cpufreq example exim hddtemp load_average mem_apps mysql nginx nut opensips phpfpm postfix sensors squid tomcat; do - for y in "" ".old" ".orig"; do - if [ -f "${NETDATA_PREFIX}/etc/netdata/${x}.conf${y}" -a ! -f "${NETDATA_PREFIX}/etc/netdata/charts.d/${x}.conf${y}" ]; then - run mv -f "${NETDATA_PREFIX}/etc/netdata/${x}.conf${y}" "${NETDATA_PREFIX}/etc/netdata/charts.d/${x}.conf${y}" - fi - done - done - - if [ ! -d "${NETDATA_PREFIX}/etc/netdata/node.d" ]; then - run mkdir "${NETDATA_PREFIX}/etc/netdata/node.d" - fi - - # move the node.d config files - for x in named sma_webbox snmp; do - for y in "" ".old" ".orig"; do - if [ -f "${NETDATA_PREFIX}/etc/netdata/${x}.conf${y}" -a ! -f "${NETDATA_PREFIX}/etc/netdata/node.d/${x}.conf${y}" ]; then - run mv -f "${NETDATA_PREFIX}/etc/netdata/${x}.conf${y}" "${NETDATA_PREFIX}/etc/netdata/node.d/${x}.conf${y}" - fi - done - done + # the configuration directory exists + + if [ ! -d "${NETDATA_PREFIX}/etc/netdata/charts.d" ]; then + run mkdir "${NETDATA_PREFIX}/etc/netdata/charts.d" + fi + + # move the charts.d config files + for x in apache ap cpu_apps cpufreq example exim hddtemp load_average mem_apps mysql nginx nut opensips phpfpm postfix sensors squid tomcat; do + for y in "" ".old" ".orig"; do + if [ -f "${NETDATA_PREFIX}/etc/netdata/${x}.conf${y}" -a ! -f "${NETDATA_PREFIX}/etc/netdata/charts.d/${x}.conf${y}" ]; then + run mv -f "${NETDATA_PREFIX}/etc/netdata/${x}.conf${y}" "${NETDATA_PREFIX}/etc/netdata/charts.d/${x}.conf${y}" + fi + done + done + + if [ ! -d "${NETDATA_PREFIX}/etc/netdata/node.d" ]; then + run mkdir "${NETDATA_PREFIX}/etc/netdata/node.d" + fi + + # move the node.d config files + for x in named sma_webbox snmp; do + for y in "" ".old" ".orig"; do + if [ -f "${NETDATA_PREFIX}/etc/netdata/${x}.conf${y}" -a ! -f "${NETDATA_PREFIX}/etc/netdata/node.d/${x}.conf${y}" ]; then + run mv -f "${NETDATA_PREFIX}/etc/netdata/${x}.conf${y}" "${NETDATA_PREFIX}/etc/netdata/node.d/${x}.conf${y}" + fi + done + done fi # ----------------------------------------------------------------------------- # shellcheck disable=SC2230 -md5sum="$(command -v md5sum 2>/dev/null || command -v md5 2>/dev/null)" +md5sum="$(command -v md5sum 2> /dev/null || command -v md5 2> /dev/null)" deleted_stock_configs=0 if [ ! -f "${NETDATA_PREFIX}/etc/netdata/.installer-cleanup-of-stock-configs-done" ]; then - progress "Backup existing netdata configuration before installing it" - - if [ "${BASH_VERSINFO[0]}" -ge "4" ]; then - declare -A configs_signatures=() - if [ -f "configs.signatures" ]; then - source "configs.signatures" || echo >&2 "ERROR: Failed to load configs.signatures !" - fi - fi - - config_signature_matches() { - local md5="${1}" file="${2}" - - if [ "${BASH_VERSINFO[0]}" -ge "4" ]; then - [ "${configs_signatures[${md5}]}" = "${file}" ] && return 0 - return 1 - fi - - if [ -f "configs.signatures" ]; then - grep "\['${md5}'\]='${file}'" "configs.signatures" >/dev/null - return $? - fi - - return 1 - } - - # clean up stock config files from the user configuration directory - for x in $(find -L "${NETDATA_PREFIX}/etc/netdata" -type f -not -path '*/\.*' -not -path "${NETDATA_PREFIX}/etc/netdata/orig/*" \( -name '*.conf.old' -o -name '*.conf' -o -name '*.conf.orig' -o -name '*.conf.installer_backup.*' \)); do - if [ -f "${x}" ]; then - # find it relative filename - f="${x/${NETDATA_PREFIX}\/etc\/netdata\//}" - - # find the stock filename - t="${f/.conf.installer_backup.*/.conf}" - t="${t/.conf.old/.conf}" - t="${t/.conf.orig/.conf}" - t="${t/orig\//}" - - if [ -z "${md5sum}" -o ! -x "${md5sum}" ]; then - # we don't have md5sum - keep it - echo >&2 "File '${TPUT_CYAN}${x}${TPUT_RESET}' ${TPUT_RET}is not known to distribution${TPUT_RESET}. Keeping it." - else - # find its checksum - md5="$(${md5sum} <"${x}" | cut -d ' ' -f 1)" - - if config_signature_matches "${md5}" "${t}"; then - # it is a stock version - remove it - echo >&2 "File '${TPUT_CYAN}${x}${TPUT_RESET}' is stock version of '${t}'." - run rm -f "${x}" - deleted_stock_configs=$((deleted_stock_configs + 1)) - else - # edited by user - keep it - echo >&2 "File '${TPUT_CYAN}${x}${TPUT_RESET}' ${TPUT_RED} does not match stock of${TPUT_RESET} ${TPUT_CYAN}'${t}'${TPUT_RESET}. Keeping it." - fi - fi - fi - done + progress "Backup existing netdata configuration before installing it" + + if [ "${BASH_VERSINFO[0]}" -ge "4" ]; then + declare -A configs_signatures=() + if [ -f "configs.signatures" ]; then + source "configs.signatures" || echo >&2 "ERROR: Failed to load configs.signatures !" + fi + fi + + config_signature_matches() { + local md5="${1}" file="${2}" + + if [ "${BASH_VERSINFO[0]}" -ge "4" ]; then + [ "${configs_signatures[${md5}]}" = "${file}" ] && return 0 + return 1 + fi + + if [ -f "configs.signatures" ]; then + grep "\['${md5}'\]='${file}'" "configs.signatures" > /dev/null + return $? + fi + + return 1 + } + + # clean up stock config files from the user configuration directory + while IFS= read -r -d '' x; do + if [ -f "${x}" ]; then + # find it relative filename + f="${x/${NETDATA_PREFIX}\/etc\/netdata\//}" + + # find the stock filename + t="${f/.conf.installer_backup.*/.conf}" + t="${t/.conf.old/.conf}" + t="${t/.conf.orig/.conf}" + t="${t/orig\//}" + + if [ -z "${md5sum}" -o ! -x "${md5sum}" ]; then + # we don't have md5sum - keep it + echo >&2 "File '${TPUT_CYAN}${x}${TPUT_RESET}' ${TPUT_RED}is not known to distribution${TPUT_RESET}. Keeping it." + else + # find its checksum + md5="$(${md5sum} < "${x}" | cut -d ' ' -f 1)" + + if config_signature_matches "${md5}" "${t}"; then + # it is a stock version - remove it + echo >&2 "File '${TPUT_CYAN}${x}${TPUT_RESET}' is stock version of '${t}'." + run rm -f "${x}" + deleted_stock_configs=$((deleted_stock_configs + 1)) + else + # edited by user - keep it + echo >&2 "File '${TPUT_CYAN}${x}${TPUT_RESET}' ${TPUT_RED} does not match stock of${TPUT_RESET} ${TPUT_CYAN}'${t}'${TPUT_RESET}. Keeping it." + fi + fi + fi + done < <(find -L "${NETDATA_PREFIX}/etc/netdata" -type f -not -path '*/\.*' -not -path "${NETDATA_PREFIX}/etc/netdata/orig/*" \( -name '*.conf.old' -o -name '*.conf' -o -name '*.conf.orig' -o -name '*.conf.installer_backup.*' \)) fi touch "${NETDATA_PREFIX}/etc/netdata/.installer-cleanup-of-stock-configs-done" # ----------------------------------------------------------------------------- progress "Install netdata" -run make install || exit 1 +run $make install || exit 1 # ----------------------------------------------------------------------------- progress "Fix generated files permissions" -run find ./system/ -type f -a \! -name \*.in -a \! -name Makefile\* -a \! -name \*.conf -a \! -name \*.service -a \! -name \*.logrotate -exec chmod 755 {} \; +run find ./system/ -type f -a \! -name \*.in -a \! -name Makefile\* -a \! -name \*.conf -a \! -name \*.service -a \! -name \*.timer -a \! -name \*.logrotate -exec chmod 755 {} \; # ----------------------------------------------------------------------------- progress "Creating standard user and groups for netdata" @@ -542,19 +1108,19 @@ progress "Creating standard user and groups for netdata" NETDATA_WANTED_GROUPS="docker nginx varnish haproxy adm nsd proxy squid ceph nobody" NETDATA_ADDED_TO_GROUPS="" if [ "${UID}" -eq 0 ]; then - progress "Adding group 'netdata'" - portable_add_group netdata || : + progress "Adding group 'netdata'" + portable_add_group netdata || : - progress "Adding user 'netdata'" - portable_add_user netdata "${NETDATA_PREFIX}/var/lib/netdata" || : + progress "Adding user 'netdata'" + portable_add_user netdata "${NETDATA_PREFIX}/var/lib/netdata" || : - progress "Assign user 'netdata' to required groups" - for g in ${NETDATA_WANTED_GROUPS}; do - # shellcheck disable=SC2086 - portable_add_user_to_group ${g} netdata && NETDATA_ADDED_TO_GROUPS="${NETDATA_ADDED_TO_GROUPS} ${g}" - done + progress "Assign user 'netdata' to required groups" + for g in ${NETDATA_WANTED_GROUPS}; do + # shellcheck disable=SC2086 + portable_add_user_to_group ${g} netdata && NETDATA_ADDED_TO_GROUPS="${NETDATA_ADDED_TO_GROUPS} ${g}" + done else - run_failed "The installer does not run as root. Nothing to do for user and groups" + run_failed "The installer does not run as root. Nothing to do for user and groups" fi # ----------------------------------------------------------------------------- @@ -562,35 +1128,34 @@ progress "Install logrotate configuration for netdata" install_netdata_logrotate - # ----------------------------------------------------------------------------- progress "Read installation options from netdata.conf" # create an empty config if it does not exist [ ! -f "${NETDATA_PREFIX}/etc/netdata/netdata.conf" ] && - touch "${NETDATA_PREFIX}/etc/netdata/netdata.conf" + touch "${NETDATA_PREFIX}/etc/netdata/netdata.conf" # function to extract values from the config file config_option() { - local section="${1}" key="${2}" value="${3}" - - if [ -s "${NETDATA_PREFIX}/etc/netdata/netdata.conf" ]; then - "${NETDATA_PREFIX}/usr/sbin/netdata" \ - -c "${NETDATA_PREFIX}/etc/netdata/netdata.conf" \ - -W get "${section}" "${key}" "${value}" || - echo "${value}" - else - echo "${value}" - fi + local section="${1}" key="${2}" value="${3}" + + if [ -s "${NETDATA_PREFIX}/etc/netdata/netdata.conf" ]; then + "${NETDATA_PREFIX}/usr/sbin/netdata" \ + -c "${NETDATA_PREFIX}/etc/netdata/netdata.conf" \ + -W get "${section}" "${key}" "${value}" || + echo "${value}" + else + echo "${value}" + fi } # the user netdata will run as if [ "${UID}" = "0" ]; then - NETDATA_USER="$(config_option "global" "run as user" "netdata")" - ROOT_USER="root" + NETDATA_USER="$(config_option "global" "run as user" "netdata")" + ROOT_USER="root" else - NETDATA_USER="${USER}" - ROOT_USER="${USER}" + NETDATA_USER="${USER}" + ROOT_USER="${USER}" fi NETDATA_GROUP="$(id -g -n "${NETDATA_USER}")" [ -z "${NETDATA_GROUP}" ] && NETDATA_GROUP="${NETDATA_USER}" @@ -600,8 +1165,8 @@ echo >&2 "Netdata user and group is finally set to: ${NETDATA_USER}/${NETDATA_GR NETDATA_WEB_USER="$(config_option "web" "web files owner" "${NETDATA_USER}")" NETDATA_WEB_GROUP="${NETDATA_GROUP}" if [ "${UID}" = "0" ] && [ "${NETDATA_USER}" != "${NETDATA_WEB_USER}" ]; then - NETDATA_WEB_GROUP="$(id -g -n "${NETDATA_WEB_USER}")" - [ -z "${NETDATA_WEB_GROUP}" ] && NETDATA_WEB_GROUP="${NETDATA_WEB_USER}" + NETDATA_WEB_GROUP="$(id -g -n "${NETDATA_WEB_USER}")" + [ -z "${NETDATA_WEB_GROUP}" ] && NETDATA_WEB_GROUP="${NETDATA_WEB_USER}" fi NETDATA_WEB_GROUP="$(config_option "web" "web files group" "${NETDATA_WEB_GROUP}")" @@ -617,8 +1182,9 @@ NETDATA_LOG_DIR="$(config_option "global" "log directory" "${NETDATA_PREFIX}/var NETDATA_USER_CONFIG_DIR="$(config_option "global" "config directory" "${NETDATA_PREFIX}/etc/netdata")" NETDATA_STOCK_CONFIG_DIR="$(config_option "global" "stock config directory" "${NETDATA_PREFIX}/usr/lib/netdata/conf.d")" NETDATA_RUN_DIR="${NETDATA_PREFIX}/var/run" +NETDATA_CLAIMING_DIR="${NETDATA_LIB_DIR}/cloud.d" -cat <&2 "Creating directory '${NETDATA_WEB_DIR}'" - run mkdir -p "${NETDATA_WEB_DIR}" || exit 1 + echo >&2 "Creating directory '${NETDATA_WEB_DIR}'" + run mkdir -p "${NETDATA_WEB_DIR}" || exit 1 fi run chown -R "${NETDATA_WEB_USER}:${NETDATA_WEB_GROUP}" "${NETDATA_WEB_DIR}" run find "${NETDATA_WEB_DIR}" -type f -exec chmod 0664 {} \; @@ -678,217 +1241,468 @@ run find "${NETDATA_WEB_DIR}" -type d -exec chmod 0775 {} \; # --- data dirs ---- for x in "${NETDATA_LIB_DIR}" "${NETDATA_CACHE_DIR}" "${NETDATA_LOG_DIR}"; do - if [ ! -d "${x}" ]; then - echo >&2 "Creating directory '${x}'" - run mkdir -p "${x}" || exit 1 - fi - - run chown -R "${NETDATA_USER}:${NETDATA_GROUP}" "${x}" - #run find "${x}" -type f -exec chmod 0660 {} \; - #run find "${x}" -type d -exec chmod 0770 {} \; + if [ ! -d "${x}" ]; then + echo >&2 "Creating directory '${x}'" + run mkdir -p "${x}" || exit 1 + fi + + run chown -R "${NETDATA_USER}:${NETDATA_GROUP}" "${x}" + #run find "${x}" -type f -exec chmod 0660 {} \; + #run find "${x}" -type d -exec chmod 0770 {} \; done run chmod 755 "${NETDATA_LOG_DIR}" +# --- claiming dir ---- + +if [ ! -d "${NETDATA_CLAIMING_DIR}" ]; then + echo >&2 "Creating directory '${NETDATA_CLAIMING_DIR}'" + run mkdir -p "${NETDATA_CLAIMING_DIR}" || exit 1 +fi +run chown -R "${NETDATA_USER}:${NETDATA_GROUP}" "${NETDATA_CLAIMING_DIR}" +run chmod 770 "${NETDATA_CLAIMING_DIR}" + # --- plugins ---- if [ "${UID}" -eq 0 ]; then - # find the admin group - admin_group= - test -z "${admin_group}" && getent group root >/dev/null 2>&1 && admin_group="root" - test -z "${admin_group}" && getent group daemon >/dev/null 2>&1 && admin_group="daemon" - test -z "${admin_group}" && admin_group="${NETDATA_GROUP}" - - run chown "${NETDATA_USER}:${admin_group}" "${NETDATA_LOG_DIR}" - run chown -R "root:${NETDATA_GROUP}" "${NETDATA_PREFIX}/usr/libexec/netdata" - run find "${NETDATA_PREFIX}/usr/libexec/netdata" -type d -exec chmod 0755 {} \; - run find "${NETDATA_PREFIX}/usr/libexec/netdata" -type f -exec chmod 0644 {} \; - run find "${NETDATA_PREFIX}/usr/libexec/netdata" -type f -a -name \*.plugin -exec chmod 0750 {} \; - run find "${NETDATA_PREFIX}/usr/libexec/netdata" -type f -a -name \*.sh -exec chmod 0755 {} \; - - if [ -f "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/apps.plugin" ]; then - run chown "root:${NETDATA_GROUP}" "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/apps.plugin" - capabilities=0 - if ! iscontainer && command -v setcap 1>/dev/null 2>&1; then - run chmod 0750 "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/apps.plugin" - if run setcap cap_dac_read_search,cap_sys_ptrace+ep "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/apps.plugin"; then - # if we managed to setcap, but we fail to execute apps.plugin setuid to root - "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/apps.plugin" -t >/dev/null 2>&1 && capabilities=1 || capabilities=0 - fi - fi - - if [ $capabilities -eq 0 ]; then - # fix apps.plugin to be setuid to root - run chmod 4750 "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/apps.plugin" - fi - fi - - if [ -f "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/freeipmi.plugin" ]; then - run chown "root:${NETDATA_GROUP}" "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/freeipmi.plugin" - run chmod 4750 "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/freeipmi.plugin" - fi - - if [ -f "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/nfacct.plugin" ]; then - run chown "root:${NETDATA_GROUP}" "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/nfacct.plugin" - run chmod 4750 "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/nfacct.plugin" - fi - - if [ -f "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/xenstat.plugin" ]; then - run chown root:${NETDATA_GROUP} "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/xenstat.plugin" - run chmod 4750 "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/xenstat.plugin" - fi - - if [ -f "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/perf.plugin" ]; then - run chown root:${NETDATA_GROUP} "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/perf.plugin" - run chmod 4750 "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/perf.plugin" - fi - - if [ -f "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/slabinfo.plugin" ]; then - run chown root:${NETDATA_GROUP} "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/slabinfo.plugin" - run chmod 4750 "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/slabinfo.plugin" - fi - - if [ -f "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/ioping" ]; then - run chown root:${NETDATA_GROUP} "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/ioping" - run chmod 4750 "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/ioping" - fi - - if [ -f "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/cgroup-network" ]; then - run chown "root:${NETDATA_GROUP}" "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/cgroup-network" - run chmod 4750 "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/cgroup-network" - fi - - if [ -f "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/cgroup-network-helper.sh" ]; then - run chown "root:${NETDATA_GROUP}" "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/cgroup-network-helper.sh" - run chmod 0550 "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/cgroup-network-helper.sh" - fi - + # find the admin group + admin_group= + test -z "${admin_group}" && getent group root > /dev/null 2>&1 && admin_group="root" + test -z "${admin_group}" && getent group daemon > /dev/null 2>&1 && admin_group="daemon" + test -z "${admin_group}" && admin_group="${NETDATA_GROUP}" + + run chown "${NETDATA_USER}:${admin_group}" "${NETDATA_LOG_DIR}" + run chown -R "root:${admin_group}" "${NETDATA_PREFIX}/usr/libexec/netdata" + run find "${NETDATA_PREFIX}/usr/libexec/netdata" -type d -exec chmod 0755 {} \; + run find "${NETDATA_PREFIX}/usr/libexec/netdata" -type f -exec chmod 0644 {} \; + run find "${NETDATA_PREFIX}/usr/libexec/netdata" -type f -a -name \*.plugin -exec chown :${NETDATA_GROUP} {} \; + run find "${NETDATA_PREFIX}/usr/libexec/netdata" -type f -a -name \*.plugin -exec chmod 0750 {} \; + run find "${NETDATA_PREFIX}/usr/libexec/netdata" -type f -a -name \*.sh -exec chmod 0755 {} \; + + if [ -f "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/apps.plugin" ]; then + run chown "root:${NETDATA_GROUP}" "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/apps.plugin" + capabilities=0 + if ! iscontainer && command -v setcap 1> /dev/null 2>&1; then + run chmod 0750 "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/apps.plugin" + if run setcap cap_dac_read_search,cap_sys_ptrace+ep "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/apps.plugin"; then + # if we managed to setcap, but we fail to execute apps.plugin setuid to root + "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/apps.plugin" -t > /dev/null 2>&1 && capabilities=1 || capabilities=0 + fi + fi + + if [ $capabilities -eq 0 ]; then + # fix apps.plugin to be setuid to root + run chmod 4750 "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/apps.plugin" + fi + fi + + if [ -f "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/freeipmi.plugin" ]; then + run chown "root:${NETDATA_GROUP}" "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/freeipmi.plugin" + run chmod 4750 "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/freeipmi.plugin" + fi + + if [ -f "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/nfacct.plugin" ]; then + run chown "root:${NETDATA_GROUP}" "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/nfacct.plugin" + run chmod 4750 "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/nfacct.plugin" + fi + + if [ -f "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/xenstat.plugin" ]; then + run chown root:${NETDATA_GROUP} "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/xenstat.plugin" + run chmod 4750 "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/xenstat.plugin" + fi + + if [ -f "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/perf.plugin" ]; then + run chown root:${NETDATA_GROUP} "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/perf.plugin" + run chmod 4750 "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/perf.plugin" + fi + + if [ -f "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/slabinfo.plugin" ]; then + run chown root:${NETDATA_GROUP} "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/slabinfo.plugin" + run chmod 4750 "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/slabinfo.plugin" + fi + + if [ -f "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/ioping" ]; then + run chown root:${NETDATA_GROUP} "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/ioping" + run chmod 4750 "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/ioping" + fi + + if [ -f "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/ebpf.plugin" ]; then + run chown root:${NETDATA_GROUP} "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/ebpf.plugin" + run chmod 4750 "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/ebpf.plugin" + fi + + if [ -f "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/cgroup-network" ]; then + run chown "root:${NETDATA_GROUP}" "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/cgroup-network" + run chmod 4750 "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/cgroup-network" + fi + + if [ -f "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/cgroup-network-helper.sh" ]; then + run chown "root:${NETDATA_GROUP}" "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/cgroup-network-helper.sh" + run chmod 0750 "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/cgroup-network-helper.sh" + fi else - # non-privileged user installation - run chown "${NETDATA_USER}:${NETDATA_GROUP}" "${NETDATA_LOG_DIR}" - run chown -R "${NETDATA_USER}:${NETDATA_GROUP}" "${NETDATA_PREFIX}/usr/libexec/netdata" - run find "${NETDATA_PREFIX}/usr/libexec/netdata" -type f -exec chmod 0755 {} \; - run find "${NETDATA_PREFIX}/usr/libexec/netdata" -type d -exec chmod 0755 {} \; + # non-privileged user installation + run chown "${NETDATA_USER}:${NETDATA_GROUP}" "${NETDATA_LOG_DIR}" + run chown -R "${NETDATA_USER}:${NETDATA_GROUP}" "${NETDATA_PREFIX}/usr/libexec/netdata" + run find "${NETDATA_PREFIX}/usr/libexec/netdata" -type f -exec chmod 0755 {} \; + run find "${NETDATA_PREFIX}/usr/libexec/netdata" -type d -exec chmod 0755 {} \; fi # ----------------------------------------------------------------------------- +copy_react_dashboard() { + run cp -a $(find ${1} -mindepth 1 -maxdepth 1) "${NETDATA_WEB_DIR}" + run chown -R "${NETDATA_WEB_USER}:${NETDATA_WEB_GROUP}" "${NETDATA_WEB_DIR}" +} + +install_react_dashboard() { + progress "Fetching and installing dashboard" + + DASHBOARD_PACKAGE_VERSION="$(cat packaging/dashboard.version)" + + tmp="$(mktemp -d -t netdata-dashboard-XXXXXX)" + DASHBOARD_PACKAGE_BASENAME="dashboard.tar.gz" + + if fetch_and_verify "dashboard" \ + "https://github.com/netdata/dashboard/releases/download/${DASHBOARD_PACKAGE_VERSION}/${DASHBOARD_PACKAGE_BASENAME}" \ + "${DASHBOARD_PACKAGE_BASENAME}" \ + "${tmp}" \ + "${NETDATA_LOCAL_TARBALL_OVERRIDE_DASHBOARD}"; then + if run tar -xf "${tmp}/${DASHBOARD_PACKAGE_BASENAME}" -C "${tmp}" && + copy_react_dashboard "${tmp}/build" && + rm -rf "${tmp}"; then + run_ok "React dashboard installed." + else + run_failed "Failed to install React dashboard. The install process will continue, but you will not be able to use the new dashboard." + fi + else + run_failed "Unable to fetch React dashboard. The install process will continue, but you will not be able to use the new dashboard." + fi +} + +install_react_dashboard + +# ----------------------------------------------------------------------------- + +# govercomp compares go.d.plugin versions. Exit codes: +# 0 - version1 == version2 +# 1 - version1 > version2 +# 2 - version2 > version1 +# 3 - error +govercomp() { + # version in file: + # - v0.14.0 + # + # 'go.d.plugin -v' output variants: + # - go.d.plugin, version: unknown + # - go.d.plugin, version: v0.14.1 + # - go.d.plugin, version: v0.14.1-dirty + # - go.d.plugin, version: v0.14.1-1-g4c5f98c + # - go.d.plugin, version: v0.14.1-1-g4c5f98c-dirty + + # we need to compare only MAJOR.MINOR.PATCH part + local ver1 ver2 + ver1=$(echo "$1" | grep -E -o "[0-9]+\.[0-9]+\.[0-9]+") + ver2=$(echo "$2" | grep -E -o "[0-9]+\.[0-9]+\.[0-9]+") + + local IFS=. + read -ra ver1 <<< "$ver1" + read -ra ver2 <<< "$ver2" + + if [ ${#ver1[@]} -eq 0 ] || [ ${#ver2[@]} -eq 0 ]; then + return 3 + fi + + local i + for ((i = 0; i < ${#ver1[@]}; i++)); do + if [ "${ver1[i]}" -gt "${ver2[i]}" ]; then + return 1 + elif [ "${ver2[i]}" -gt "${ver1[i]}" ]; then + return 2 + fi + done + + return 0 +} + +should_install_go() { + if [ -n "${NETDATA_DISABLE_GO+x}" ]; then + return 1 + fi + + local version_in_file + local binary_version + + version_in_file="$(cat packaging/go.d.version 2> /dev/null)" + binary_version=$("${NETDATA_PREFIX}"/usr/libexec/netdata/plugins.d/go.d.plugin -v 2> /dev/null) + + govercomp "$version_in_file" "$binary_version" + case $? in + 0) return 1 ;; # = + 2) return 1 ;; # < + *) return 0 ;; # >, error + esac +} + install_go() { - # When updating this value, ensure correct checksums in packaging/go.d.checksums - GO_PACKAGE_VERSION="$(cat packaging/go.d.version)" - ARCH_MAP=( - 'i386::386' - 'i686::386' - 'x86_64::amd64' - 'aarch64::arm64' - 'armv64::arm64' - 'armv6l::arm' - 'armv7l::arm' - 'armv5tel::arm' - ) - - if [ -z "${NETDATA_DISABLE_GO+x}" ]; then - progress "Install go.d.plugin" - ARCH=$(uname -m) - OS=$(uname -s | tr '[:upper:]' '[:lower:]') - - for index in "${ARCH_MAP[@]}" ; do - KEY="${index%%::*}" - VALUE="${index##*::}" - if [ "$KEY" = "$ARCH" ]; then - ARCH="${VALUE}" - break - fi - done - tmp=$(mktemp -d /tmp/netdata-go-XXXXXX) - GO_PACKAGE_BASENAME="go.d.plugin-${GO_PACKAGE_VERSION}.${OS}-${ARCH}.tar.gz" - - if [ -z "${NETDATA_LOCAL_TARBALL_OVERRIDE_GO_PLUGIN}" ]; then - download_go "https://github.com/netdata/go.d.plugin/releases/download/${GO_PACKAGE_VERSION}/${GO_PACKAGE_BASENAME}" "${tmp}/${GO_PACKAGE_BASENAME}" - else - progress "Using provided go.d tarball ${NETDATA_LOCAL_TARBALL_OVERRIDE_GO_PLUGIN}" - run cp "${NETDATA_LOCAL_TARBALL_OVERRIDE_GO_PLUGIN}" "${tmp}/${GO_PACKAGE_BASENAME}" - fi - - if [ -z "${NETDATA_LOCAL_TARBALL_OVERRIDE_GO_PLUGIN_CONFIG}" ]; then - download_go "https://github.com/netdata/go.d.plugin/releases/download/${GO_PACKAGE_VERSION}/config.tar.gz" "${tmp}/config.tar.gz" - else - progress "Using provided config file for go.d ${NETDATA_LOCAL_TARBALL_OVERRIDE_GO_PLUGIN_CONFIG}" - run cp "${NETDATA_LOCAL_TARBALL_OVERRIDE_GO_PLUGIN_CONFIG}" "${tmp}/config.tar.gz" - fi - - if [ ! -f "${tmp}/${GO_PACKAGE_BASENAME}" ] || [ ! -f "${tmp}/config.tar.gz" ] || [ ! -s "${tmp}/config.tar.gz" ] || [ ! -s "${tmp}/${GO_PACKAGE_BASENAME}" ]; then - run_failed "go.d plugin download failed, go.d plugin will not be available" - echo >&2 "Either check the error or consider disabling it by issuing '--disable-go' in the installer" - echo >&2 - return 0 - fi - - grep "${GO_PACKAGE_BASENAME}\$" "${INSTALLER_DIR}/packaging/go.d.checksums" > "${tmp}/sha256sums.txt" 2>/dev/null - grep "config.tar.gz" "${INSTALLER_DIR}/packaging/go.d.checksums" >> "${tmp}/sha256sums.txt" 2>/dev/null - - # Checksum validation - if ! (cd "${tmp}" && safe_sha256sum -c "sha256sums.txt"); then - - echo >&2 "go.d plugin checksum validation failure." - echo >&2 "Either check the error or consider disabling it by issuing '--disable-go' in the installer" - echo >&2 - - run_failed "go.d.plugin package files checksum validation failed." - return 0 - fi - - # Install new files - run rm -rf "${NETDATA_STOCK_CONFIG_DIR}/go.d" - run rm -rf "${NETDATA_STOCK_CONFIG_DIR}/go.d.conf" - run tar -xf "${tmp}/config.tar.gz" -C "${NETDATA_STOCK_CONFIG_DIR}/" - run chown -R "${ROOT_USER}:${NETDATA_GROUP}" "${NETDATA_STOCK_CONFIG_DIR}" - - run tar xf "${tmp}/${GO_PACKAGE_BASENAME}" - run mv "${GO_PACKAGE_BASENAME/\.tar\.gz/}" "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/go.d.plugin" - if [ "${UID}" -eq 0 ]; then - run chown "root:${NETDATA_GROUP}" "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/go.d.plugin" - fi - run chmod 0750 "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/go.d.plugin" - rm -rf "${tmp}" - fi - return 0 + if ! should_install_go; then + return 0 + fi + + # When updating this value, ensure correct checksums in packaging/go.d.checksums + GO_PACKAGE_VERSION="$(cat packaging/go.d.version)" + ARCH_MAP=( + 'i386::386' + 'i686::386' + 'x86_64::amd64' + 'aarch64::arm64' + 'armv64::arm64' + 'armv6l::arm' + 'armv7l::arm' + 'armv5tel::arm' + ) + + progress "Install go.d.plugin" + ARCH=$(uname -m) + OS=$(uname -s | tr '[:upper:]' '[:lower:]') + + for index in "${ARCH_MAP[@]}"; do + KEY="${index%%::*}" + VALUE="${index##*::}" + if [ "$KEY" = "$ARCH" ]; then + ARCH="${VALUE}" + break + fi + done + tmp="$(mktemp -d -t netdata-go-XXXXXX)" + GO_PACKAGE_BASENAME="go.d.plugin-${GO_PACKAGE_VERSION}.${OS}-${ARCH}.tar.gz" + + if [ -z "${NETDATA_LOCAL_TARBALL_OVERRIDE_GO_PLUGIN}" ]; then + download_go "https://github.com/netdata/go.d.plugin/releases/download/${GO_PACKAGE_VERSION}/${GO_PACKAGE_BASENAME}" "${tmp}/${GO_PACKAGE_BASENAME}" + else + progress "Using provided go.d tarball ${NETDATA_LOCAL_TARBALL_OVERRIDE_GO_PLUGIN}" + run cp "${NETDATA_LOCAL_TARBALL_OVERRIDE_GO_PLUGIN}" "${tmp}/${GO_PACKAGE_BASENAME}" + fi + + if [ -z "${NETDATA_LOCAL_TARBALL_OVERRIDE_GO_PLUGIN_CONFIG}" ]; then + download_go "https://github.com/netdata/go.d.plugin/releases/download/${GO_PACKAGE_VERSION}/config.tar.gz" "${tmp}/config.tar.gz" + else + progress "Using provided config file for go.d ${NETDATA_LOCAL_TARBALL_OVERRIDE_GO_PLUGIN_CONFIG}" + run cp "${NETDATA_LOCAL_TARBALL_OVERRIDE_GO_PLUGIN_CONFIG}" "${tmp}/config.tar.gz" + fi + + if [ ! -f "${tmp}/${GO_PACKAGE_BASENAME}" ] || [ ! -f "${tmp}/config.tar.gz" ] || [ ! -s "${tmp}/config.tar.gz" ] || [ ! -s "${tmp}/${GO_PACKAGE_BASENAME}" ]; then + run_failed "go.d plugin download failed, go.d plugin will not be available" + defer_error "go.d plugin download failed, go.d plugin will not be available" + echo >&2 "Either check the error or consider disabling it by issuing '--disable-go' in the installer" + echo >&2 + return 0 + fi + + grep "${GO_PACKAGE_BASENAME}\$" "${INSTALLER_DIR}/packaging/go.d.checksums" > "${tmp}/sha256sums.txt" 2> /dev/null + grep "config.tar.gz" "${INSTALLER_DIR}/packaging/go.d.checksums" >> "${tmp}/sha256sums.txt" 2> /dev/null + + # Checksum validation + if ! (cd "${tmp}" && safe_sha256sum -c "sha256sums.txt"); then + + echo >&2 "go.d plugin checksum validation failure." + echo >&2 "Either check the error or consider disabling it by issuing '--disable-go' in the installer" + echo >&2 + + run_failed "go.d.plugin package files checksum validation failed." + defer_error "go.d.plugin package files checksum validation failed, go.d.plugin will not be available" + return 0 + fi + + # Install new files + run rm -rf "${NETDATA_STOCK_CONFIG_DIR}/go.d" + run rm -rf "${NETDATA_STOCK_CONFIG_DIR}/go.d.conf" + run tar -xf "${tmp}/config.tar.gz" -C "${NETDATA_STOCK_CONFIG_DIR}/" + run chown -R "${ROOT_USER}:${ROOT_GROUP}" "${NETDATA_STOCK_CONFIG_DIR}" + + run tar xf "${tmp}/${GO_PACKAGE_BASENAME}" + run mv "${GO_PACKAGE_BASENAME/\.tar\.gz/}" "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/go.d.plugin" + if [ "${UID}" -eq 0 ]; then + run chown "root:${NETDATA_GROUP}" "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/go.d.plugin" + fi + run chmod 0750 "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/go.d.plugin" + rm -rf "${tmp}" + return 0 } + install_go +function get_kernel_version() { + r="$(uname -r | cut -f 1 -d '-')" + + read -r -a p <<< "$(echo "${r}" | tr '.' ' ')" + + printf "%03d%03d%03d" "${p[0]}" "${p[1]}" "${p[2]}" +} + +function get_rh_version() { + if [ ! -f /etc/redhat-release ]; then + printf "000000000" + return + fi + + r="$(cut -f 4 -d ' ' < /etc/redhat-release)" + + read -r -a p <<< "$(echo "${r}" | tr '.' ' ')" + + printf "%03d%03d%03d" "${p[0]}" "${p[1]}" "${p[2]}" +} + +detect_libc() { + libc= + if ldd --version 2>&1 | grep -q -i glibc; then + echo >&2 " Detected GLIBC" + libc="glibc" + elif ldd --version 2>&1 | grep -q -i 'gnu libc'; then + echo >&2 " Detected GLIBC" + libc="glibc" + elif ldd --version 2>&1 | grep -q -i musl; then + echo >&2 " Detected musl" + libc="musl" + else + echo >&2 " ERROR: Cannot detect a supported libc on your system!" + return 1 + fi + echo "${libc}" + return 0 +} + +should_install_ebpf() { + if [ "${NETDATA_DISABLE_EBPF:=0}" -eq 1 ]; then + run_failed "eBPF explicitly disabled." + defer_error "eBPF explicitly disabled." + return 1 + fi + + if [ "$(uname -s)" != "Linux" ]; then + run_failed "Currently eBPF is only supported on Linux." + defer_error "Currently eBPF is only supported on Linux." + return 1 + fi + + # Check Kernel Config + if ! run "${INSTALLER_DIR}"/packaging/check-kernel-config.sh; then + echo >&2 "Warning: Kernel unsupported or missing required config (eBPF may not work on your system)" + fi + + return 0 +} + +remove_old_ebpf() { + if [ -f "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/ebpf_process.plugin" ]; then + echo >&2 "Removing alpha eBPF collector." + rm -f "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/ebpf_process.plugin" + fi + + if [ -f "${NETDATA_PREFIX}/usr/lib/netdata/conf.d/ebpf_process.conf" ]; then + echo >&2 "Removing alpha eBPF stock file" + rm -f "${NETDATA_PREFIX}/usr/lib/netdata/conf.d/ebpf_process.conf" + fi + + if [ -f "${NETDATA_PREFIX}/etc/netdata/ebpf_process.conf" ]; then + echo >&2 "Renaming eBPF configuration file." + mv "${NETDATA_PREFIX}/etc/netdata/ebpf_process.conf" "${NETDATA_PREFIX}/etc/netdata/ebpf.conf" + fi + + # Added to remove eBPF programs with name pattern: NAME_VERSION.SUBVERSION.PATCH + if [ -f "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/pnetdata_ebpf_process.3.10.0.o" ]; then + echo >&2 "Removing old eBPF programs" + rm -f "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/rnetdata_ebpf"*.?.*.*.o + rm -f "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/pnetdata_ebpf"*.?.*.*.o + fi + +} + +install_ebpf() { + if ! should_install_ebpf; then + return 0 + fi + + remove_old_ebpf + + progress "Installing eBPF plugin" + + # Detect libc + libc="${EBPF_LIBC:-"$(detect_libc)"}" + + EBPF_VERSION="$(cat packaging/ebpf.version)" + EBPF_TARBALL="netdata-kernel-collector-${libc}-${EBPF_VERSION}.tar.xz" + + tmp="$(mktemp -d -t netdata-ebpf-XXXXXX)" + + if ! fetch_and_verify "ebpf" \ + "https://github.com/netdata/kernel-collector/releases/download/${EBPF_VERSION}/${EBPF_TARBALL}" \ + "${EBPF_TARBALL}" \ + "${tmp}" \ + "${NETDATA_LOCAL_TARBALL_OVERRIDE_EBPF}"; then + run_failed "Failed to download eBPF collector package" + echo 2>&" Removing temporary directory ${tmp} ..." + rm -rf "${tmp}" + return 1 + fi + + echo >&2 " Extracting ${EBPF_TARBALL} ..." + tar -xf "${tmp}/${EBPF_TARBALL}" -C "${tmp}" + + # chown everything to root:netdata before we start copying out of our package + run chown -R root:netdata "${tmp}" + + run cp -a -v "${tmp}"/*netdata_ebpf_*.o "${NETDATA_PREFIX}"/usr/libexec/netdata/plugins.d + + rm -rf "${tmp}" + + return 0 +} + +progress "eBPF Kernel Collector" +install_ebpf + # ----------------------------------------------------------------------------- progress "Telemetry configuration" +if [ ! "${DO_NOT_TRACK:-0}" -eq 0 ] || [ -n "$DO_NOT_TRACK" ]; then + NETDATA_DISABLE_TELEMETRY=1 +fi + # Opt-out from telemetry program if [ -n "${NETDATA_DISABLE_TELEMETRY+x}" ]; then - run touch "${NETDATA_USER_CONFIG_DIR}/.opt-out-from-anonymous-statistics" + run touch "${NETDATA_USER_CONFIG_DIR}/.opt-out-from-anonymous-statistics" else - printf "You can opt out from anonymous statistics via the --disable-telemetry option, or by creating an empty file ${NETDATA_USER_CONFIG_DIR}/.opt-out-from-anonymous-statistics \n\n" + printf "You can opt out from anonymous statistics via the --disable-telemetry option, or by creating an empty file %s \n\n" "${NETDATA_USER_CONFIG_DIR}/.opt-out-from-anonymous-statistics" fi # ----------------------------------------------------------------------------- progress "Install netdata at system init" +# By default we assume the shutdown/startup of the Netdata Agent are effectively +# without any system supervisor/init like SystemD or SysV. So we assume the most +# basic startup/shutdown commands... +NETDATA_STOP_CMD="${NETDATA_PREFIX}/usr/sbin/netdatacli shutdown-agent" NETDATA_START_CMD="${NETDATA_PREFIX}/usr/sbin/netdata" -if grep -q docker /proc/1/cgroup >/dev/null 2>&1; then - # If docker runs systemd for some weird reason, let the install proceed - is_systemd_running="NO" - if command -v pidof >/dev/null 2>&1; then - is_systemd_running="$(pidof /usr/sbin/init || pidof systemd || echo "NO")" - else - is_systemd_running="$( (ps -p 1 | grep -q systemd && echo "1") || echo "NO")" - fi - - if [ "${is_systemd_running}" == "1" ]; then - echo >&2 "Found systemd within the docker container, running install_netdata_service() method" - install_netdata_service || run_failed "Cannot install netdata init service." - else - echo >&2 "We are running within a docker container, will not be installing netdata service" - fi - echo >&2 +if grep -q docker /proc/1/cgroup > /dev/null 2>&1; then + # If docker runs systemd for some weird reason, let the install proceed + is_systemd_running="NO" + if command -v pidof > /dev/null 2>&1; then + is_systemd_running="$(pidof /usr/sbin/init || pidof systemd || echo "NO")" + else + is_systemd_running="$( (pgrep -q -f systemd && echo "1") || echo "NO")" + fi + + if [ "${is_systemd_running}" == "1" ]; then + echo >&2 "Found systemd within the docker container, running install_netdata_service() method" + install_netdata_service || run_failed "Cannot install netdata init service." + else + echo >&2 "We are running within a docker container, will not be installing netdata service" + fi + echo >&2 else - install_netdata_service || run_failed "Cannot install netdata init service." + install_netdata_service || run_failed "Cannot install netdata init service." fi # ----------------------------------------------------------------------------- @@ -897,24 +1711,24 @@ fi # TODO(paulfantom): Creation of configuration file should be handled by a build system. Additionally we shouldn't touch configuration files in /etc/netdata/... started=0 if [ ${DONOTSTART} -eq 1 ]; then - create_netdata_conf "${NETDATA_PREFIX}/etc/netdata/netdata.conf" + create_netdata_conf "${NETDATA_PREFIX}/etc/netdata/netdata.conf" else - if ! restart_netdata "${NETDATA_PREFIX}/usr/sbin/netdata" "${@}"; then - fatal "Cannot start netdata!" - fi + if ! restart_netdata "${NETDATA_PREFIX}/usr/sbin/netdata" "${@}"; then + fatal "Cannot start netdata!" + fi - started=1 - run_ok "netdata started!" - create_netdata_conf "${NETDATA_PREFIX}/etc/netdata/netdata.conf" "http://localhost:${NETDATA_PORT}/netdata.conf" + started=1 + run_ok "netdata started!" + create_netdata_conf "${NETDATA_PREFIX}/etc/netdata/netdata.conf" "http://localhost:${NETDATA_PORT}/netdata.conf" fi run chmod 0644 "${NETDATA_PREFIX}/etc/netdata/netdata.conf" if [ "$(uname)" = "Linux" ]; then - # ------------------------------------------------------------------------- - progress "Check KSM (kernel memory deduper)" + # ------------------------------------------------------------------------- + progress "Check KSM (kernel memory deduper)" - ksm_is_available_but_disabled() { - cat <&2 "Removing uninstaller from old location" - rm -f "${NETDATA_PREFIX}"/usr/libexec/netdata-uninstaller.sh; + echo >&2 "Removing uninstaller from old location" + rm -f "${NETDATA_PREFIX}"/usr/libexec/netdata-uninstaller.sh fi sed "s|ENVIRONMENT_FILE=\"/etc/netdata/.environment\"|ENVIRONMENT_FILE=\"${NETDATA_PREFIX}/etc/netdata/.environment\"|" packaging/installer/netdata-uninstaller.sh > ${NETDATA_PREFIX}/usr/libexec/netdata/netdata-uninstaller.sh @@ -1019,7 +1833,7 @@ chmod 750 ${NETDATA_PREFIX}/usr/libexec/netdata/netdata-uninstaller.sh # ----------------------------------------------------------------------------- progress "Basic netdata instructions" -cat <&2 "Preparing .environment file" -cat < "${NETDATA_USER_CONFIG_DIR}/.environment" +cat << EOF > "${NETDATA_USER_CONFIG_DIR}/.environment" # Created by installer PATH="${PATH}" CFLAGS="${CFLAGS}" +LDFLAGS="${LDFLAGS}" +NETDATA_TMPDIR="${TMPDIR}" NETDATA_PREFIX="${NETDATA_PREFIX}" NETDATA_CONFIGURE_OPTIONS="${NETDATA_CONFIGURE_OPTIONS}" NETDATA_ADDED_TO_GROUPS="${NETDATA_ADDED_TO_GROUPS}" INSTALL_UID="${UID}" NETDATA_GROUP="${NETDATA_GROUP}" -REINSTALL_COMMAND="${REINSTALL_COMMAND}" +REINSTALL_OPTIONS="${REINSTALL_OPTIONS}" RELEASE_CHANNEL="${RELEASE_CHANNEL}" IS_NETDATA_STATIC_BINARY="${IS_NETDATA_STATIC_BINARY}" NETDATA_LIB_DIR="${NETDATA_LIB_DIR}" @@ -1073,18 +1888,20 @@ EOF run chmod 0644 "${NETDATA_USER_CONFIG_DIR}/.environment" echo >&2 "Setting netdata.tarball.checksum to 'new_installation'" -cat < "${NETDATA_LIB_DIR}/netdata.tarball.checksum" +cat << EOF > "${NETDATA_LIB_DIR}/netdata.tarball.checksum" new_installation EOF +print_deferred_errors + # ----------------------------------------------------------------------------- echo >&2 progress "We are done!" if [ ${started} -eq 1 ]; then - netdata_banner "is installed and running now!" + netdata_banner "is installed and running now!" else - netdata_banner "is installed now!" + netdata_banner "is installed now!" fi echo >&2 " enjoy real-time performance and health monitoring..." -- cgit v1.2.3