diff options
Diffstat (limited to 'packaging/installer')
-rw-r--r-- | packaging/installer/REINSTALL.md | 42 | ||||
-rw-r--r-- | packaging/installer/UNINSTALL.md | 18 | ||||
-rwxr-xr-x | packaging/installer/dependencies/centos.sh | 20 | ||||
-rw-r--r-- | packaging/installer/functions.sh | 89 | ||||
-rwxr-xr-x | packaging/installer/install-required-packages.sh | 55 | ||||
-rwxr-xr-x | packaging/installer/kickstart.sh | 792 | ||||
-rw-r--r-- | packaging/installer/methods/kickstart.md | 17 | ||||
-rw-r--r-- | packaging/installer/methods/macos.md | 2 | ||||
-rw-r--r-- | packaging/installer/methods/offline.md | 84 | ||||
-rwxr-xr-x | packaging/installer/netdata-uninstaller.sh | 114 | ||||
-rwxr-xr-x | packaging/installer/netdata-updater.sh | 129 |
11 files changed, 939 insertions, 423 deletions
diff --git a/packaging/installer/REINSTALL.md b/packaging/installer/REINSTALL.md index ddfc8bcb..1356c70d 100644 --- a/packaging/installer/REINSTALL.md +++ b/packaging/installer/REINSTALL.md @@ -11,8 +11,11 @@ Netdata Agent on your node. ## One-line installer script (`kickstart.sh`) +### Reinstalling with the same install type + Run the one-line installer script with the `--reinstall` parameter to reinstall the Netdata Agent. This will preserve -any [user configuration](/docs/configure/nodes.md) in `netdata.conf` or other files. +any [user configuration](/docs/configure/nodes.md) in `netdata.conf` or other files, and will keep the same install +type that was used for the original install. If you used any [optional parameters](/packaging/installer/methods/kickstart.md#optional-parameters-to-alter-your-installation) during initial @@ -24,6 +27,41 @@ optional parameters. wget -O /tmp/netdata-kickstart.sh https://my-netdata.io/kickstart.sh && sh /tmp/netdata-kickstart.sh --reinstall ``` +### Performing a clean reinstall + +Run the one-line installer script with the `--reinstall-clean` parameter to perform a clean reinstall of the +Netdata Agent. This will wipe all existing configuration and historical data, but can be useful sometimes for +getting a badly broken installation working again. Unlike the regular `--reinstall` parameter, this may use a +different install type than the original install used. + +If you used any [optional +parameters](/packaging/installer/methods/kickstart.md#optional-parameters-to-alter-your-installation) during initial +installation, you need to pass them to the script again during reinstallation. If you cannot remember which options you +used, read the contents of the `.environment` file and look for a `REINSTALL_OPTIONS` line. This line contains a list of +optional parameters. + +```bash +wget -O /tmp/netdata-kickstart.sh https://my-netdata.io/kickstart.sh && sh /tmp/netdata-kickstart.sh --reinstall-clean +``` + +### Changing the install type of an existing installation + +The clean reinstall procedure outlined above can also be used to manually change the install type for an existing +installation. Without any extra parameters, it will automatically pick the preferred installation type for your +system, even if that has changed since the original install. If you want to force use of a specific install type, +you can use the `--native-only`, `--static-only`, or `--build-only` parameter to control which install type gets +used, just like with a new install. + +When using the `--reinstall-clean` option to change the install type, you will need to manually preserve any +configuration or historical data you want to keep. The following directories may need to be preserved: + +- `/etc/netdata` (`/opt/netdata/etc/netdata` for static installs): For agent configuration. +- `/var/lib/netdata` (`/opt/netdata/var/lib/netdata` for static installs): For claiming configuration. +- `/var/cache/netdata` (`/opt/netdata/var/cache/netdata` for static installs): For historical data. + +When copying these directories back after the reinstall, you may need to update file ownership by running `chown +-R netdata:netdata` on them. + ## Troubleshooting If you still experience problems with your Netdata Agent installation after following one of these processes, the next @@ -32,5 +70,3 @@ installer](/packaging/installer/methods/kickstart.md). You can also post to our [community forums](https://community.netdata.cloud/c/support/13) or create a new [bug report](https://github.com/netdata/netdata/issues/new?assignees=&labels=bug%2Cneeds+triage&template=BUG_REPORT.yml). - - diff --git a/packaging/installer/UNINSTALL.md b/packaging/installer/UNINSTALL.md index 87c76ca6..54ca771f 100644 --- a/packaging/installer/UNINSTALL.md +++ b/packaging/installer/UNINSTALL.md @@ -33,9 +33,21 @@ NETDATA_ADDED_TO_GROUPS="<additional groups>" # Additional groups for a user ru 3. Run `netdata-uninstaller.sh` as follows -```sh -${NETDATA_PREFIX}/usr/libexec/netdata/netdata-uninstaller.sh --yes --env <environment_file> -``` + 3.1 **Interactive mode (Default)** + + The default mode in the uninstaller script is **interactive**. This means that the script provides the user the option to reply with "yes" (`y`/`Y`) or "no" (`n`/`N`) to control the removal of each Netdata asset in the filesystem. + + ```sh + ${NETDATA_PREFIX}/usr/libexec/netdata/netdata-uninstaller.sh --yes --env <environment_file> + ``` + + 3.2 **Non-interactive mode** + + If you are sure and you know what you are doing, you can speed up the removal of the Netdata assets from the filesystem without any questions by using the force option (`-f`/`--force`). This option will remove all the Netdata assets in a **non-interactive** mode. + + ```sh + ${NETDATA_PREFIX}/usr/libexec/netdata/netdata-uninstaller.sh --yes --force --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: diff --git a/packaging/installer/dependencies/centos.sh b/packaging/installer/dependencies/centos.sh index 738a0ce7..eea71ca3 100755 --- a/packaging/installer/dependencies/centos.sh +++ b/packaging/installer/dependencies/centos.sh @@ -10,7 +10,6 @@ declare -a package_tree=( make autoconf autoconf-archive - autogen automake libatomic libtool @@ -106,7 +105,22 @@ validate_tree_centos() { echo >&2 " > CentOS Version: $(os_version) ..." - if [[ $(os_version) =~ ^8(\..*)?$ ]]; then + if [[ $(os_version) =~ ^9(\..*)?$ ]]; then + package_manager=dnf + echo >&2 " > Checking for config-manager ..." + if ! dnf config-manager --help &> /dev/null; then + if prompt "config-manager not found, shall I install it?"; then + dnf ${opts} install 'dnf-command(config-manager)' + fi + fi + + echo >&2 " > Checking for CRB ..." + if ! dnf repolist | grep CRB; then + if prompt "CRB not found, shall I install it?"; then + dnf ${opts} config-manager --set-enabled crb + fi + fi + elif [[ $(os_version) =~ ^8(\..*)?$ ]]; then package_manager=dnf echo >&2 " > Checking for config-manager ..." if ! dnf config-manager --help &> /dev/null; then @@ -128,7 +142,7 @@ validate_tree_centos() { echo >&2 " > Installing Judy-devel directly ..." dnf ${opts} install http://mirror.centos.org/centos/8/PowerTools/x86_64/os/Packages/Judy-devel-1.0.5-18.module_el8.3.0+757+d382997d.x86_64.rpm dnf makecache --refresh -elif [[ $(os_version) =~ ^7(\..*)?$ ]]; then + elif [[ $(os_version) =~ ^7(\..*)?$ ]]; then package_manager=yum echo >&2 " > Checking for EPEL ..." if ! rpm -qa | grep epel-release > /dev/null; then diff --git a/packaging/installer/functions.sh b/packaging/installer/functions.sh index 471e6457..fe2fed78 100644 --- a/packaging/installer/functions.sh +++ b/packaging/installer/functions.sh @@ -2,6 +2,8 @@ # SPDX-License-Identifier: GPL-3.0-or-later +# next unused error code: L0003 + # make sure we have a UID [ -z "${UID}" ] && UID="$(id -u)" # ----------------------------------------------------------------------------- @@ -42,6 +44,7 @@ setup_terminal() { TPUT_RESET="$(tput sgr 0)" # shellcheck disable=SC2034 TPUT_BLACK="$(tput setaf 0)" + # shellcheck disable=SC2034 TPUT_RED="$(tput setaf 1)" TPUT_GREEN="$(tput setaf 2)" # shellcheck disable=SC2034 @@ -99,7 +102,7 @@ get() { elif command -v wget > /dev/null 2>&1; then wget -T 15 -O - "${url}" else - fatal "I need curl or wget to proceed, but neither is available on this system." + fatal "I need curl or wget to proceed, but neither is available on this system." "L0002" fi } @@ -245,17 +248,43 @@ find_processors() { } # ----------------------------------------------------------------------------- +exit_reason() { + if [ -n "${NETDATA_SAVE_WARNINGS}" ]; then + EXIT_REASON="${1}" + EXIT_CODE="${2}" + if [ -n "${NETDATA_PROPAGATE_WARNINGS}" ]; then + export EXIT_REASON + export EXIT_CODE + export NETDATA_WARNINGS="${NETDATA_WARNINGS}${SAVED_WARNINGS}" + fi + fi +} + fatal() { - printf >&2 "%s ABORTED %s %s \n\n" "${TPUT_BGRED}${TPUT_WHITE}${TPUT_BOLD}" "${TPUT_RESET}" "${*}" + printf >&2 "%s ABORTED %s %s \n\n" "${TPUT_BGRED}${TPUT_WHITE}${TPUT_BOLD}" "${TPUT_RESET}" "${1}" + if [ -n "${NETDATA_SAVE_WARNINGS}" ]; then + SAVED_WARNINGS="${SAVED_WARNINGS}\n - ${1}" + fi + exit_reason "${1}" "${2}" exit 1 } +warning() { + printf >&2 "%s WARNING %s %s\n\n" "${TPUT_BGYELLOW}${TPUT_BLACK}${TPUT_BOLD}" "${TPUT_RESET}" "${1}" + if [ -n "${NETDATA_SAVE_WARNINGS}" ]; then + SAVED_WARNINGS="${SAVED_WARNINGS}\n - ${1}" + fi +} + run_ok() { - printf >&2 "%s OK %s %s \n\n" "${TPUT_BGGREEN}${TPUT_WHITE}${TPUT_BOLD}" "${TPUT_RESET}" "${*}" + printf >&2 "%s OK %s %s\n\n" "${TPUT_BGGREEN}${TPUT_WHITE}${TPUT_BOLD}" "${TPUT_RESET}" "${1:-''}" } run_failed() { - printf >&2 "%s FAILED %s %s \n\n" "${TPUT_BGRED}${TPUT_WHITE}${TPUT_BOLD}" "${TPUT_RESET}" "${*}" + printf >&2 "%s FAILED %s %s\n\n" "${TPUT_BGRED}${TPUT_WHITE}${TPUT_BOLD}" "${TPUT_RESET}" "${1:-''}" + if [ -n "${NETDATA_SAVE_WARNINGS}" ] && [ -n "${1:-''}" ]; then + SAVED_WARNINGS="${SAVED_WARNINGS}\n - ${1}" + fi } ESCAPED_PRINT_METHOD= @@ -299,6 +328,9 @@ run() { if [ ${ret} -ne 0 ]; then run_failed printf >> "${run_logfile}" "FAILED with exit code %s\n" "${ret}" + if [ -n "${NETDATA_SAVE_WARNINGS}" ]; then + SAVED_WARNINGS="${SAVED_WARNINGS}\n - Command '${*}' failed with exit code ${ret}." + fi else run_ok printf >> "${run_logfile}" "OK\n" @@ -430,14 +462,14 @@ install_non_systemd_init() { run chkconfig netdata on && return 0 else - echo >&2 "I don't know what init file to install on system '${key}'. Open a github issue to help us fix it." + warning "Could not determine what type of init script to install on this system." return 1 fi elif [ -f /etc/init.d/netdata ]; then echo >&2 "file '/etc/init.d/netdata' already exists." return 0 else - echo >&2 "I don't know what init file to install on system '${key}'. Open a github issue to help us fix it." + warning "Could not determine what type of init script to install on this system." fi return 1 @@ -507,7 +539,7 @@ install_netdata_service() { ${ENABLE_NETDATA_IF_PREVIOUSLY_ENABLED} && return 0 else - echo >&2 "no systemd directory; cannot install netdata.service" + warning "Could not find a systemd service directory, unable to install Netdata systemd service." fi else install_non_systemd_init @@ -559,7 +591,7 @@ stop_netdata_on_pid() { printf >&2 "Stopping netdata on pid %s ..." "${pid}" while [ -n "${pid}" ] && [ ${ret} -eq 0 ]; do if [ ${count} -gt 24 ]; then - echo >&2 "Cannot stop the running netdata on pid ${pid}." + warning "Cannot stop netdata agent with PID ${pid}." return 1 fi @@ -584,7 +616,7 @@ stop_netdata_on_pid() { echo >&2 if [ ${ret} -eq 0 ]; then - echo >&2 "SORRY! CANNOT STOP netdata ON PID ${pid} !" + warning "Failed to stop netdata agent process with PID ${pid}." return 1 fi @@ -608,39 +640,46 @@ netdata_pids() { } stop_all_netdata() { + stop_success=0 if [ "${UID}" -eq 0 ]; then - uname="$(uname 2> /dev/null)" + uname="$(uname 2>/dev/null)" # Any of these may fail, but we need to not bail if they do. if issystemd; then if systemctl stop netdata; then + stop_success=1 sleep 5 fi elif [ "${uname}" = "Darwin" ]; then if launchctl stop netdata; then + stop_success=1 sleep 5 fi elif [ "${uname}" = "FreeBSD" ]; then if /etc/rc.d/netdata stop; then + stop_success=1 sleep 5 fi else if service netdata stop; then + stop_success=1 sleep 5 fi fi fi - if [ -n "$(netdata_pids)" ] && [ -n "$(command -v netdatacli)" ]; then - netdatacli shutdown-agent - sleep 20 - fi + if [ "$stop_success" = "0" ]; then + if [ -n "$(netdata_pids)" ] && [ -n "$(command -v netdatacli)" ]; then + netdatacli shutdown-agent + sleep 20 + fi - for p in $(netdata_pids); do - # shellcheck disable=SC2086 - stop_netdata_on_pid ${p} - done + for p in $(netdata_pids); do + # shellcheck disable=SC2086 + stop_netdata_on_pid ${p} + done + fi } # ----------------------------------------------------------------------------- @@ -687,7 +726,7 @@ restart_netdata() { if [ ${started} -eq 0 ]; then # still not started... another forced attempt, just run the binary - echo >&2 "Netdata service still not started, attempting another forced restart by running '${netdata} ${*}'" + warning "Netdata service still not started, attempting another forced restart by running '${netdata} ${*}'" run stop_all_netdata run "${netdata}" "${@}" return $? @@ -798,7 +837,7 @@ portable_add_user() { run sysadminctl -addUser "${username}" && return 0 fi - echo >&2 "Failed to add ${username} user account !" + warning "Failed to add ${username} user account!" return 1 } @@ -834,7 +873,7 @@ portable_add_group() { dseditgroup -o create "${groupname}" && return 0 fi - echo >&2 "Failed to add ${groupname} user group !" + warning >&2 "Failed to add ${groupname} user group !" return 1 } @@ -845,7 +884,8 @@ portable_add_user_to_group() { # 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 + # Don’t treat this as a failure, if the group does not exist we should not be trying to add the user to it. + return 0 fi # Check if user is in group @@ -876,7 +916,8 @@ portable_add_user_to_group() { if command -v dseditgroup 1> /dev/null 2>&1; then dseditgroup -u "${username}" "${groupname}" && return 0 fi - echo >&2 "Failed to add user ${username} to group ${groupname} !" + + warning >&2 "Failed to add user ${username} to group ${groupname}!" return 1 fi } @@ -889,7 +930,7 @@ safe_sha256sum() { elif command -v shasum > /dev/null 2>&1; then shasum -a 256 "$@" else - fatal "I could not find a suitable checksum binary to use" + fatal "I could not find a suitable checksum binary to use" "L0001" fi } diff --git a/packaging/installer/install-required-packages.sh b/packaging/installer/install-required-packages.sh index 7bfbeaaf..8855aceb 100755 --- a/packaging/installer/install-required-packages.sh +++ b/packaging/installer/install-required-packages.sh @@ -18,7 +18,6 @@ fi # These options control which packages we are going to install # They can be pre-set, but also can be controlled with command line options PACKAGES_NETDATA=${PACKAGES_NETDATA-1} -PACKAGES_NETDATA_NODEJS=${PACKAGES_NETDATA_NODEJS-0} PACKAGES_NETDATA_PYTHON=${PACKAGES_NETDATA_PYTHON-0} PACKAGES_NETDATA_PYTHON3=${PACKAGES_NETDATA_PYTHON3-1} PACKAGES_NETDATA_PYTHON_MYSQL=${PACKAGES_NETDATA_PYTHON_MYSQL-0} @@ -103,10 +102,7 @@ Supported packages (you can append many of them): node.js, python, sensors, etc - netdata minimum packages required to install netdata - (no mysql client, no nodejs, includes python) - - - nodejs install nodejs - (required for monitoring named and SNMP) + (no mysql client, includes python) - python install python @@ -664,6 +660,8 @@ declare -A pkg_autogen=( # exceptions ['centos-6']="WARNING|" ['rhel-6']="WARNING|" + ['centos-9']="NOTREQUIRED|" + ['rhel-9']="NOTREQUIRED|" ) declare -A pkg_automake=( @@ -930,20 +928,6 @@ declare -A pkg_nginx=( ['default']="nginx" ) -declare -A pkg_nodejs=( - ['gentoo']="net-libs/nodejs" - ['clearlinux']="nodejs-basic" - ['freebsd']="node" - ['default']="nodejs" - - # exceptions - ['rhel-6']="WARNING|To install nodejs check: https://nodejs.org/en/download/package-manager/" - ['rhel-7']="WARNING|To install nodejs check: https://nodejs.org/en/download/package-manager/" - ['centos-6']="WARNING|To install nodejs check: https://nodejs.org/en/download/package-manager/" - ['debian-6']="WARNING|To install nodejs check: https://nodejs.org/en/download/package-manager/" - ['debian-7']="WARNING|To install nodejs check: https://nodejs.org/en/download/package-manager/" -) - declare -A pkg_postfix=( ['gentoo']="mail-mta/postfix" ['macos']="WARNING|" @@ -1448,13 +1432,6 @@ packages() { fi # ------------------------------------------------------------------------- - # scripting interpreters for netdata plugins - - if [ "${PACKAGES_NETDATA_NODEJS}" -ne 0 ]; then - require_cmd nodejs node js || suitable_package nodejs - fi - - # ------------------------------------------------------------------------- # python2 if [ "${PACKAGES_NETDATA_PYTHON}" -ne 0 ]; then @@ -1626,7 +1603,21 @@ validate_tree_centos() { echo >&2 " > CentOS Version: ${version} ..." - if [[ "${version}" =~ ^8(\..*)?$ ]]; then + if [[ "${version}" =~ ^9(\..*)?$ ]]; then + echo >&2 " > Checking for config-manager ..." + if ! run ${sudo} dnf config-manager --help; then + if prompt "config-manager not found, shall I install it?"; then + run ${sudo} dnf ${opts} install 'dnf-command(config-manager)' + fi + fi + + echo >&2 " > Checking for CRB ..." + if ! run dnf ${sudo} repolist | grep CRB; then + if prompt "CRB not found, shall I install it?"; then + run ${sudo} dnf ${opts} config-manager --set-enabled crb + fi + fi + elif [[ "${version}" =~ ^8(\..*)?$ ]]; then echo >&2 " > Checking for config-manager ..." if ! run ${sudo} yum config-manager --help; then if prompt "config-manager not found, shall I install it?"; then @@ -2001,7 +1992,7 @@ EOF remote_log() { # log success or failure on our system # to help us solve installation issues - curl > /dev/null 2>&1 -Ss --max-time 3 "https://registry.my-netdata.io/log/installer?status=${1}&error=${2}&distribution=${distribution}&version=${version}&installer=${package_installer}&tree=${tree}&detection=${detection}&netdata=${PACKAGES_NETDATA}&nodejs=${PACKAGES_NETDATA_NODEJS}&python=${PACKAGES_NETDATA_PYTHON}&python3=${PACKAGES_NETDATA_PYTHON3}&mysql=${PACKAGES_NETDATA_PYTHON_MYSQL}&postgres=${PACKAGES_NETDATA_PYTHON_POSTGRES}&pymongo=${PACKAGES_NETDATA_PYTHON_MONGO}&sensors=${PACKAGES_NETDATA_SENSORS}&database=${PACKAGES_NETDATA_DATABASE}&ebpf=${PACKAGES_NETDATA_EBPF}&firehol=${PACKAGES_FIREHOL}&fireqos=${PACKAGES_FIREQOS}&iprange=${PACKAGES_IPRANGE}&update_ipsets=${PACKAGES_UPDATE_IPSETS}&demo=${PACKAGES_NETDATA_DEMO_SITE}" + curl > /dev/null 2>&1 -Ss --max-time 3 "https://registry.my-netdata.io/log/installer?status=${1}&error=${2}&distribution=${distribution}&version=${version}&installer=${package_installer}&tree=${tree}&detection=${detection}&netdata=${PACKAGES_NETDATA}&python=${PACKAGES_NETDATA_PYTHON}&python3=${PACKAGES_NETDATA_PYTHON3}&mysql=${PACKAGES_NETDATA_PYTHON_MYSQL}&postgres=${PACKAGES_NETDATA_PYTHON_POSTGRES}&pymongo=${PACKAGES_NETDATA_PYTHON_MONGO}&sensors=${PACKAGES_NETDATA_SENSORS}&database=${PACKAGES_NETDATA_DATABASE}&ebpf=${PACKAGES_NETDATA_EBPF}&firehol=${PACKAGES_FIREHOL}&fireqos=${PACKAGES_FIREQOS}&iprange=${PACKAGES_IPRANGE}&update_ipsets=${PACKAGES_UPDATE_IPSETS}&demo=${PACKAGES_NETDATA_DEMO_SITE}" } if [ -z "${1}" ]; then @@ -2062,7 +2053,6 @@ while [ -n "${1}" ]; do netdata-all) PACKAGES_NETDATA=1 - PACKAGES_NETDATA_NODEJS=1 if [ "${pv}" -eq 2 ]; then PACKAGES_NETDATA_PYTHON=1 PACKAGES_NETDATA_PYTHON_MYSQL=1 @@ -2124,12 +2114,6 @@ while [ -n "${1}" ]; do fi ;; - nodejs | netdata-nodejs) - PACKAGES_NETDATA=1 - PACKAGES_NETDATA_NODEJS=1 - PACKAGES_NETDATA_DATABASE=1 - ;; - sensors | netdata-sensors) PACKAGES_NETDATA=1 PACKAGES_NETDATA_PYTHON3=1 @@ -2147,7 +2131,6 @@ while [ -n "${1}" ]; do demo | all) PACKAGES_NETDATA=1 - PACKAGES_NETDATA_NODEJS=1 if [ "${pv}" -eq 2 ]; then PACKAGES_NETDATA_PYTHON=1 PACKAGES_NETDATA_PYTHON_MYSQL=1 diff --git a/packaging/installer/kickstart.sh b/packaging/installer/kickstart.sh index ffc95155..a1079c3f 100755 --- a/packaging/installer/kickstart.sh +++ b/packaging/installer/kickstart.sh @@ -1,24 +1,30 @@ #!/bin/sh # # SPDX-License-Identifier: GPL-3.0-or-later +# +# Next unused error code: F050A # ====================================================================== # Constants AGENT_BUG_REPORT_URL="https://github.com/netdata/netdata/issues/new/choose" CLOUD_BUG_REPORT_URL="https://github.com/netdata/netdata-cloud/issues/new/choose" -DISCUSSIONS_URL="https://github.com/netdata/netdata/discussions" +DEFAULT_RELEASE_CHANNEL="nightly" DISCORD_INVITE="https://discord.gg/5ygS846fR6" +DISCUSSIONS_URL="https://github.com/netdata/netdata/discussions" +DISCUSSIONS_URL="https://github.com/netdata/netdata/discussions" DOCS_URL="https://learn.netdata.cloud/docs/" FORUM_URL="https://community.netdata.cloud/" KICKSTART_OPTIONS="${*}" +KICKSTART_SOURCE="$(realpath "$0")" PACKAGES_SCRIPT="https://raw.githubusercontent.com/netdata/netdata/master/packaging/installer/install-required-packages.sh" PATH="${PATH}:/usr/local/bin:/usr/local/sbin" PUBLIC_CLOUD_URL="https://app.netdata.cloud" REPOCONFIG_URL_PREFIX="https://packagecloud.io/netdata/netdata-repoconfig/packages" REPOCONFIG_VERSION="1-1" -TELEMETRY_URL="https://posthog.netdata.cloud/capture/" START_TIME="$(date +%s)" +STATIC_INSTALL_ARCHES="x86_64 armv7l aarch64 ppc64le" +TELEMETRY_URL="https://posthog.netdata.cloud/capture/" # ====================================================================== # Defaults for environment variables @@ -27,16 +33,17 @@ DRY_RUN=0 SELECTED_INSTALL_METHOD="none" INSTALL_TYPE="unknown" INSTALL_PREFIX="" -NETDATA_AUTO_UPDATES="1" +NETDATA_AUTO_UPDATES="default" NETDATA_CLAIM_ONLY=0 NETDATA_CLAIM_URL="${PUBLIC_CLOUD_URL}" NETDATA_DISABLE_CLOUD=0 NETDATA_ONLY_BUILD=0 NETDATA_ONLY_NATIVE=0 NETDATA_ONLY_STATIC=0 +NETDATA_OFFLINE_INSTALL_SOURCE="" NETDATA_REQUIRE_CLOUD=1 -RELEASE_CHANNEL="nightly" -WARNINGS="" +NETDATA_WARNINGS="" +RELEASE_CHANNEL="default" if [ -n "$DISABLE_TELEMETRY" ]; then NETDATA_DISABLE_TELEMETRY="${DISABLE_TELEMETRY}" @@ -60,33 +67,54 @@ else INTERACTIVE=1 fi +# ====================================================================== +# Core program logic + main() { - if [ "${ACTION}" = "uninstall" ]; then - uninstall - printf >&2 "Finished uninstalling the Netdata Agent." - deferred_warnings - cleanup - trap - EXIT - exit 0 - fi + case "${ACTION}" in + uninstall) + uninstall + printf >&2 "Finished uninstalling the Netdata Agent." + deferred_warnings + cleanup + trap - EXIT + exit 0 + ;; + reinstall-clean) + NEW_INSTALL_PREFIX="${INSTALL_PREFIX}" + uninstall + cleanup - if [ "${ACTION}" = "reinstall-clean" ]; then - NEW_INSTALL_PREFIX="${INSTALL_PREFIX}" - uninstall - cleanup + ACTION= + INSTALL_PREFIX="${NEW_INSTALL_PREFIX}" + # shellcheck disable=SC2086 + main - ACTION= - INSTALL_PREFIX="${NEW_INSTALL_PREFIX}" - # shellcheck disable=SC2086 - main + trap - EXIT + exit 0 + ;; + prepare-offline) + prepare_offline_install_source "${OFFLINE_TARGET}" + deferred_warnings + trap - EXIT + exit 0 + ;; + esac - trap - EXIT - exit 0 - fi + set_tmpdir + + if [ -n "${INSTALL_VERSION}" ]; then + if echo "${INSTALL_VERSION}" | grep -E -o "^[[:digit:]]+\.[[:digit:]]+\.[[:digit:]]+$" > /dev/null 2>&1; then + NEW_SELECTED_RELEASE_CHANNEL="stable" + else + NEW_SELECTED_RELEASE_CHANNEL="nightly" + fi - tmpdir="$(create_tmp_directory)" - progress "Using ${tmpdir} as a temporary directory." - cd "${tmpdir}" || fatal "Failed to change current working directory to ${tmpdir}." F000A + if ! [ "${NEW_SELECTED_RELEASE_CHANNEL}" = "${SELECTED_RELEASE_CHANNEL}" ]; then + warning "Selected release channel does not match this version and it will be changed automatically." + SELECTED_RELEASE_CHANNEL="${NEW_SELECTED_RELEASE_CHANNEL}" + fi + fi case "${SYSTYPE}" in Linux) install_on_linux ;; @@ -118,32 +146,39 @@ usage() { USAGE: kickstart.sh [options] where options include: - --non-interactive Do not prompt for user input. (default: prompt if there is a controlling terminal) - --interactive Prompt for user input even if there is no controlling terminal. - --dont-start-it Do not start the agent by default (only for static installs or local builds) - --dry-run Report what we would do with the given options on this system, but don’t actually do anything. - --stable-channel Install a stable version instead of a nightly build (default: install a nightly build) - --nightly-channel Install a nightly build instead of a stable version - --no-updates Do not enable automatic updates (default: enable automatic updates using the best supported scheduling method) - --auto-update Enable automatic updates. - --auto-update-type Specify a particular scheduling type for auto-updates (valid types: systemd, interval, crontab) - --disable-telemetry Opt-out of anonymous statistics. - --native-only Only install if native binary packages are available. - --static-only Only install if a static build is available. - --build-only Only install using a local build. - --reinstall Explicitly reinstall instead of updating any existing install. - --reinstall-even-if-unsafe Even try to reinstall if we don't think we can do so safely (implies --reinstall). - --disable-cloud Disable support for Netdata Cloud (default: detect) - --require-cloud Only install if Netdata Cloud can be enabled. Overrides --disable-cloud. - --install <path> Specify an installation prefix for local builds (default: autodetect based on system type). - --old-install-prefix <path> Specify an old local builds installation prefix for uninstall/reinstall (if it's not default). - --claim-token Use a specified token for claiming to Netdata Cloud. - --claim-rooms When claiming, add the node to the specified rooms. - --claim-only If there is an existing install, only try to claim it, not update it. - --claim-* Specify other options for the claiming script. - --no-cleanup Don't do any cleanup steps. This is intended to help with debugging the installer. - --uninstall Uninstall an existing installation of Netdata. - --reinstall-clean Clean reinstall Netdata. + --non-interactive Do not prompt for user input. (default: prompt if there is a controlling terminal) + --interactive Prompt for user input even if there is no controlling terminal. + --dont-start-it Do not start the agent by default (only for static installs or local builds) + --dry-run Report what we would do with the given options on this system, but don’t actually do anything. + --release-channel Specify the release channel to use for the install (default: ${DEFAULT_RELEASE_CHANNEL}) + --stable-channel Equivalent to "--release-channel stable" + --nightly-channel Equivalent to "--release-channel nightly" + --no-updates Do not enable automatic updates (default: enable automatic updates using the best supported scheduling method) + --auto-update Enable automatic updates. + --auto-update-type Specify a particular scheduling type for auto-updates (valid types: systemd, interval, crontab) + --disable-telemetry Opt-out of anonymous statistics. + --repositories-only Only install appropriate repository configuration packages (only for native install). + --native-only Only install if native binary packages are available. + --static-only Only install if a static build is available. + --build-only Only install using a local build. + --reinstall Explicitly reinstall instead of updating any existing install. + --reinstall-even-if-unsafe Even try to reinstall if we don't think we can do so safely (implies --reinstall). + --disable-cloud Disable support for Netdata Cloud (default: detect) + --require-cloud Only install if Netdata Cloud can be enabled. Overrides --disable-cloud. + --install <path> This option is deprecated and will be removed in a future version, use --install-prefix instead. + --install-prefix <path> Specify an installation prefix for local builds (default: autodetect based on system type). + --old-install-prefix <path> Specify an old local builds installation prefix for uninstall/reinstall (if it's not default). + --install-version <version> Specify the version of Netdata to install. + --claim-token Use a specified token for claiming to Netdata Cloud. + --claim-rooms When claiming, add the node to the specified rooms. + --claim-only If there is an existing install, only try to claim it, not update it. + --claim-* Specify other options for the claiming script. + --no-cleanup Don't do any cleanup steps. This is intended to help with debugging the installer. + --uninstall Uninstall an existing installation of Netdata. + --reinstall-clean Clean reinstall Netdata. + --local-build-options Specify additional options to pass to the installer code when building locally. Only valid if --build-only is also specified. + --static-install-options Specify additional options to pass to the static installer code. Only valid if --static-only is also specified. + --prepare-offline-install-source Instead of installing the agent, prepare a directory that can be used to install on another system without needing to download anything. Additionally, this script may use the following environment variables: @@ -155,7 +190,6 @@ Additionally, this script may use the following environment variables: you need special options for one of those to work, or have a different tool to do the same thing on your system, you can specify it here. DISABLE_TELEMETRY If set to a value other than 0, behave as if \`--disable-telemetry\` was specified. - NETDATA_INSTALLER_OPTIONS: Specifies extra options to pass to the static installer or local build script. HEREDOC } @@ -222,6 +256,7 @@ telemetry_event() { "error_message": "${2}", "install_options": "${KICKSTART_OPTIONS}", "install_interactivity": "${INTERACTIVE}", + "install_auto_updates": "${NETDATA_AUTO_UPDATES}", "total_runtime": "${total_duration}", "selected_install_method": "${SELECTED_INSTALL_METHOD}", "netdata_release_channel": "${RELEASE_CHANNEL:-null}", @@ -302,7 +337,7 @@ setup_terminal() { test -t 2 || return 1 if command -v tput > /dev/null 2>&1; then - if [ $(($(tput colors 2> /dev/null))) -ge 8 ]; then + if num_colors=$(tput colors 2> /dev/null) && [ "${num_colors:-0}" -ge 8 ]; then # Enable colors TPUT_RESET="$(tput sgr 0)" TPUT_WHITE="$(tput setaf 7)" @@ -336,16 +371,18 @@ success_banner() { } cleanup() { - if [ -z "${NO_CLEANUP}" ]; then + if [ -z "${NO_CLEANUP}" ] && [ -n "${tmpdir}" ]; then + cd || true ${ROOTCMD} rm -rf "${tmpdir}" fi } deferred_warnings() { - if [ -n "${WARNINGS}" ]; then + if [ -n "${NETDATA_WARNINGS}" ]; then printf >&2 "%s\n" "The following non-fatal warnings or errors were encountered:" - echo >&2 "${WARNINGS}" - printf >&2 "\n" + # shellcheck disable=SC2059 + printf >&2 "${NETDATA_WARNINGS}" + printf >&2 "\n\n" fi } @@ -417,7 +454,8 @@ run() { if [ ${ret} -ne 0 ]; then printf >&2 "%s\n\n" "${TPUT_BGRED}${TPUT_WHITE}${TPUT_BOLD} FAILED ${TPUT_RESET}" printf "%s\n" "FAILED with exit code ${ret}" >> "${run_logfile}" - WARNINGS="${WARNINGS}\n - Command \"${*}\" failed with exit code ${ret}." + # shellcheck disable=SC2089 + NETDATA_WARNINGS="${NETDATA_WARNINGS}\n - Command \"${*}\" failed with exit code ${ret}." else printf >&2 "%s\n\n" "${TPUT_BGGREEN}${TPUT_WHITE}${TPUT_BOLD} OK ${TPUT_RESET}" printf "OK\n" >> "${run_logfile}" @@ -428,7 +466,7 @@ run() { warning() { printf >&2 "%s\n\n" "${TPUT_BGRED}${TPUT_WHITE}${TPUT_BOLD} WARNING ${TPUT_RESET} ${*}" - WARNINGS="${WARNINGS}\n - ${*}" + NETDATA_WARNINGS="${NETDATA_WARNINGS}\n - ${*}" } _cannot_use_tmpdir() { @@ -467,9 +505,20 @@ create_tmp_directory() { mktemp -d -t netdata-kickstart-XXXXXXXXXX } +set_tmpdir() { + if [ -z "${tmpdir}" ]; then + tmpdir="$(create_tmp_directory)" + progress "Using ${tmpdir} as a temporary directory." + cd "${tmpdir}" || fatal "Failed to change current working directory to ${tmpdir}." F000A + fi +} + check_for_remote_file() { url="${1}" - if command -v curl > /dev/null 2>&1; then + + if echo "${url}" | grep -Eq "^file:///"; then + [ -e "${url#file://}" ] || return 1 + elif command -v curl > /dev/null 2>&1; then curl --output /dev/null --silent --head --fail "${url}" || return 1 elif command -v wget > /dev/null 2>&1; then wget -S --spider "${url}" 2>&1 | grep -q 'HTTP/1.1 200 OK' || return 1 @@ -481,7 +530,10 @@ check_for_remote_file() { download() { url="${1}" dest="${2}" - if command -v curl > /dev/null 2>&1; then + + if echo "${url}" | grep -Eq "^file:///"; then + run cp "${url#file://}" "${dest}" || return 1 + elif command -v curl > /dev/null 2>&1; then run curl --fail -q -sSL --connect-timeout 10 --retry 3 --output "${dest}" "${url}" || return 1 elif command -v wget > /dev/null 2>&1; then run wget -T 15 -O "${dest}" "${url}" || return 1 @@ -644,11 +696,19 @@ update() { return 0 fi + export NETDATA_SAVE_WARNINGS=1 + export NETDATA_PROPAGATE_WARNINGS=1 + # shellcheck disable=SC2090 + export NETDATA_WARNINGS="${NETDATA_WARNINGS}" if run ${ROOTCMD} "${updater}" --not-running-from-cron; then progress "Updated existing install at ${ndprefix}" return 0 else - fatal "Failed to update existing Netdata install at ${ndprefix}" F0100 + if [ -n "${EXIT_REASON}" ]; then + fatal "Failed to update existing Netdata install at ${ndprefix}: ${EXIT_REASON}" "${EXIT_CODE}" + else + fatal "Failed to update existing Netdata install at ${ndprefix}." U0000 + fi fi else warning "Could not find a usable copy of the updater script." @@ -657,6 +717,7 @@ update() { } uninstall() { + set_tmpdir get_system_info detect_existing_install @@ -681,6 +742,10 @@ uninstall() { return 0 else progress "Found existing netdata-uninstaller. Running it.." + export NETDATA_SAVE_WARNINGS=1 + export NETDATA_PROPAGATE_WARNINGS=1 + # shellcheck disable=SC2090 + export NETDATA_WARNINGS="${NETDATA_WARNINGS}" if ! run ${ROOTCMD} "${uninstaller}" $FLAGS; then warning "Uninstaller failed. Some parts of Netdata may still be present on the system." fi @@ -694,6 +759,10 @@ uninstall() { progress "Downloading netdata-uninstaller ..." download "${uninstaller_url}" "${tmpdir}/netdata-uninstaller.sh" chmod +x "${tmpdir}/netdata-uninstaller.sh" + export NETDATA_SAVE_WARNINGS=1 + export NETDATA_PROPAGATE_WARNINGS=1 + # shellcheck disable=SC2090 + export NETDATA_WARNINGS="${NETDATA_WARNINGS}" if ! run ${ROOTCMD} "${tmpdir}/netdata-uninstaller.sh" $FLAGS; then warning "Uninstaller failed. Some parts of Netdata may still be present on the system." fi @@ -901,11 +970,11 @@ EOF confirm_install_prefix() { if [ -n "${INSTALL_PREFIX}" ] && [ "${NETDATA_ONLY_BUILD}" -ne 1 ]; then - fatal "The \`--install\` option is only supported together with the \`--build-only\` option." F0204 + fatal "The \`--install-prefix\` and \`--install\` options are only supported together with the \`--build-only\` option." F0204 fi if [ -n "${INSTALL_PREFIX}" ]; then - NETDATA_INSTALLER_OPTIONS="${NETDATA_INSTALLER_OPTIONS} --install ${INSTALL_PREFIX}" + NETDATA_INSTALLER_OPTIONS="${NETDATA_INSTALLER_OPTIONS} --install-prefix ${INSTALL_PREFIX}" else case "${SYSTYPE}" in Darwin) @@ -1067,7 +1136,7 @@ set_auto_updates() { return 0 fi - if [ "${NETDATA_AUTO_UPDATES}" = "1" ]; then + if [ "${AUTO_UPDATE}" -eq 1 ]; then if [ "${DRY_RUN}" -eq 1 ]; then progress "Would have attempted to enable automatic updates." # This first case is for catching using a new kickstart script with an old build. It can be safely removed after v1.34.0 is released. @@ -1092,6 +1161,7 @@ set_auto_updates() { pkg_installed() { case "${DISTRO_COMPAT_NAME}" in debian|ubuntu) + # shellcheck disable=SC2016 dpkg-query --show --showformat '${Status}' "${1}" 2>&1 | cut -f 1 -d ' ' | grep -q '^install$' return $? ;; @@ -1163,7 +1233,7 @@ try_package_install() { progress "Attempting to install using native packages..." fi - if [ "${RELEASE_CHANNEL}" = "nightly" ]; then + if [ "${SELECTED_RELEASE_CHANNEL}" = "nightly" ]; then release="-edge" else release="" @@ -1190,6 +1260,7 @@ try_package_install() { repo_update_opts="${interactive_opts}" uninstall_subcmd="purge" INSTALL_TYPE="binpkg-deb" + NATIVE_VERSION="${INSTALL_VERSION:+"=${INSTALL_VERSION}"}" ;; ubuntu) needs_early_refresh=1 @@ -1203,6 +1274,7 @@ try_package_install() { repo_update_opts="${interactive_opts}" uninstall_subcmd="purge" INSTALL_TYPE="binpkg-deb" + NATIVE_VERSION="${INSTALL_VERSION:+"=${INSTALL_VERSION}"}" ;; centos) if command -v dnf > /dev/null; then @@ -1219,6 +1291,7 @@ try_package_install() { repo_update_opts="${interactive_opts}" uninstall_subcmd="remove" INSTALL_TYPE="binpkg-rpm" + NATIVE_VERSION="${INSTALL_VERSION:+"-${INSTALL_VERSION}.${SYSARCH}"}" ;; fedora) if command -v dnf > /dev/null; then @@ -1235,6 +1308,7 @@ try_package_install() { repo_update_opts="${interactive_opts}" uninstall_subcmd="remove" INSTALL_TYPE="binpkg-rpm" + NATIVE_VERSION="${INSTALL_VERSION:+"-${INSTALL_VERSION}.${SYSARCH}"}" ;; opensuse) pm_cmd="zypper" @@ -1247,6 +1321,7 @@ try_package_install() { repo_update_opts="" uninstall_subcmd="remove" INSTALL_TYPE="binpkg-rpm" + NATIVE_VERSION="${INSTALL_VERSION:+"-${INSTALL_VERSION}.${SYSARCH}"}" ;; ol) if command -v dnf > /dev/null; then @@ -1263,6 +1338,7 @@ try_package_install() { repo_update_opts="${interactive_opts}" uninstall_subcmd="remove" INSTALL_TYPE="binpkg-rpm" + NATIVE_VERSION="${INSTALL_VERSION:+"-${INSTALL_VERSION}.${SYSARCH}"}" ;; *) warning "We do not provide native packages for ${DISTRO}." @@ -1270,6 +1346,20 @@ try_package_install() { ;; esac + if [ -n "${INSTALL_VERSION}" ]; then + if echo "${INSTALL_VERSION}" | grep -q "nightly"; then + new_release="-edge" + else + new_release= + fi + + if { [ -n "${new_release}" ] && [ -z "${release}" ]; } || { [ -z "${new_release}" ] && [ -n "${release}" ]; }; then + warning "Selected release channel does not match this version and it will be changed automatically." + fi + + release="${new_release}" + fi + repoconfig_name="netdata-repo${release}" repoconfig_file="${repoconfig_name}${pkg_vsep}${REPOCONFIG_VERSION}${pkg_suffix}.${pkg_type}" repoconfig_url="${REPOCONFIG_URL_PREFIX}/${repo_prefix}/${repoconfig_file}/download.${pkg_type}" @@ -1309,6 +1399,14 @@ try_package_install() { progress "Repository configuration is already present, attempting to install netdata." fi + if [ "${REPO_ACTION}" = "repositories-only" ]; then + progress "Successfully installed repository configuraion package." + deferred_warnings + cleanup + trap - EXIT + exit 1 + fi + if ! check_special_native_deps; then warning "Could not find secondary dependencies for ${DISTRO} on ${SYSARCH}." if [ -z "${NO_CLEANUP}" ]; then @@ -1335,7 +1433,7 @@ try_package_install() { fi # shellcheck disable=SC2086 - if ! run ${ROOTCMD} env ${env} ${pm_cmd} install ${pkg_install_opts} netdata; then + if ! run ${ROOTCMD} env ${env} ${pm_cmd} install ${pkg_install_opts} "netdata${NATIVE_VERSION}"; then warning "Failed to install Netdata package." if [ -z "${NO_CLEANUP}" ]; then progress "Attempting to uninstall repository configuration package." @@ -1348,20 +1446,42 @@ try_package_install() { # ====================================================================== # Static build install code - +# shellcheck disable=SC2034,SC2086,SC2126 set_static_archive_urls() { - if [ "${RELEASE_CHANNEL}" = "stable" ]; then - latest="$(get_redirect "https://github.com/netdata/netdata/releases/latest")" - export NETDATA_STATIC_ARCHIVE_URL="https://github.com/netdata/netdata/releases/download/${latest}/netdata-${SYSARCH}-latest.gz.run" - export NETDATA_STATIC_ARCHIVE_CHECKSUM_URL="https://github.com/netdata/netdata/releases/download/${latest}/sha256sums.txt" + if [ -z "${2}" ]; then + arch="${SYSARCH}" + else + arch="${2}" + fi + + if [ -n "${NETDATA_OFFLINE_INSTALL_SOURCE}" ]; then + path="$(cd "${NETDATA_OFFLINE_INSTALL_SOURCE}" || exit 1; pwd)" + export NETDATA_STATIC_ARCHIVE_URL="file://${path}/netdata-${arch}-latest.gz.run" + export NETDATA_STATIC_ARCHIVE_CHECKSUM_URL="file://${path}/sha256sums.txt" + elif [ "${1}" = "stable" ]; then + if [ -n "${INSTALL_VERSION}" ]; then + export NETDATA_STATIC_ARCHIVE_OLD_URL="https://github.com/netdata/netdata/releases/download/v${INSTALL_VERSION}/netdata-v${INSTALL_VERSION}.gz.run" + export NETDATA_STATIC_ARCHIVE_URL="https://github.com/netdata/netdata/releases/download/v${INSTALL_VERSION}/netdata-${arch}-v${INSTALL_VERSION}.gz.run" + export NETDATA_STATIC_ARCHIVE_CHECKSUM_URL="https://github.com/netdata/netdata/releases/download/v${INSTALL_VERSION}/sha256sums.txt" + else + latest="$(get_redirect "https://github.com/netdata/netdata/releases/latest")" + export NETDATA_STATIC_ARCHIVE_URL="https://github.com/netdata/netdata/releases/download/${latest}/netdata-${arch}-latest.gz.run" + export NETDATA_STATIC_ARCHIVE_CHECKSUM_URL="https://github.com/netdata/netdata/releases/download/${latest}/sha256sums.txt" + fi else - export NETDATA_STATIC_ARCHIVE_URL="${NETDATA_TARBALL_BASEURL}/netdata-${SYSARCH}-latest.gz.run" - export NETDATA_STATIC_ARCHIVE_CHECKSUM_URL="${NETDATA_TARBALL_BASEURL}/sha256sums.txt" + if [ -n "${INSTALL_VERSION}" ]; then + export NETDATA_STATIC_ARCHIVE_URL="${NETDATA_TARBALL_BASEURL}/netdata-${arch}-v${INSTALL_VERSION}.gz.run" + export NETDATA_STATIC_ARCHIVE_OLD_URL="${NETDATA_TARBALL_BASEURL}/netdata-v${INSTALL_VERSION}.gz.run" + export NETDATA_STATIC_ARCHIVE_CHECKSUM_URL="${NETDATA_TARBALL_BASEURL}/sha256sums.txt" + else + export NETDATA_STATIC_ARCHIVE_URL="${NETDATA_TARBALL_BASEURL}/netdata-${arch}-latest.gz.run" + export NETDATA_STATIC_ARCHIVE_CHECKSUM_URL="${NETDATA_TARBALL_BASEURL}/sha256sums.txt" + fi fi } try_static_install() { - set_static_archive_urls "${RELEASE_CHANNEL}" + set_static_archive_urls "${SELECTED_RELEASE_CHANNEL}" if [ "${DRY_RUN}" -eq 1 ]; then progress "Would attempt to install using static build..." else @@ -1369,12 +1489,31 @@ try_static_install() { fi # Check status code first, so that we can provide nicer fallback for dry runs. - if ! check_for_remote_file "${NETDATA_STATIC_ARCHIVE_URL}"; then + if check_for_remote_file "${NETDATA_STATIC_ARCHIVE_URL}"; then + if [ -n "${NETDATA_OFFLINE_INSTALL_SOURCE}" ]; then + netdata_agent="$(basename "${NETDATA_STATIC_ARCHIVE_URL#"file://"}")" + elif [ -n "${INSTALL_VERSION}" ]; then + if [ "${SELECTED_RELEASE_CHANNEL}" = "stable" ]; then + netdata_agent="${NETDATA_STATIC_ARCHIVE_URL#"https://github.com/netdata/netdata/releases/download/v${INSTALL_VERSION}/"}" + else + netdata_agent="${NETDATA_STATIC_ARCHIVE_URL#"${NETDATA_TARBALL_BASEURL}/"}" + fi + else + if [ "${SELECTED_RELEASE_CHANNEL}" = "stable" ]; then + netdata_agent="${NETDATA_STATIC_ARCHIVE_URL#"https://github.com/netdata/netdata/releases/download/${latest}/"}" + else + netdata_agent="${NETDATA_STATIC_ARCHIVE_URL#"${NETDATA_TARBALL_BASEURL}/"}" + fi + fi + elif [ "${SYSARCH}" = "x86_64" ] && check_for_remote_file "${NETDATA_STATIC_ARCHIVE_OLD_URL}"; then + netdata_agent="${NETDATA_STATIC_ARCHIVE_OLD_URL#"https://github.com/netdata/netdata/releases/download/v${INSTALL_VERSION}/"}" + export NETDATA_STATIC_ARCHIVE_URL="${NETDATA_STATIC_ARCHIVE_OLD_URL}" + else warning "No static build available for ${SYSARCH} CPUs." return 2 fi - if ! download "${NETDATA_STATIC_ARCHIVE_URL}" "${tmpdir}/netdata-${SYSARCH}-latest.gz.run"; then + if ! download "${NETDATA_STATIC_ARCHIVE_URL}" "${tmpdir}/${netdata_agent}"; then fatal "Unable to download static build archive for ${SYSARCH}." F0208 fi @@ -1385,8 +1524,10 @@ try_static_install() { if [ "${DRY_RUN}" -eq 1 ]; then progress "Would validate SHA256 checksum of downloaded static build archive." else - if ! grep "netdata-${SYSARCH}-latest.gz.run" "${tmpdir}/sha256sum.txt" | safe_sha256sum -c - > /dev/null 2>&1; then - fatal "Static binary checksum validation failed. Usually this is a result of an older copy of the file being cached somewhere upstream and can be resolved by retrying in an hour." F0207 + if [ -z "${INSTALL_VERSION}" ]; then + if ! grep "${netdata_agent}" "${tmpdir}/sha256sum.txt" | safe_sha256sum -c - > /dev/null 2>&1; then + fatal "Static binary checksum validation failed. Usually this is a result of an older copy of the file being cached somewhere upstream and can be resolved by retrying in an hour." F0207 + fi fi fi @@ -1396,7 +1537,7 @@ try_static_install() { progress "Installing netdata" # shellcheck disable=SC2086 - if ! run ${ROOTCMD} sh "${tmpdir}/netdata-${SYSARCH}-latest.gz.run" ${opts} -- ${NETDATA_AUTO_UPDATES:+--auto-update} ${NETDATA_INSTALLER_OPTIONS}; then + if ! run ${ROOTCMD} sh "${tmpdir}/${netdata_agent}" ${opts} -- ${NETDATA_INSTALLER_OPTIONS}; then warning "Failed to install static build of Netdata on ${SYSARCH}." run rm -rf /opt/netdata return 2 @@ -1424,12 +1565,22 @@ try_static_install() { set_source_archive_urls() { if [ "$1" = "stable" ]; then - latest="$(get_redirect "https://github.com/netdata/netdata/releases/latest")" - export NETDATA_SOURCE_ARCHIVE_URL="https://github.com/netdata/netdata/releases/download/${latest}/netdata-${latest}.tar.gz" - export NETDATA_SOURCE_ARCHIVE_CHECKSUM_URL="https://github.com/netdata/netdata/releases/download/${latest}/sha256sums.txt" + if [ -n "${INSTALL_VERSION}" ]; then + export NETDATA_SOURCE_ARCHIVE_URL="https://github.com/netdata/netdata/releases/download/v${INSTALL_VERSION}/netdata-v${INSTALL_VERSION}.tar.gz" + export NETDATA_SOURCE_ARCHIVE_CHECKSUM_URL="https://github.com/netdata/netdata/releases/download/v${INSTALL_VERSION}/sha256sums.txt" + else + latest="$(get_redirect "https://github.com/netdata/netdata/releases/latest")" + export NETDATA_SOURCE_ARCHIVE_URL="https://github.com/netdata/netdata/releases/download/${latest}/netdata-${latest}.tar.gz" + export NETDATA_SOURCE_ARCHIVE_CHECKSUM_URL="https://github.com/netdata/netdata/releases/download/${latest}/sha256sums.txt" + fi else - export NETDATA_SOURCE_ARCHIVE_URL="${NETDATA_TARBALL_BASEURL}/netdata-latest.tar.gz" - export NETDATA_SOURCE_ARCHIVE_CHECKSUM_URL="${NETDATA_TARBALL_BASEURL}/sha256sums.txt" + if [ -n "${INSTALL_VERSION}" ]; then + export NETDATA_SOURCE_ARCHIVE_URL="${NETDATA_TARBALL_BASEURL}/netdata-v${INSTALL_VERSION}.tar.gz" + export NETDATA_SOURCE_ARCHIVE_CHECKSUM_URL="${NETDATA_TARBALL_BASEURL}/sha256sums.txt" + else + export NETDATA_SOURCE_ARCHIVE_URL="${NETDATA_TARBALL_BASEURL}/netdata-latest.tar.gz" + export NETDATA_SOURCE_ARCHIVE_CHECKSUM_URL="${NETDATA_TARBALL_BASEURL}/sha256sums.txt" + fi fi } @@ -1482,11 +1633,7 @@ build_and_install() { opts="${opts} --dont-wait" fi - if [ "${NETDATA_AUTO_UPDATES}" -eq 1 ]; then - opts="${opts} --auto-update" - fi - - if [ "${RELEASE_CHANNEL}" = "stable" ]; then + if [ "${SELECTED_RELEASE_CHANNEL}" = "stable" ]; then opts="${opts} --stable-channel" fi @@ -1496,12 +1643,20 @@ build_and_install() { opts="${opts} --disable-cloud" fi + export NETDATA_SAVE_WARNINGS=1 + export NETDATA_PROPAGATE_WARNINGS=1 + # shellcheck disable=SC2090 + export NETDATA_WARNINGS="${NETDATA_WARNINGS}" # shellcheck disable=SC2086 run ${ROOTCMD} ./netdata-installer.sh ${opts} case $? in 1) - fatal "netdata-installer.sh failed to run correctly." F0007 + if [ -n "${EXIT_REASON}" ]; then + fatal "netdata-installer.sh failed to run: ${EXIT_REASON}" "${EXIT_CODE}" + else + fatal "netdata-installer.sh failed to run correctly." I0000 + fi ;; 2) fatal "Insufficient RAM to install netdata." F0008 @@ -1520,9 +1675,13 @@ try_build_install() { return 1 fi - set_source_archive_urls "${RELEASE_CHANNEL}" + set_source_archive_urls "${SELECTED_RELEASE_CHANNEL}" - if ! download "${NETDATA_SOURCE_ARCHIVE_URL}" "${tmpdir}/netdata-latest.tar.gz"; then + if [ -n "${INSTALL_VERSION}" ]; then + if ! download "${NETDATA_SOURCE_ARCHIVE_URL}" "${tmpdir}/netdata-v${INSTALL_VERSION}.tar.gz"; then + fatal "Failed to download source tarball for local build." F000B + fi + elif ! download "${NETDATA_SOURCE_ARCHIVE_URL}" "${tmpdir}/netdata-latest.tar.gz"; then fatal "Failed to download source tarball for local build." F000B fi @@ -1533,13 +1692,22 @@ try_build_install() { if [ "${DRY_RUN}" -eq 1 ]; then progress "Would validate SHA256 checksum of downloaded source archive." else - if ! grep netdata-latest.tar.gz "${tmpdir}/sha256sum.txt" | safe_sha256sum -c - > /dev/null 2>&1; then - fatal "Tarball checksum validation failed. Usually this is a result of an older copy of the file being cached somewhere upstream and can be resolved by retrying in an hour." F0005 + if [ -z "${INSTALL_VERSION}" ]; then + # shellcheck disable=SC2086 + if ! grep netdata-latest.tar.gz "${tmpdir}/sha256sum.txt" | safe_sha256sum -c - > /dev/null 2>&1; then + fatal "Tarball checksum validation failed. Usually this is a result of an older copy of the file being cached somewhere upstream and can be resolved by retrying in an hour." F0005 + fi fi fi - run tar -xf "${tmpdir}/netdata-latest.tar.gz" -C "${tmpdir}" - rm -rf "${tmpdir}/netdata-latest.tar.gz" > /dev/null 2>&1 + if [ -n "${INSTALL_VERSION}" ]; then + run tar -xf "${tmpdir}/netdata-v${INSTALL_VERSION}.tar.gz" -C "${tmpdir}" + rm -rf "${tmpdir}/netdata-v${INSTALL_VERSION}.tar.gz" > /dev/null 2>&1 + else + run tar -xf "${tmpdir}/netdata-latest.tar.gz" -C "${tmpdir}" + rm -rf "${tmpdir}/netdata-latest.tar.gz" > /dev/null 2>&1 + fi + if [ "${DRY_RUN}" -ne 1 ]; then cd "$(find "${tmpdir}" -mindepth 1 -maxdepth 1 -type d -name netdata-)" || fatal "Cannot change directory to netdata source tree" F0006 fi @@ -1557,10 +1725,97 @@ try_build_install() { } # ====================================================================== +# Offline install support code + +prepare_offline_install_source() { + if [ -e "${1}" ]; then + if [ ! -d "${1}" ]; then + fatal "${1} is not a directory, unable to prepare offline install source." F0503 + fi + else + run mkdir -p "${1}" || fatal "Unable to create target directory for offline install preparation." F0504 + fi + + run cd "${1}" || fatal "Failed to swtich to target directory for offline install preparation." F0505 + + if [ "${NETDATA_ONLY_NATIVE}" -ne 1 ] && [ "${NETDATA_ONLY_BUILD}" -ne 1 ]; then + set_static_archive_urls "${SELECTED_RELEASE_CHANNEL}" "x86_64" + + if check_for_remote_file "${NETDATA_STATIC_ARCHIVE_URL}"; then + for arch in ${STATIC_INSTALL_ARCHES}; do + set_static_archive_urls "${SELECTED_RELEASE_CHANNEL}" "${arch}" + + progress "Fetching ${NETDATA_STATIC_ARCHIVE_URL}" + if ! download "${NETDATA_STATIC_ARCHIVE_URL}" "netdata-${arch}-latest.gz.run"; then + warning "Failed to download static installer archive for ${arch}." + fi + done + legacy=0 + else + warning "Selected version of Netdata only provides static builds for x86_64. You will only be able to install on x86_64 systems with this offline install source." + progress "Fetching ${NETDATA_STATIC_ARCHIVE_OLD_URL}" + legacy=1 + + if ! download "${NETDATA_STATIC_ARCHIVE_OLD_URL}" "netdata-x86_64-latest.gz.run"; then + warning "Failed to download static installer archive for x86_64." + fi + fi + + progress "Fetching ${NETDATA_STATIC_ARCHIVE_CHECKSUM_URL}" + if ! download "${NETDATA_STATIC_ARCHIVE_CHECKSUM_URL}" "sha256sums.txt"; then + fatal "Failed to download checksum file." F0506 + fi + fi + + if [ "${legacy:-0}" -eq 1 ]; then + sed -e 's/netdata-latest.gz.run/netdata-x86_64-latest.gz.run' sha256sums.txt > sha256sums.tmp + mv sha256sums.tmp sha256sums.txt + fi + + if [ "${DRY_RUN}" -ne 1 ]; then + progress "Verifying checksums." + if ! grep -e "$(find . -name '*.gz.run')" sha256sums.txt | safe_sha256sum -c -; then + fatal "Checksums for offline install files are incorrect. Usually this is a result of an older copy of the file being cached somewhere upstream and can be resolved by retrying in an hour." F0507 + fi + else + progress "Would verify SHA256 checksums of downloaded installation files." + fi + + if [ "${DRY_RUN}" -ne 1 ]; then + progress "Preparing install script." + cat > "install.sh" <<-EOF + #!/bin/sh + dir=\$(CDPATH= cd -- "\$(dirname -- "\$0")" && pwd) + "\${dir}/kickstart.sh" --offline-install-source "\${dir}" \${@} + EOF + chmod +x "install.sh" + else + progress "Would create install script" + fi + + if [ "${DRY_RUN}" -ne 1 ]; then + progress "Copying kickstart script." + cp "${KICKSTART_SOURCE}" "kickstart.sh" + chmod +x "kickstart.sh" + else + progress "Would copy kickstart.sh to offline install source directory" + fi + + if [ "${DRY_RUN}" -ne 1 ]; then + progress "Saving release channel information." + echo "${SELECTED_RELEASE_CHANNEL}" > "channel" + else + progress "Would save release channel information to offline install source directory" + fi + + progress "Finished preparing offline install source directory at ${1}. You can now copy this directory to a target system and then run the script ‘install.sh’ from it to install on that system." +} + +# ====================================================================== # Per system-type install logic install_on_linux() { - if [ "${NETDATA_ONLY_STATIC}" -ne 1 ] && [ "${NETDATA_ONLY_BUILD}" -ne 1 ]; then + if [ "${NETDATA_ONLY_STATIC}" -ne 1 ] && [ "${NETDATA_ONLY_BUILD}" -ne 1 ] && [ -z "${NETDATA_OFFLINE_INSTALL_SOURCE}" ]; then SELECTED_INSTALL_METHOD="native" try_package_install @@ -1664,124 +1919,235 @@ install_on_freebsd() { } # ====================================================================== -# Main program +# Argument parsing code -setup_terminal || echo > /dev/null +validate_args() { + check_claim_opts -while [ -n "${1}" ]; do - case "${1}" in - "--help") - usage - cleanup - trap - EXIT - exit 0 - ;; - "--no-cleanup") NO_CLEANUP=1 ;; - "--dont-wait"|"--non-interactive") INTERACTIVE=0 ;; - "--interactive") INTERACTIVE=1 ;; - "--dry-run") DRY_RUN=1 ;; - "--stable-channel") RELEASE_CHANNEL="stable" ;; - "--no-updates") NETDATA_AUTO_UPDATES=0 ;; - "--auto-update") NETDATA_AUTO_UPDATES="1" ;; - "--auto-update-method") - NETDATA_AUTO_UPDATE_TYPE="$(echo "${2}" | tr '[:upper:]' '[:lower:]')" - case "${NETDATA_AUTO_UPDATE_TYPE}" in - systemd|interval|crontab) + if [ -n "${NETDATA_OFFLINE_INSTALL_SOURCE}" ]; then + if [ "${NETDATA_ONLY_NATIVE}" -eq 1 ] || [ "${NETDATA_ONLY_BUILD}" -eq 1 ]; then + fatal "Offline installs are only supported for static builds currently." F0502 + fi + fi + + if [ -n "${LOCAL_BUILD_OPTIONS}" ]; then + if [ "${NETDATA_ONLY_BUILD}" -eq 1 ]; then + NETDATA_INSTALLER_OPTIONS="${NETDATA_INSTALLER_OPTIONS} ${LOCAL_BUILD_OPTIONS}" + else + fatal "Specifying local build options is only supported when the --build-only option is also specified." F0401 + fi + fi + + if [ -n "${STATIC_INSTALL_OPTIONS}" ]; then + if [ "${NETDATA_ONLY_STATIC}" -eq 1 ]; then + NETDATA_INSTALLER_OPTIONS="${NETDATA_INSTALLER_OPTIONS} ${STATIC_INSTALL_OPTIONS}" + else + fatal "Specifying installer options options is only supported when the --static-only option is also specified." F0402 + fi + fi + + if [ -n "${NETDATA_OFFLINE_INSTALL_SOURCE}" ] && [ -n "${INSTALL_VERSION}" ]; then + fatal "Specifying an install version alongside an offline install source is not supported." F050A + fi + + if [ "${NETDATA_AUTO_UPDATES}" = "default" ]; then + if [ -n "${NETDATA_OFFLINE_INSTALL_SOURCE}" ] || [ -n "${INSTALL_VERSION}" ]; then + AUTO_UPDATE=0 + else + AUTO_UPDATE=1 + fi + elif [ "${NETDATA_AUTO_UPDATES}" = 1 ]; then + AUTO_UPDATE=1 + else + AUTO_UPDATE=0 + fi + + if [ "${RELEASE_CHANNEL}" = "default" ]; then + if [ -n "${NETDATA_OFFLINE_INSTALL_SOURCE}" ]; then + SELECTED_RELEASE_CHANNEL="$(cat "${NETDATA_OFFLINE_INSTALL_SOURCE}/channel")" + + if [ -z "${SELECTED_RELEASE_CHANNEL}" ]; then + fatal "Could not find a release channel indicator in ${NETDATA_OFFLINE_INSTALL_SOURCE}." F0508 + fi + else + SELECTED_RELEASE_CHANNEL="${DEFAULT_RELEASE_CHANNEL}" + fi + else + if [ -n "${NETDATA_OFFLINE_INSTALL_SOURCE}" ] && [ "${RELEASE_CHANNEL}" != "$(cat "${NETDATA_OFFLINE_INSTALL_SOURCE}/channel")" ]; then + fatal "Release channal '${RELEASE_CHANNEL}' requested, but indicated offline installation source release channel is '$(cat "${NETDATA_OFFLINE_INSTALL_SOURCE}/channel")'." F0509 + fi + + SELECTED_RELEASE_CHANNEL="${RELEASE_CHANNEL}" + fi +} + +parse_args() { + if [ -n "${NETDATA_INSTALLER_OPTIONS}" ]; then + warning "Explicitly specifying additional installer options with NETDATA_INSTALLER_OPTIONS is deprecated. Please instead pass the options to the script using either --local-build-options or --static-install-options as appropriate." + fi + + while [ -n "${1}" ]; do + case "${1}" in + "--help") + usage + cleanup + trap - EXIT + exit 0 + ;; + "--no-cleanup") NO_CLEANUP=1 ;; + "--dont-wait"|"--non-interactive") INTERACTIVE=0 ;; + "--interactive") INTERACTIVE=1 ;; + "--dry-run") DRY_RUN=1 ;; + "--stable-channel") RELEASE_CHANNEL="stable" ;; + "--no-updates") NETDATA_AUTO_UPDATES=0 ;; + "--auto-update") NETDATA_AUTO_UPDATES="1" ;; + "--auto-update-method") + NETDATA_AUTO_UPDATE_TYPE="$(echo "${2}" | tr '[:upper:]' '[:lower:]')" + case "${NETDATA_AUTO_UPDATE_TYPE}" in + systemd|interval|crontab) + shift 1 + ;; + *) + echo "Unrecognized value for --auto-update-type. Valid values are: systemd, interval, crontab" + exit 1 + ;; + esac + ;; + "--reinstall") NETDATA_REINSTALL=1 ;; + "--reinstall-even-if-unsafe") NETDATA_UNSAFE_REINSTALL=1 ;; + "--claim-only") NETDATA_CLAIM_ONLY=1 ;; + "--disable-cloud") + NETDATA_DISABLE_CLOUD=1 + NETDATA_REQUIRE_CLOUD=0 + ;; + "--require-cloud") + NETDATA_DISABLE_CLOUD=0 + NETDATA_REQUIRE_CLOUD=1 + ;; + "--dont-start-it") + NETDATA_NO_START=1 + NETDATA_INSTALLER_OPTIONS="${NETDATA_INSTALLER_OPTIONS} --dont-start-it" + ;; + "--disable-telemetry") + NETDATA_DISABLE_TELEMETRY="1" + NETDATA_INSTALLER_OPTIONS="${NETDATA_INSTALLER_OPTIONS} --disable-telemetry" + ;; + "--install") + warning "--install flag is deprecated and will be removed in a future version. Please use --install-prefix instead." + INSTALL_PREFIX="${2}" + shift 1 + ;; + "--install-prefix") + INSTALL_PREFIX="${2}" + shift 1 + ;; + "--old-install-prefix") + OLD_INSTALL_PREFIX="${2}" + shift 1 + ;; + "--install-version") + INSTALL_VERSION="${2}" + AUTO_UPDATE=0 + shift 1 + ;; + "--uninstall") + ACTION="uninstall" + ;; + "--reinstall-clean") + ACTION="reinstall-clean" + ;; + "--repositories-only") + REPO_ACTION="repositories-only" + ;; + "--native-only") + NETDATA_ONLY_NATIVE=1 + NETDATA_ONLY_STATIC=0 + NETDATA_ONLY_BUILD=0 + SELECTED_INSTALL_METHOD="native" + ;; + "--static-only") + NETDATA_ONLY_STATIC=1 + NETDATA_ONLY_NATIVE=0 + NETDATA_ONLY_BUILD=0 + SELECTED_INSTALL_METHOD="static" + ;; + "--build-only") + NETDATA_ONLY_BUILD=1 + NETDATA_ONLY_NATIVE=0 + NETDATA_ONLY_STATIC=0 + SELECTED_INSTALL_METHOD="build" + ;; + "--claim-token") + NETDATA_CLAIM_TOKEN="${2}" + shift 1 + ;; + "--claim-rooms") + NETDATA_CLAIM_ROOMS="${2}" + shift 1 + ;; + "--claim-url") + NETDATA_CLAIM_URL="${2}" + shift 1 + ;; + "--claim-"*) + optname="$(echo "${1}" | cut -d '-' -f 4-)" + case "${optname}" in + id|proxy|user|hostname) + NETDATA_CLAIM_EXTRA="${NETDATA_CLAIM_EXTRA} -${optname}=${2}" + shift 1 + ;; + verbose|insecure|noproxy|noreload|daemon-not-running) + NETDATA_CLAIM_EXTRA="${NETDATA_CLAIM_EXTRA} -${optname}" + ;; + *) + warning "Ignoring unrecognized claiming option ${optname}" + ;; + esac + ;; + "--local-build-options") + LOCAL_BUILD_OPTIONS="${2}" + shift 1 + ;; + "--static-install-options") + STATIC_INSTALL_OPTIONS="${2}" + shift 1 + ;; + "--prepare-offline-install-source") + if [ -n "${2}" ]; then + ACTION="prepare-offline" + OFFLINE_TARGET="${2}" shift 1 - ;; - *) - echo "Unrecognized value for --auto-update-type. Valid values are: systemd, interval, crontab" - exit 1 - ;; - esac - ;; - "--reinstall") NETDATA_REINSTALL=1 ;; - "--reinstall-even-if-unsafe") NETDATA_UNSAFE_REINSTALL=1 ;; - "--claim-only") NETDATA_CLAIM_ONLY=1 ;; - "--disable-cloud") - NETDATA_DISABLE_CLOUD=1 - NETDATA_REQUIRE_CLOUD=0 - ;; - "--require-cloud") - NETDATA_DISABLE_CLOUD=0 - NETDATA_REQUIRE_CLOUD=1 - ;; - "--dont-start-it") - NETDATA_NO_START=1 - NETDATA_INSTALLER_OPTIONS="${NETDATA_INSTALLER_OPTIONS} --dont-start-it" - ;; - "--disable-telemetry") - NETDATA_DISABLE_TELEMETRY="1" - NETDATA_INSTALLER_OPTIONS="${NETDATA_INSTALLER_OPTIONS} --disable-telemetry" - ;; - "--install") - INSTALL_PREFIX="${2}" - shift 1 - ;; - "--old-install-prefix") - OLD_INSTALL_PREFIX="${2}" - shift 1 - ;; - "--uninstall") - ACTION="uninstall" - ;; - "--reinstall-clean") - ACTION="reinstall-clean" - ;; - "--native-only") - NETDATA_ONLY_NATIVE=1 - NETDATA_ONLY_STATIC=0 - NETDATA_ONLY_BUILD=0 - SELECTED_INSTALL_METHOD="native" - ;; - "--static-only") - NETDATA_ONLY_STATIC=1 - NETDATA_ONLY_NATIVE=0 - NETDATA_ONLY_BUILD=0 - SELECTED_INSTALL_METHOD="static" - ;; - "--build-only") - NETDATA_ONLY_BUILD=1 - NETDATA_ONLY_NATIVE=0 - NETDATA_ONLY_STATIC=0 - SELECTED_INSTALL_METHOD="build" - ;; - "--claim-token") - NETDATA_CLAIM_TOKEN="${2}" - shift 1 - ;; - "--claim-rooms") - NETDATA_CLAIM_ROOMS="${2}" - shift 1 - ;; - "--claim-url") - NETDATA_CLAIM_URL="${2}" - shift 1 - ;; - "--claim-"*) - optname="$(echo "${1}" | cut -d '-' -f 4-)" - case "${optname}" in - id|proxy|user|hostname) - NETDATA_CLAIM_EXTRA="${NETDATA_CLAIM_EXTRA} -${optname}=${2}" + else + fatal "A target directory must be specified with the --prepare-offline-install-source option." F0500 + fi + ;; + "--offline-install-source") + if [ -d "${2}" ]; then + NETDATA_OFFLINE_INSTALL_SOURCE="${2}" shift 1 - ;; - verbose|insecure|noproxy|noreload|daemon-not-running) - NETDATA_CLAIM_EXTRA="${NETDATA_CLAIM_EXTRA} -${optname}" - ;; - *) - warning "Ignoring unrecognized claiming option ${optname}" - ;; - esac - ;; - *) - warning "Passing unrecognized option '${1}' to installer script. If this is intended, please add it to \$NETDATA_INSTALLER_OPTIONS instead." - NETDATA_INSTALLER_OPTIONS="${NETDATA_INSTALLER_OPTIONS} ${1}" - ;; - esac - shift 1 -done + else + fatal "A source directory must be specified with the --offline-install-source option." F0501 + fi + ;; + *) + warning "Passing unrecognized option '${1}' to installer script. This behavior is deprecated and will be removed in the near future. If you intended to pass this option to the installer code, please use either --local-build-options or --static-install-options to specify it instead." + NETDATA_INSTALLER_OPTIONS="${NETDATA_INSTALLER_OPTIONS} ${1}" + ;; + esac + shift 1 + done + + validate_args +} + +# ====================================================================== +# Main program + +setup_terminal || echo > /dev/null + +# shellcheck disable=SC2068 +parse_args $@ -check_claim_opts confirm_root_support get_system_info confirm_install_prefix diff --git a/packaging/installer/methods/kickstart.md b/packaging/installer/methods/kickstart.md index 2ff20cfd..fc212ea2 100644 --- a/packaging/installer/methods/kickstart.md +++ b/packaging/installer/methods/kickstart.md @@ -50,11 +50,16 @@ The `kickstart.sh` script accepts a number of optional parameters to control how - `--dont-wait`: Synonym for `--non-interactive` - `--dry-run`: Show what the installer would do, but don’t actually do any of it. - `--dont-start-it`: Don’t auto-start the daemon after installing. This parameter is not guaranteed to work. -- `--nightly-channel`: Use a nightly build instead of a stable release (this is the default). -- `--stable-channel`: Use a stable release instead of a nightly build. +- `--release-channel`: Specify a particular release channel to install from. Currently supported release channels are: + - `nightly`: Installs a nightly build (this is currently the default). + - `stable`: Installs a stable release. + - `default`: Explicitly request whatever the current default is. +- `--nightly-channel`: Synonym for `--release-channel nightly`. +- `--stable-channel`: Synonym for `--release-channel stable`. - `--auto-update`: Enable automatic updates (this is the default). - `--no-updates`: Disable automatic updates. - `--disable-telemetry`: Disable anonymous statistics. +- `--repositories-only`: Only install appropriate repository configuration packages (only for native install). - `--native-only`: Only install if native binary packages are available. - `--static-only`: Only install if a static build is available. - `--build-only`: Only install using a local build. @@ -63,10 +68,15 @@ The `kickstart.sh` script accepts a number of optional parameters to control how - `--disable-cloud`: For local builds, don’t build any of the cloud code at all. For native packages and static builds, use runtime configuration to disable cloud support. - `--require-cloud`: Only install if Netdata Cloud can be enabled. Overrides `--disable-cloud`. -- `--install`: Specify an installation prefix for local builds (by default, we use a sane prefix based on the type of system). +- `--install`: Specify an installation prefix for local builds (by default, we use a sane prefix based on the type of system), this option is deprecated and will be removed in a future version, please use `--install-prefix` instead. +- `--install-prefix`: Specify an installation prefix for local builds (by default, we use a sane prefix based on the type of system). +- `--install-version`: Specify the version of Netdata to install. - `--old-install-prefix`: Specify the custom local build's installation prefix that should be removed. - `--uninstall`: Uninstall an existing installation of Netdata. - `--reinstall-clean`: Performs an uninstall of Netdata and clean installation. +- `--local-build-options`: Specify additional options to pass to the installer code when building locally. Only valid if `--build-only` is also specified. +- `--static-install-options`: Specify additional options to pass to the static installer code. Only valid if --static-only is also specified. +- `--prepare-offline-install-source`: Instead of insallling the agent, prepare a directory that can be used to install on another system without needing to download anything. See our [offline installation documentation](/packaging/installer/methods/offline.md) for more info. Additionally, the following environment variables may be used to further customize how the script runs (most users should not need to use special values for any of these): @@ -78,7 +88,6 @@ should not need to use special values for any of these): we try to use sudo, doas, or pkexec (in that order of preference), but if you need special options for one of those to work, or have a different tool to do the same thing on your system, you can specify it here. - `DISABLE_TELEMETRY`: If set to a value other than 0, behave as if `--disable-telemetry` was specified. -- `NETDATA_INSTALLER_OPTIONS`: Specifies extra options to pass to the static installer or local build script. ### Connect node to Netdata Cloud during installation diff --git a/packaging/installer/methods/macos.md b/packaging/installer/methods/macos.md index 7257e1a6..c43d8dfb 100644 --- a/packaging/installer/methods/macos.md +++ b/packaging/installer/methods/macos.md @@ -28,7 +28,7 @@ To install Netdata using our automatic [kickstart](/packaging/installer/README.m ```bash curl https://my-netdata.io/kickstart.sh > /tmp/netdata-kickstart.sh && sh /tmp/netdata-kickstart.sh ``` -The Netdata Agent is be installed under `/usr/local/netdata`. Dependencies are handled via Homebrew. +The Netdata Agent is installed under `/usr/local/netdata`. Dependencies are handled via Homebrew. **Automatically connect to Netdata Cloud during installation** <!-- Potential reuse: https://learn.netdata.cloud/docs/agent/claim#connect-an-agent-running-in-macos--> diff --git a/packaging/installer/methods/offline.md b/packaging/installer/methods/offline.md index 53390c71..5e92976e 100644 --- a/packaging/installer/methods/offline.md +++ b/packaging/installer/methods/offline.md @@ -6,75 +6,53 @@ custom_edit_url: https://github.com/netdata/netdata/edit/master/packaging/instal # Install Netdata on offline systems -The Netdata Agent installs on offline or air gapped systems with a few additional steps. +Our kickstart install script provides support for installing the Netdata Agent on systems which do not have a +usable internet connection by prefetching all of the required files so that they can be copied to the target system. +Currently, we only support using static installs with this method. There are tentative plans to support building +locally on offline systems as well, but there is currently no estimate of when this functionality may be implemented. -By default, the `kickstart.sh` and `kickstart-static64.sh` download Netdata assets, like the precompiled binary and a -few dependencies, using the system's internet connection, but the Agent installer can also use equivalent files already -present on the local filesystem. +Users who wish to use native packages on offline systems may be able to do so using whatever tooling their +distribution already provides for offline package management (such as `apt-offline` on Debian or Ubuntu systems), +but this is not officially supported. -First, download the required files. If you're using `kickstart.sh`, you need the Netdata tarball, the checksums, the -go.d plugin binary, and the go.d plugin configuration. If you're using `kickstart-static64.sh`, you need only the -Netdata tarball and checksums. +## Preparing the offline installation source -Download the files you need to a system of yours that's connected to the internet. Use the commands below, or visit the -[latest Netdata release page](https://github.com/netdata/netdata/releases/latest) and [latest go.d plugin release -page](https://github.com/netdata/go.d.plugin/releases) to download the required files manually. +The first step to installing Netdata on an offline system is to prepare the offline installation source. This can +be as a regular user from any internet connected system that has the following tools available: -**If you're using `kickstart.sh`**, use the following commands: +- cURL or wget +- sha256sum or shasum +- A standard POSIX compliant shell -```bash -cd /tmp - -curl -s https://my-netdata.io/kickstart.sh > kickstart.sh - -# Netdata tarball -curl -s https://api.github.com/repos/netdata/netdata/releases/latest | grep "browser_download_url.*tar.gz" | cut -d '"' -f 4 | wget -qi - - -# Netdata checksums -curl -s https://api.github.com/repos/netdata/netdata/releases/latest | grep "browser_download_url.*txt" | cut -d '"' -f 4 | wget -qi - +To prepare the offline installation source, simply run: -# Netdata dependency handling script -wget -q - https://raw.githubusercontent.com/netdata/netdata/master/packaging/installer/install-required-packages.sh - -# go.d plugin -# For binaries for OS types and architectures not listed on [go.d releases](https://github.com/netdata/go.d.plugin/releases/latest), kindly open a github issue and we will do our best to serve your request -export OS=$(uname -s | tr '[:upper:]' '[:lower:]') ARCH=$(uname -m | sed -e 's/i386/386/g' -e 's/i686/386/g' -e 's/x86_64/amd64/g' -e 's/aarch64/arm64/g' -e 's/armv64/arm64/g' -e 's/armv6l/arm/g' -e 's/armv7l/arm/g' -e 's/armv5tel/arm/g') && curl -s https://api.github.com/repos/netdata/go.d.plugin/releases/latest | grep "browser_download_url.*${OS}-${ARCH}.tar.gz" | cut -d '"' -f 4 | wget -qi - - -# go.d configuration -curl -s https://api.github.com/repos/netdata/go.d.plugin/releases/latest | grep "browser_download_url.*config.tar.gz" | cut -d '"' -f 4 | wget -qi - +```bash +wget -O /tmp/netdata-kickstart.sh https://my-netdata.io/kickstart.sh && sh /tmp/netdata-kickstart.sh --prepare-offline-install-source ./netdata-offline ``` -**If you're using `kickstart-static64.sh`**, use the following commands: +or ```bash -cd /tmp - -curl -s https://my-netdata.io/kickstart-static64.sh > kickstart-static64.sh - -# Netdata static64 tarball -curl -s https://api.github.com/repos/netdata/netdata/releases/latest | grep "browser_download_url.*gz.run" | cut -d '"' -f 4 | wget -qi - - -# Netdata checksums -curl -s https://api.github.com/repos/netdata/netdata/releases/latest | grep "browser_download_url.*txt" | cut -d '"' -f 4 | wget -qi - +curl https://my-netdata.io/kickstart.sh > /tmp/netdata-kickstart.sh && sh /tmp/netdata-kickstart.sh --prepare-offline-install-source ./netdata-offline ``` -Move downloaded files to the `/tmp` directory on the offline system in whichever way your defined policy allows (if -any). +> The exact name used for the directory does not matter, you can specify any other name you want in place of `./netdata-offline`. -Now you can run either the `kickstart.sh` or `kickstart-static64.sh` scripts using the `--local-files` option. This -option requires you to specify the location and names of the files you just downloaded. +This will create a directory called `netdata-offline` in the current directory and place all the files required for an offline install in it. -> When using `--local-files`, the `kickstart.sh` or `kickstart-static64.sh` scripts won't download any Netdata assets -> from the internet. But, you may still need a connection to install dependencies using your system's package manager. -> The scripts will warn you if your system doesn't have all the dependencies. +If you want to use a specific release channel (nightly or stable), it _must_ be specified on this step using the +apporpriate option for the kickstart script. -```bash -# kickstart.sh -bash kickstart.sh --local-files /tmp/netdata-(version-number-here).tar.gz /tmp/sha256sums.txt /tmp/go.d.plugin-(version-number-here).(OS)-(architecture).tar.gz /tmp/config.tar.gz /tmp/install-required-packages.sh +## Installing on the target system -# kickstart-static64.sh -bash kickstart-static64.sh --local-files /tmp/netdata-(version-number-here).gz.run /tmp/sha256sums.txt -``` +Once you have prepared the offline install source, you need to copy the offline install source directory to the +target system. This can be done in any manner you like, as long as filenames are not changed. + +After copying the files, simply run the `install.sh` script located in the +offline install source directory. It accepts all the [same options as the kickstart +script](/packaging/installer/methods/kickstart.md#optional-parameters-to-alter-your-installation) for further +customization of the installation, though it will default to not enabling automatic updates (as they are not +supported on offline installs). ## What's next? diff --git a/packaging/installer/netdata-uninstaller.sh b/packaging/installer/netdata-uninstaller.sh index f2cc7b7c..45ec73fc 100755 --- a/packaging/installer/netdata-uninstaller.sh +++ b/packaging/installer/netdata-uninstaller.sh @@ -10,6 +10,8 @@ # # Author: Paweł Krupa <paulfantom@gmail.com> # Author: Pavlos Emm. Katsoulakis <paul@netdata.cloud> +# +# Next unused error code: R0005 usage="$(basename "$0") [-h] [-f ] -- program to calculate the answer to life, the universe and everything @@ -51,17 +53,57 @@ while :; do esac done +if [ -n "${script_source}" ]; then + script_name="$(basename "${script_source}")" +else + script_name="netdata-uninstaller.sh" +fi + +info() { + echo >&2 "$(date) : INFO: ${script_name}: " "${1}" +} + +error() { + echo >&2 "$(date) : ERROR: ${script_name}: " "${1}" + if [ -n "${NETDATA_SAVE_WARNINGS}" ]; then + NETDATA_WARNINGS="${NETDATA_WARNINGS}\n - ${1}" + fi +} + +fatal() { + echo >&2 "$(date) : FATAL: ${script_name}: FAILED TO UNINSTALL NETDATA: " "${1}" + if [ -n "${NETDATA_SAVE_WARNINGS}" ]; then + NETDATA_WARNINGS="${NETDATA_WARNINGS}\n - ${1}" + fi + exit_reason "${1}" "${2}" + exit 1 +} + +exit_reason() { + if [ -n "${NETDATA_SAVE_WARNINGS}" ]; then + EXIT_REASON="${1}" + EXIT_CODE="${2}" + if [ -n "${NETDATA_PROPAGATE_WARNINGS}" ]; then + export EXIT_REASON + export EXIT_CODE + export NETDATA_WARNINGS + fi + fi +} + if [ "$YES" != "1" ]; then echo >&2 "This script will REMOVE netdata from your system." echo >&2 "Run it again with --yes to do it." + exit_reason "User did not accept uninstalling." R0001 exit 1 fi if [ "$(id -u)" -ne 0 ]; then - echo >&2 "This script SHOULD be run as root or otherwise it won't delete all installed components." + error "This script SHOULD be run as root or otherwise it won't delete all installed components." key="n" read -r 1 -p "Do you want to continue as non-root user [y/n] ? " key if [ "$key" != "y" ] && [ "$key" != "Y" ]; then + exit_reason "User cancelled uninstall." R0002 exit 1 fi fi @@ -107,7 +149,7 @@ create_tmp_directory() { if [ -z "${TMPDIR}" ] || _cannot_use_tmpdir "${TMPDIR}"; then if _cannot_use_tmpdir /tmp; then if _cannot_use_tmpdir "${PWD}"; then - fatal "Unable to find a usable temporary directory. Please set \$TMPDIR to a path that is both writable and allows execution of files and try again." F0400 + fatal "Unable to find a usable temporary directory. Please set \$TMPDIR to a path that is both writable and allows execution of files and try again." R0003 else TMPDIR="${PWD}" fi @@ -325,14 +367,6 @@ setup_terminal() { } setup_terminal || echo > /dev/null -run_ok() { - printf >&2 "%s OK %s\n\n" "${TPUT_BGGREEN}${TPUT_WHITE}${TPUT_BOLD}" "${TPUT_RESET}" -} - -run_failed() { - printf >&2 "%s FAILED %s\n\n" "${TPUT_BGRED}${TPUT_WHITE}${TPUT_BOLD}" "${TPUT_RESET}" -} - ESCAPED_PRINT_METHOD= if printf "%s " test > /dev/null 2>&1; then ESCAPED_PRINT_METHOD="printfq" @@ -373,10 +407,11 @@ run() { ret=$? if [ ${ret} -ne 0 ]; then - run_failed + printf >&2 "%s FAILED %s\n\n" "${TPUT_BGRED}${TPUT_WHITE}${TPUT_BOLD}" "${TPUT_RESET}" printf >> "${run_logfile}" "FAILED with exit code %s\n" "${ret}" + NETDATA_WARNINGS="${NETDATA_WARNINGS}\n - Command \"${*}\" failed with exit code ${ret}." else - run_ok + printf >&2 "%s OK %s\n\n" "${TPUT_BGGREEN}${TPUT_WHITE}${TPUT_BOLD}" "${TPUT_RESET}" printf >> "${run_logfile}" "OK\n" fi @@ -387,14 +422,14 @@ portable_del_group() { groupname="${1}" # Check if group exist - echo >&2 "Removing ${groupname} user group ..." + info "Removing ${groupname} user group ..." # Linux if command -v groupdel 1> /dev/null 2>&1; then if grep -q "${groupname}" /etc/group; then run groupdel "${groupname}" && return 0 else - echo >&2 "Group ${groupname} already removed in a previous step." + info "Group ${groupname} already removed in a previous step." return 0 fi fi @@ -404,12 +439,12 @@ portable_del_group() { if dseditgroup -o read netdata 1> /dev/null 2>&1; then run dseditgroup -o delete "${groupname}" && return 0 else - echo >&2 "Could not find group ${groupname}, nothing to do" + info "Could not find group ${groupname}, nothing to do" return 0 fi fi - echo >&2 "Group ${groupname} was not automatically removed, you might have to remove it manually" + error "Group ${groupname} was not automatically removed, you might have to remove it manually" return 1 } @@ -453,7 +488,7 @@ issystemd() { portable_del_user() { username="${1}" - echo >&2 "Deleting ${username} user account ..." + info "Deleting ${username} user account ..." # Linux if command -v userdel 1> /dev/null 2>&1; then @@ -465,7 +500,7 @@ portable_del_user() { run sysadminctl -deleteUser "${username}" && return 0 fi - echo >&2 "User ${username} could not be deleted from system, you might have to remove it manually" + error "User ${username} could not be deleted from system, you might have to remove it manually" return 1 } @@ -474,7 +509,7 @@ portable_del_user_from_group() { username="${2}" # username is not in group - echo >&2 "Deleting ${username} user from ${groupname} group ..." + info "Deleting ${username} user from ${groupname} group ..." # Linux if command -v gpasswd 1> /dev/null 2>&1; then @@ -496,16 +531,16 @@ portable_del_user_from_group() { run dseditgroup -o delete -u "${username}" "${groupname}" && return 0 fi - echo >&2 "Failed to delete user ${username} from group ${groupname} !" + error "Failed to delete user ${username} from group ${groupname} !" return 1 } quit_msg() { echo if [ "$FILE_REMOVAL_STATUS" -eq 0 ]; then - echo >&2 "Something went wrong :(" + fatal "Failed to completely remove Netdata from this system." R0004 else - echo >&2 "Netdata files were successfully removed from your system" + info "Netdata files were successfully removed from your system" fi } @@ -513,7 +548,7 @@ rm_file() { FILE="$1" if [ -f "${FILE}" ]; then if user_input "Do you want to delete this file '$FILE' ? "; then - run rm -v "${FILE}" + run rm -v "${FILE}" fi fi } @@ -559,10 +594,10 @@ stop_netdata_on_pid() { pidisnetdata "${pid}" || return 0 - printf >&2 "Stopping netdata on pid %s ..." "${pid}" + info "Stopping netdata on pid ${pid} ..." while [ -n "$pid" ] && [ ${ret} -eq 0 ]; do if [ ${count} -gt 24 ]; then - echo >&2 "Cannot stop the running netdata on pid ${pid}." + error "Cannot stop the running netdata on pid ${pid}." return 1 fi @@ -587,11 +622,11 @@ stop_netdata_on_pid() { echo >&2 if [ ${ret} -eq 0 ]; then - echo >&2 "SORRY! CANNOT STOP netdata ON PID ${pid} !" + error "SORRY! CANNOT STOP netdata ON PID ${pid} !" return 1 fi - echo >&2 "netdata on pid ${pid} stopped." + info "netdata on pid ${pid} stopped." return 0 } @@ -615,6 +650,7 @@ netdata_pids() { stop_all_netdata() { p='' + stop_success=0 if [ "$(id -u)" -eq 0 ]; then uname="$(uname 2> /dev/null)" @@ -622,32 +658,38 @@ stop_all_netdata() { # Any of these may fail, but we need to not bail if they do. if issystemd; then if systemctl stop netdata; then + stop_success=1 sleep 5 fi elif [ "${uname}" = "Darwin" ]; then if launchctl stop netdata; then + stop_success=1 sleep 5 fi elif [ "${uname}" = "FreeBSD" ]; then if /etc/rc.d/netdata stop; then + stop_success=1 sleep 5 fi else if service netdata stop; then + stop_success=1 sleep 5 fi fi fi - if [ -n "$(netdata_pids)" ] && [ -n "$(command -v netdatacli)" ]; then - netdatacli shutdown-agent - sleep 20 - fi + if [ "$stop_success" = "0" ]; then + if [ -n "$(netdata_pids)" ] && [ -n "$(command -v netdatacli)" ]; then + netdatacli shutdown-agent + sleep 20 + fi - for p in $(netdata_pids); do - # shellcheck disable=SC2086 - stop_netdata_on_pid ${p} - done + for p in $(netdata_pids); do + # shellcheck disable=SC2086 + stop_netdata_on_pid ${p} + done + fi } trap quit_msg EXIT @@ -657,7 +699,7 @@ trap quit_msg EXIT . "${ENVIRONMENT_FILE}" || exit 1 #### STOP NETDATA -echo >&2 "Stopping a possibly running netdata..." +info "Stopping a possibly running netdata..." stop_all_netdata #### REMOVE NETDATA FILES diff --git a/packaging/installer/netdata-updater.sh b/packaging/installer/netdata-updater.sh index 63280437..e4cb29a4 100755 --- a/packaging/installer/netdata-updater.sh +++ b/packaging/installer/netdata-updater.sh @@ -28,6 +28,8 @@ # Author: Pavlos Emm. Katsoulakis <paul@netdata.cloud> # Author: Austin S. Hemmelgarn <austin@netdata.cloud> +# Next unused error code: U001A + set -e PACKAGES_SCRIPT="https://raw.githubusercontent.com/netdata/netdata/master/packaging/installer/install-required-packages.sh" @@ -55,18 +57,41 @@ else fi info() { - echo >&3 "$(date) : INFO: ${script_name}: " "${@}" + echo >&3 "$(date) : INFO: ${script_name}: " "${1}" +} + +warning() { + echo >&3 "$(date) : WARNING: ${script_name}: " "${@}" } error() { - echo >&3 "$(date) : ERROR: ${script_name}: " "${@}" + echo >&3 "$(date) : ERROR: ${script_name}: " "${1}" + if [ -n "${NETDATA_SAVE_WARNINGS}" ]; then + NETDATA_WARNINGS="${NETDATA_WARNINGS}\n - ${1}" + fi } fatal() { - echo >&3 "$(date) : FATAL: ${script_name}: FAILED TO UPDATE NETDATA: " "${@}" + echo >&3 "$(date) : FATAL: ${script_name}: FAILED TO UPDATE NETDATA: " "${1}" + if [ -n "${NETDATA_SAVE_WARNINGS}" ]; then + NETDATA_WARNINGS="${NETDATA_WARNINGS}\n - ${1}" + fi + exit_reason "${1}" "${2}" exit 1 } +exit_reason() { + if [ -n "${NETDATA_SAVE_WARNINGS}" ]; then + EXIT_REASON="${1}" + EXIT_CODE="${2}" + if [ -n "${NETDATA_PROPAGATE_WARNINGS}" ]; then + export EXIT_REASON + export EXIT_CODE + export NETDATA_WARNINGS + fi + fi +} + issystemd() { # if the directory /lib/systemd/system OR /usr/lib/systemd/system (SLES 12.x) does not exit, it is not systemd if [ ! -d /lib/systemd/system ] && [ ! -d /usr/lib/systemd/system ]; then @@ -158,8 +183,7 @@ enable_netdata_updater() { updater_type="$(_get_scheduler_type)" ;; *) - error "Unrecognized updater type ${updater_type} requested. Supported types are 'systemd', 'interval', and 'crontab'." - exit 1 + fatal "Unrecognized updater type ${updater_type} requested. Supported types are 'systemd', 'interval', and 'crontab'." U0001 ;; esac @@ -172,8 +196,7 @@ enable_netdata_updater() { info "If the update process fails, the failure will be logged to the systemd journal just like a regular service failure." info "Successful updates should produce empty logs." else - error "Systemd-based auto-update scheduling requested, but this does not appear to be a systemd system." - error "Auto-updates have NOT been enabled." + error "Systemd-based auto-update scheduling requested, but this does not appear to be a systemd system. Auto-updates have NOT been enabled." return 1 fi ;; @@ -185,8 +208,7 @@ enable_netdata_updater() { info "If the update process fails and you have email notifications set up correctly for cron on this system, you should receive an email notification of the failure." info "Successful updates will not send an email." else - error "Interval-based auto-update scheduling requested, but I could not find an interval scheduling directory." - error "Auto-updates have NOT been enabled." + error "Interval-based auto-update scheduling requested, but I could not find an interval scheduling directory. Auto-updates have NOT been enabled." return 1 fi ;; @@ -200,14 +222,12 @@ enable_netdata_updater() { info "If the update process fails and you have email notifications set up correctly for cron on this system, you should receive an email notification of the failure." info "Successful updates will not send an email." else - error "Crontab-based auto-update scheduling requested, but there is no '/etc/cron.d'." - error "Auto-updates have NOT been enabled." + error "Crontab-based auto-update scheduling requested, but there is no '/etc/cron.d'. Auto-updates have NOT been enabled." return 1 fi ;; *) - error "Unable to determine what type of auto-update scheduling to use." - error "Auto-updates have NOT been enabled." + error "Unable to determine what type of auto-update scheduling to use. Auto-updates have NOT been enabled." return 1 esac @@ -251,7 +271,7 @@ safe_sha256sum() { elif command -v shasum > /dev/null 2>&1; then shasum -a 256 "$@" else - fatal "I could not find a suitable checksum binary to use" + fatal "I could not find a suitable checksum binary to use" U0002 fi } @@ -294,7 +314,7 @@ create_tmp_directory() { if [ -z "${TMPDIR}" ] || _cannot_use_tmpdir "${TMPDIR}" ; then if _cannot_use_tmpdir /tmp ; then if _cannot_use_tmpdir "${PWD}" ; then - fatal "Unable to find a usable temporary directory. Please set \$TMPDIR to a path that is both writable and allows execution of files and try again." + fatal "Unable to find a usable temporary directory. Please set \$TMPDIR to a path that is both writable and allows execution of files and try again." U0003 else TMPDIR="${PWD}" fi @@ -334,9 +354,9 @@ download() { if [ ${ret} -eq 0 ]; then return 0 elif [ ${ret} -eq 255 ]; then - fatal "I need curl or wget to proceed, but neither is available on this system." + fatal "I need curl or wget to proceed, but neither is available on this system." U0004 else - fatal "Cannot download ${url}" + fatal "Cannot download ${url}" U0005 fi } @@ -349,7 +369,7 @@ get_netdata_latest_tag() { elif command -v wget >/dev/null 2>&1; then tag=$(wget --max-redirect=0 "${url}" 2>&1 | grep Location | cut -d ' ' -f2 | grep -m 1 -o '[^/]*$') else - fatal "I need curl or wget to proceed, but neither of them are available on this system." + fatal "I need curl or wget to proceed, but neither of them are available on this system." U0006 fi echo "${tag}" >"${dest}" @@ -440,10 +460,10 @@ get_latest_version() { } validate_environment_file() { - if [ -n "${RELEASE_CHANNEL}" ] && [ -n "${NETDATA_PREFIX}" ] && [ -n "${REINSTALL_OPTIONS}" ] && [ -n "${IS_NETDATA_STATIC_BINARY}" ]; then + if [ -n "${NETDATA_PREFIX+SET_BUT_NULL}" ] && [ -n "${REINSTALL_OPTIONS+SET_BUT_NULL}" ]; then return 0 else - error "Environment file located at ${ENVIRONMENT_FILE} is not valid, unable to update." + fatal "Environment file located at ${ENVIRONMENT_FILE} is not valid, unable to update." U0007 fi } @@ -513,7 +533,7 @@ update_build() { RUN_INSTALLER=0 ndtmpdir=$(create_tmp_directory) - cd "$ndtmpdir" || exit 1 + cd "$ndtmpdir" || fatal "Failed to change current working directory to ${ndtmpdir}" U0016 install_build_dependencies @@ -526,12 +546,12 @@ update_build() { info "Newest version is already installed" else if ! grep netdata-latest.tar.gz sha256sum.txt | safe_sha256sum -c - >&3 2>&3; then - fatal "Tarball checksum validation failed. Stopping netdata upgrade and leaving tarball in ${ndtmpdir}\nUsually this is a result of an older copy of the tarball or checksum file being cached somewhere upstream and can be resolved by retrying in an hour." + fatal "Tarball checksum validation failed. Stopping netdata upgrade and leaving tarball in ${ndtmpdir}\nUsually this is a result of an older copy of the tarball or checksum file being cached somewhere upstream and can be resolved by retrying in an hour." U0008 fi NEW_CHECKSUM="$(safe_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 "$(find . -maxdepth 1 -name "netdata-${path_version}*" | head -n 1)" || exit 1 + cd "$(find . -maxdepth 1 -name "netdata-${path_version}*" | head -n 1)" || fatal "Failed to switch to build directory" U0017 RUN_INSTALLER=1 fi fi @@ -550,7 +570,7 @@ update_build() { do_not_start="--dont-start-it" fi - env="TMPDIR='${TMPDIR}'" + env="env TMPDIR=${TMPDIR}" if [ -n "${NETDATA_SELECTED_DASHBOARD}" ]; then env="${env} NETDATA_SELECTED_DASHBOARD=${NETDATA_SELECTED_DASHBOARD}" @@ -558,7 +578,7 @@ update_build() { if [ ! -x ./netdata-installer.sh ]; then if [ "$(find . -mindepth 1 -maxdepth 1 -type d | wc -l)" -eq 1 ] && [ -x "$(find . -mindepth 1 -maxdepth 1 -type d)/netdata-installer.sh" ]; then - cd "$(find . -mindepth 1 -maxdepth 1 -type d)" || exit 1 + cd "$(find . -mindepth 1 -maxdepth 1 -type d)" || fatal "Failed to switch to build directory" U0018 fi fi @@ -573,7 +593,18 @@ update_build() { fi info "Re-installing netdata..." - eval "${env} ./netdata-installer.sh ${REINSTALL_OPTIONS} --dont-wait ${do_not_start}" >&3 2>&3 || fatal "FAILED TO COMPILE/INSTALL NETDATA" + export NETDATA_SAVE_WARNINGS=1 + export NETDATA_PROPAGATE_WARNINGS=1 + export NETDATA_WARNINGS="${NETDATA_WARNINGS}" + # shellcheck disable=SC2086 + if ! ${env} ./netdata-installer.sh ${REINSTALL_OPTIONS} --dont-wait ${do_not_start} >&3 2>&3; then + if [ -n "${EXIT_REASON}" ]; then + fatal "Failed to rebuild existing netdata install: ${EXIT_REASON}" "U${EXIT_CODE}" + else + fatal "Failed to rebuild existing netdata reinstall." UI0000 + fi + fi + eval "${env} ./netdata-installer.sh ${REINSTALL_OPTIONS} --dont-wait ${do_not_start}" >&3 2>&3 || fatal "FAILED TO COMPILE/INSTALL NETDATA" U0009 # We no longer store checksum info here. but leave this so that we clean up all environment files upon next update. sed -i '/NETDATA_TARBALL/d' "${ENVIRONMENT_FILE}" @@ -595,14 +626,14 @@ update_static() { PREVDIR="$(pwd)" info "Entering ${ndtmpdir}" - cd "${ndtmpdir}" || exit 1 + cd "${ndtmpdir}" || fatal "Failed to change current working directory to ${ndtmpdir}" U0019 if update_available; then sysarch="$(uname -m)" download "${NETDATA_TARBALL_CHECKSUM_URL}" "${ndtmpdir}/sha256sum.txt" download "${NETDATA_TARBALL_URL}" "${ndtmpdir}/netdata-${sysarch}-latest.gz.run" if ! grep "netdata-${sysarch}-latest.gz.run" "${ndtmpdir}/sha256sum.txt" | safe_sha256sum -c - > /dev/null 2>&1; then - fatal "Static binary checksum validation failed. Stopping netdata installation and leaving binary in ${ndtmpdir}\nUsually this is a result of an older copy of the file being cached somewhere and can be resolved by simply retrying in an hour." + fatal "Static binary checksum validation failed. Stopping netdata installation and leaving binary in ${ndtmpdir}\nUsually this is a result of an older copy of the file being cached somewhere and can be resolved by simply retrying in an hour." U000A fi if [ -e /opt/netdata/etc/netdata/.install-type ] ; then @@ -637,7 +668,7 @@ update_binpkg() { elif [ -s "/usr/lib/os-release" ] && [ -r "/usr/lib/os-release" ]; then os_release_file="/usr/lib/os-release" else - fatal "Cannot find an os-release file ..." F0401 + fatal "Cannot find an os-release file ..." U000B fi # shellcheck disable=SC1090 @@ -654,7 +685,7 @@ update_binpkg() { opensuse-leap) DISTRO_COMPAT_NAME="opensuse" ;; - rhel) + almalinux|rocky|rhel) DISTRO_COMPAT_NAME="centos" ;; *) @@ -675,7 +706,7 @@ update_binpkg() { debian) pm_cmd="apt-get" repo_subcmd="update" - upgrade_cmd="upgrade" + upgrade_cmd="--only-upgrade install" pkg_install_opts="${interactive_opts}" repo_update_opts="${interactive_opts}" pkg_installed_check="dpkg -s" @@ -684,7 +715,7 @@ update_binpkg() { ubuntu) pm_cmd="apt-get" repo_subcmd="update" - upgrade_cmd="upgrade" + upgrade_cmd="--only-upgrade install" pkg_install_opts="${interactive_opts}" repo_update_opts="${interactive_opts}" pkg_installed_check="dpkg -s" @@ -733,20 +764,24 @@ update_binpkg() { if [ -n "${repo_subcmd}" ]; then # shellcheck disable=SC2086 - env ${env} ${pm_cmd} ${repo_subcmd} ${repo_update_opts} || fatal "Failed to update repository metadata." + env ${env} ${pm_cmd} ${repo_subcmd} ${repo_update_opts} >&3 2>&3 || fatal "Failed to update repository metadata." U000C fi for repopkg in netdata-repo netdata-repo-edge; do if ${pkg_installed_check} ${repopkg} > /dev/null 2>&1; then # shellcheck disable=SC2086 - env ${env} ${pm_cmd} ${upgrade_cmd} ${pkg_install_opts} ${repopkg} || fatal "Failed to update Netdata repository config." + env ${env} ${pm_cmd} ${upgrade_cmd} ${pkg_install_opts} ${repopkg} >&3 2>&3 || fatal "Failed to update Netdata repository config." U000D # shellcheck disable=SC2086 - env ${env} ${pm_cmd} ${repo_subcmd} ${repo_update_opts} || fatal "Failed to update repository metadata." + if [ -n "${repo_subcmd}" ]; then + env ${env} ${pm_cmd} ${repo_subcmd} ${repo_update_opts} >&3 2>&3 || fatal "Failed to update repository metadata." U000E + fi fi done # shellcheck disable=SC2086 - env ${env} ${pm_cmd} ${upgrade_cmd} ${pkg_install_opts} netdata || fatal "Failed to update Netdata package." + env ${env} ${pm_cmd} ${upgrade_cmd} ${pkg_install_opts} netdata >&3 2>&3 || fatal "Failed to update Netdata package." U000F + [ -n "${logfile}" ] && rm "${logfile}" && logfile= + return 0 } # Simple function to encapsulate original updater behavior. @@ -793,19 +828,19 @@ if [ "${ENVIRONMENT_FILE}" = "THIS_SHOULD_BE_REPLACED_BY_INSTALLER_SCRIPT" ]; th elif [ -r "${itpath}" ]; then ENVIRONMENT_FILE="$(dirname "${itpath}")/.environment" else - fatal "Cannot find environment file or install type file, unable to update." + fatal "Cannot find environment file or install type file, unable to update." U0010 fi fi fi if [ -r "${ENVIRONMENT_FILE}" ] ; then # shellcheck source=/dev/null - . "${ENVIRONMENT_FILE}" || exit 1 + . "${ENVIRONMENT_FILE}" || fatal "Failed to source ${ENVIRONMENT_FILE}" U0014 fi if [ -r "$(dirname "${ENVIRONMENT_FILE}")/.install-type" ]; then # shellcheck source=/dev/null - . "$(dirname "${ENVIRONMENT_FILE}")/.install-type" || exit 1 + . "$(dirname "${ENVIRONMENT_FILE}")/.install-type" || fatal "Failed to source $(dirname "${ENVIRONMENT_FILE}")/.install-type" U0015 fi while [ -n "${1}" ]; do @@ -854,7 +889,7 @@ export NETDATA_LIB_DIR="${NETDATA_LIB_DIR:-${NETDATA_PREFIX}/var/lib/netdata}" export NETDATA_NIGHTLIES_BASEURL="${NETDATA_NIGHTLIES_BASEURL:-https://storage.googleapis.com/netdata-nightlies}" if echo "$INSTALL_TYPE" | grep -qv ^binpkg && [ "${INSTALL_UID}" != "$(id -u)" ]; then - fatal "You are running this script as user with uid $(id -u). We recommend to run this script as root (user with uid 0)" + fatal "You are running this script as user with uid $(id -u). We recommend to run this script as root (user with uid 0)" U0011 fi self_update @@ -862,12 +897,12 @@ self_update # shellcheck disable=SC2153 case "${INSTALL_TYPE}" in *-build) - validate_environment_file || exit 1 + validate_environment_file set_tarball_urls "${RELEASE_CHANNEL}" "${IS_NETDATA_STATIC_BINARY}" update_build && exit 0 ;; *-static*) - validate_environment_file || exit 1 + validate_environment_file set_tarball_urls "${RELEASE_CHANNEL}" "${IS_NETDATA_STATIC_BINARY}" update_static && exit 0 ;; @@ -875,22 +910,22 @@ case "${INSTALL_TYPE}" in update_binpkg && exit 0 ;; "") # Fallback case for no `.install-type` file. This just works like the old install type detection. - validate_environment_file || exit 1 + validate_environment_file update_legacy ;; custom) # At this point, we _should_ have a valid `.environment` file, but it's best to just check. # If we do, then behave like the legacy updater. - if validate_environment_file; then + if validate_environment_file && [ -n "${IS_NETDATA_STATIC_BINARY}" ]; then update_legacy else - fatal "This script does not support updating custom installations without valid environment files." + fatal "This script does not support updating custom installations without valid environment files." U0012 fi ;; oci) - fatal "This script does not support updating Netdata inside our official Docker containers, please instead update the container itself." + fatal "This script does not support updating Netdata inside our official Docker containers, please instead update the container itself." U0013 ;; *) - fatal "Unrecognized installation type (${INSTALL_TYPE}), unable to update." + fatal "Unrecognized installation type (${INSTALL_TYPE}), unable to update." U0014 ;; esac |