summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAustin S. Hemmelgarn <austin@netdata.cloud>2024-01-17 06:49:57 -0500
committerGitHub <noreply@github.com>2024-01-17 06:49:57 -0500
commitb70e223e80f432b4dd46d3653f4c071a3c0b9b3f (patch)
treeb8446f037828d68c813b4703209678fd010e7dde
parente0e24f8b737df7161b400be228dc65ce48452eee (diff)
Add check to avoid auto-installing new major versions of Netdata. (#15898)
* Add check to avoid auto-installing new major versions of Netdata. With the specific intent of avoiding breaking user’s systems. * Add latest tag check override. * Fix local testing fallback case. * Fix version parsing code. * Allow major version updates in CI jobs. * Fix fetching latest tag. * Properly fix CI jobs. * Switch to using a list of accepted major versions. And pre-populate it with versions we think are fine. * Fix CI again. * Fix check logic.
-rwxr-xr-x.github/scripts/run-updater-check.sh3
-rw-r--r--.github/workflows/build.yml11
-rw-r--r--packaging/installer/UPDATE.md2
-rwxr-xr-xpackaging/installer/netdata-updater.sh122
-rw-r--r--system/netdata-updater.conf26
5 files changed, 145 insertions, 19 deletions
diff --git a/.github/scripts/run-updater-check.sh b/.github/scripts/run-updater-check.sh
index 1224d8f674..2e70a10aff 100755
--- a/.github/scripts/run-updater-check.sh
+++ b/.github/scripts/run-updater-check.sh
@@ -12,7 +12,8 @@ echo "::group::>>> Pre-Update Netdata Build Info"
netdata -W buildinfo
echo "::endgroup::"
echo ">>> Updating Netdata..."
-export NETDATA_BASE_URL="http://localhost:8080/artifacts/" # Pull the tarball from the local web server.
+export NETDATA_BASE_URL="http://localhost:8080/artifacts" # Pull the tarball from the local web server.
+echo 'NETDATA_ACCEPT_MAJOR_VERSIONS="1 9999"' > /etc/netdata/netdata-updater.conf
timeout 3600 /netdata/packaging/installer/netdata-updater.sh --not-running-from-cron --no-updater-self-update
case "$?" in
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 4fd0a31e54..69f49c49d6 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -492,14 +492,17 @@ jobs:
id: prepare
if: needs.file-check.outputs.run == 'true'
run: |
- mkdir -p artifacts/download/latest || exit 1
- echo "9999.0.0-0" > artifacts/download/latest/latest-version.txt || exit 1
- cp dist-tarball/* artifacts/download/latest || exit 1
- cd artifacts/download/latest || exit 1
+ mkdir -p artifacts/download/v9999.0.0 || exit 1
+ mkdir -p artifacts/latest || exit 1
+ echo "v9999.0.0" > artifacts/latest/latest-version.txt || exit 1
+ cp dist-tarball/* artifacts/download/v9999.0.0 || exit 1
+ cd artifacts/download/v9999.0.0 || exit 1
ln -s ${{ needs.build-dist.outputs.distfile }} netdata-latest.tar.gz || exit 1
ls -lFh
sha256sum -b ./* > "sha256sums.txt" || exit 1
cat sha256sums.txt
+ cd ../.. || exit 1
+ ls -lR
- name: Fetch test environment
id: fetch-test-environment
if: needs.file-check.outputs.run == 'true'
diff --git a/packaging/installer/UPDATE.md b/packaging/installer/UPDATE.md
index a16179abda..50d8c8270b 100644
--- a/packaging/installer/UPDATE.md
+++ b/packaging/installer/UPDATE.md
@@ -204,6 +204,8 @@ The following configuration options are currently supported:
as a scheduled task. This random delay helps avoid issues resulting from too many nodes trying to reconnect to
the Cloud at the same time. The default value is 3600, which corresponds to one hour. Most users should not ever
need to change this.
+- `NETDATA_MAJOR_VERSION_UPDATES`: If set to a value other than 0, then new major versions will be installed
+ without user confirmation. Must be set to a non-zero value for automated updates to install new major versions.
- `NETDATA_NO_SYSTEMD_JOURNAL`: If set to a value other than 0, skip attempting to install the
`netdata-plugin-systemd-journal` package on supported systems on update. This optional package will be installed
by default on supported systems by the updater if this option is not set. Only affects systems using native packages.
diff --git a/packaging/installer/netdata-updater.sh b/packaging/installer/netdata-updater.sh
index 61b2174a26..268465ff30 100755
--- a/packaging/installer/netdata-updater.sh
+++ b/packaging/installer/netdata-updater.sh
@@ -28,7 +28,7 @@
# Author: Pavlos Emm. Katsoulakis <paul@netdata.cloud>
# Author: Austin S. Hemmelgarn <austin@netdata.cloud>
-# Next unused error code: U001B
+# Next unused error code: U001D
set -e
@@ -36,10 +36,12 @@ PACKAGES_SCRIPT="https://raw.githubusercontent.com/netdata/netdata/master/packag
NETDATA_STABLE_BASE_URL="${NETDATA_BASE_URL:-https://github.com/netdata/netdata/releases}"
NETDATA_NIGHTLY_BASE_URL="${NETDATA_BASE_URL:-https://github.com/netdata/netdata-nightlies/releases}"
+NETDATA_DEFAULT_ACCEPT_MAJOR_VERSIONS="1 2"
# Following variables are intended to be overridden by the updater config file.
NETDATA_UPDATER_JITTER=3600
NETDATA_NO_SYSTEMD_JOURNAL=0
+NETDATA_ACCEPT_MAJOR_VERSIONS=''
script_dir="$(CDPATH='' cd -- "$(dirname -- "$0")" && pwd -P)"
@@ -171,6 +173,38 @@ _get_scheduler_type() {
fi
}
+confirm() {
+ prompt="${1} [y/n]"
+
+ while true; do
+ echo "${prompt}"
+ read -r yn
+
+ case "$yn" in
+ [Yy]*) return 0;;
+ [Nn]*) return 1;;
+ *) echo "Please answer yes or no.";;
+ esac
+ done
+}
+
+warn_major_update() {
+ nmv_suffix="New major versions generally involve breaking changes, and may not work in the same way as older versions."
+
+ if [ "${INTERACTIVE}" -eq 0 ]; then
+ warning "Would update to a new major version of Netdata. ${nmv_suffix}"
+ warning "To install the new major version anyway, either run the updater interactively, or include the new major version number in the NETDATA_ACCEPT_MAJOR_VERSIONS variable in ${UPDATER_CONFIG_PATH}."
+ fatal "Aborting update to new major version to avoid breaking things." U001B
+ else
+ warning "This update will install a new major version of Netdata. ${nmv_suffix}"
+ if confirm "Are you sure you want to update to a new major version of Netdata?"; then
+ notice "User accepted update to new major version of Netdata."
+ else
+ fatal "Aborting update to new major version at user request." U001C
+ fi
+ fi
+}
+
install_build_dependencies() {
bash="$(command -v bash 2> /dev/null)"
@@ -394,19 +428,33 @@ download() {
get_netdata_latest_tag() {
url="${1}/latest"
- dest="${2}"
check_for_curl
if [ -n "${curl}" ]; then
- tag=$("${curl}" "${url}" -s -L -I -o /dev/null -w '%{url_effective}' | grep -m 1 -o '[^/]*$')
+ tag=$("${curl}" "${url}" -s -L -I -o /dev/null -w '%{url_effective}' | grep -Eom 1 '[^/]*/?$')
elif command -v wget >/dev/null 2>&1; then
- tag=$(wget -S -O /dev/null "${url}" 2>&1 | grep -m 1 Location | grep -o '[^/]*$')
+ tag=$(wget -S -O /dev/null "${url}" 2>&1 | grep -m 1 Location | grep -Eo '[^/]*/?$')
else
fatal "I need curl or wget to proceed, but neither of them are available on this system." U0006
fi
- echo "${tag}" >"${dest}"
+ # Fallback case for simpler local testing.
+ if echo "${tag}" | grep -Eq 'latest/?$'; then
+ if _safe_download "${url}/latest-version.txt" ./ndupdate-version.txt; then
+ tag="$(cat ./ndupdate-version.txt)"
+
+ if grep -q 'Not Found' ./ndupdate-version.txt; then
+ tag="latest"
+ fi
+
+ rm -f ./ndupdate-version.txt
+ else
+ tag="latest"
+ fi
+ fi
+
+ echo "${tag}"
}
newer_commit_date() {
@@ -494,9 +542,9 @@ parse_version() {
get_latest_version() {
if [ "${RELEASE_CHANNEL}" = "stable" ]; then
- get_netdata_latest_tag "${NETDATA_STABLE_BASE_URL}" /dev/stdout
+ get_netdata_latest_tag "${NETDATA_STABLE_BASE_URL}"
else
- get_netdata_latest_tag "${NETDATA_NIGHTLY_BASE_URL}" /dev/stdout
+ get_netdata_latest_tag "${NETDATA_NIGHTLY_BASE_URL}"
fi
}
@@ -513,6 +561,7 @@ update_available() {
info "Force update requested"
return 0
fi
+
basepath="$(dirname "$(dirname "$(dirname "${NETDATA_LIB_DIR}")")")"
searchpath="${basepath}/bin:${basepath}/sbin:${basepath}/usr/bin:${basepath}/usr/sbin:${PATH}"
searchpath="${basepath}/netdata/bin:${basepath}/netdata/sbin:${basepath}/netdata/usr/bin:${basepath}/netdata/usr/sbin:${searchpath}"
@@ -542,6 +591,27 @@ update_available() {
return 1
else
info "Update available"
+
+ if [ "${current_version}" -ne 0 ] && [ "${latest_version}" -ne 0 ]; then
+ current_major="$(${ndbinary} -v | cut -f 2 -d ' ' | cut -f 1 -d '.' | tr -d 'v')"
+ latest_major="$(echo "${latest_tag}" | cut -f 1 -d '.' | tr -d 'v')"
+
+ if [ "${current_major}" -ne "${latest_major}" ]; then
+ update_safe=0
+
+ for v in ${NETDATA_ACCEPT_MAJOR_VERSIONS}; do
+ if [ "${current_major}" -eq "${v}" ]; then
+ update_safe=1
+ break
+ fi
+ done
+
+ if [ "${update_safe}" -eq 0 ]; then
+ warn_major_update
+ fi
+ fi
+ fi
+
return 0
fi
}
@@ -561,11 +631,11 @@ set_tarball_urls() {
fi
if [ "$1" = "stable" ]; then
- latest="$(get_netdata_latest_tag "${NETDATA_STABLE_BASE_URL}" /dev/stdout)"
+ latest="$(get_netdata_latest_tag "${NETDATA_STABLE_BASE_URL}")"
export NETDATA_TARBALL_URL="${NETDATA_STABLE_BASE_URL}/download/$latest/${filename}"
export NETDATA_TARBALL_CHECKSUM_URL="${NETDATA_STABLE_BASE_URL}/download/$latest/sha256sums.txt"
else
- tag="$(get_netdata_latest_tag "${NETDATA_NIGHTLY_BASE_URL}" /dev/stdout)"
+ tag="$(get_netdata_latest_tag "${NETDATA_NIGHTLY_BASE_URL}")"
export NETDATA_TARBALL_URL="${NETDATA_NIGHTLY_BASE_URL}/download/${tag}/${filename}"
export NETDATA_TARBALL_CHECKSUM_URL="${NETDATA_NIGHTLY_BASE_URL}/download/${tag}/sha256sums.txt"
fi
@@ -714,6 +784,15 @@ update_static() {
exit 0
}
+get_new_binpkg_major() {
+ case "${pm_cmd}" in
+ apt-get) apt-get --just-print upgrade 2>&1 | grep Inst | grep ' netdata ' | cut -f 3 -d ' ' | tr -d '[]' | cut -f 1 -d '.' ;;
+ yum) yum check-update netdata | grep -E '^netdata ' | awk '{print $2}' | cut -f 1 -d '.' ;;
+ dnf) dnf check-update netdata | grep -E '^netdata ' | awk '{print $2}' | cut -f 1 -d '.' ;;
+ zypper) zypper list-updates | grep '| netdata |' | cut -f 5 -d '|' | tr -d ' ' | cut -f 1 -d '.' ;;
+ esac
+}
+
update_binpkg() {
os_release_file=
if [ -s "/etc/os-release" ] && [ -r "/etc/os-release" ]; then
@@ -824,6 +903,24 @@ update_binpkg() {
fi
done
+ current_major="$(netdata -v | cut -f 2 -d ' ' | cut -f 1 -d '.' | tr -d 'v')"
+ latest_major="$(get_new_binpkg_major)"
+
+ if [ -n "${latest_major}" ] && [ "${latest_major}" -ne "${current_major}" ]; then
+ update_safe=0
+
+ for v in ${NETDATA_ACCEPT_MAJOR_VERSIONS}; do
+ if [ "${current_major}" -eq "${v}" ]; then
+ update_safe=1
+ break
+ fi
+ done
+
+ if [ "${update_safe}" -eq 0 ]; then
+ warn_major_update
+ fi
+ fi
+
# shellcheck disable=SC2086
env ${env} ${pm_cmd} ${upgrade_subcmd} ${pkg_install_opts} netdata >&3 2>&3 || fatal "Failed to update Netdata package." U000F
@@ -902,11 +999,14 @@ if [ -r "$(dirname "${ENVIRONMENT_FILE}")/.install-type" ]; then
. "$(dirname "${ENVIRONMENT_FILE}")/.install-type" || fatal "Failed to source $(dirname "${ENVIRONMENT_FILE}")/.install-type" U0015
fi
-if [ -r "$(dirname "${ENVIRONMENT_FILE}")/netdata-updater.conf" ]; then
+UPDATER_CONFIG_PATH="$(dirname "${ENVIRONMENT_FILE}")/netdata-updater.conf"
+if [ -r "${UPDATER_CONFIG_PATH}" ]; then
# shellcheck source=/dev/null
- . "$(dirname "${ENVIRONMENT_FILE}")/netdata-updater.conf"
+ . "${UPDATER_CONFIG_PATH}"
fi
+[ -z "${NETDATA_ACCEPT_MAJOR_VERSIONS}" ] && NETDATA_ACCEPT_MAJOR_VERSIONS="${NETDATA_DEFAULT_ACCEPT_MAJOR_VERSIONS}"
+
while [ -n "${1}" ]; do
case "${1}" in
--not-running-from-cron) NETDATA_NOT_RUNNING_FROM_CRON=1 ;;
diff --git a/system/netdata-updater.conf b/system/netdata-updater.conf
index 09af046be4..ac35131da3 100644
--- a/system/netdata-updater.conf
+++ b/system/netdata-updater.conf
@@ -2,10 +2,30 @@
#
# When run non-interactively, the updater script will delay some
# random number of seconds up to NETDATA_UPDATER_JITTER before
-# actually running the update. The default is 3600 (one
-# hour). Most users should not need to change this.
+# actually running the update. The default is 3600 (one hour). Most
+# users should not need to change this.
#NETDATA_UPDATER_JITTER="3600"
+# By default, the updater will update to new major versions without asking
+# for user confirmation once we consider them ready for general usage.
+#
+# You can override this behavior by setting NETDATA_ACCEPT_MAJOR_VERSIONS
+# to a space separated list of major versions you are willing to update
+# to. Attempts to update to newer major versions not listed in this variable
+# will be treated as a fatal error.
+#
+# An empty value is equivalent to the default behavior.
+#
+# This only applies to static builds and local builds. If you are using
+# our native packages, use your package manager’s existing functionality
+# to prevent updates (for example, pinning versions on APT-based systems,
+# or the DNF versionlock plugin on RHEL/Fedora).
+#
+# To lock yourself to a specific major version, set this value to exactly
+# that major version number. For example, to stay on version 1.x even
+# if 2.x has been released, set this to a value of `1`.
+#NETDATA_ACCEPT_MAJOR_VERSIONS=''
+
# On systems using our native packages, the updater will by default
# attempt to install optional plugin packages that would be installed by
# default on clean installs if those packages are supported on the system.
@@ -13,7 +33,7 @@
# This behavior can be disabled on a per-package basis using the below
# variables. Setting the variable to a value other than 0 will disable
# the corresponding package (note that you still need to remove the package
-# yourself if you don0t want it, this just controls whether the updater
+# yourself if you don't want it, this just controls whether the updater
# will try to ensure it’s installed or not).
#
# NETDATA_NO_SYSTEMD_JOURNAL controls the `netdata-plugin-systemd-journal`