@cryptotaxi247 / netdata-1 / commits / 98eeb1ae7

Adds a GHA workflow to test install-required-packages (#7949)

* Fixed shellcheck warnings/errors and some legitimate bugs in ./packaging/installer/install-required-packages.sh * Fixed erroneous \ * Removed accidentally committed test.sh :D * Remove redundant redirection on grep commands * Fixed erroneous trailing gon search/replace expression * Fixed incorrect expansion of in apt-get invocation * Fixed incorrect expanasion of on other package managers too * Fixed insistent prompt search/replace (adding space) :D * Fixed (properly) handling of opts to pakage managers using a proper array and array expansion * Re-fixed: echo * Bah humbug :D * Rebased on master * Fixed erroneous \ * Added support for CentOS 8.x * Removed extra space * Rebased on centos8_deps_2 * Added GHA workflor for testing install-required-packages * Rebased on centos8_deps_3 * Only test on archlinux:latest * Add Ubuntu 16.04 and 19.04 to the matrix * Remove test.sh :)

James Mills committed Feb 4, 2020 at 14:26 UTC 98eeb1ae7fc6beaac26bf0d5a5520242e6ebec10
2 files changed +291 -124
.github/workflows/installer.yml new
+75
@@ -0,0 +1,75 @@
1 +---
2 +name: Installer
3 +on:
4 + push:
5 + branches:
6 + - master
7 + paths:
8 + - 'packaging/installer/install-required-packages.sh'
9 + pull_request:
10 + paths:
11 + - 'packaging/installer/install-required-packages.sh'
12 +jobs:
13 + install-required-packages:
14 + name: Required Packages
15 + strategy:
16 + matrix:
17 + distro:
18 + - 'alpine:3.11'
19 + - 'alpine:3.10'
20 + - 'alpine:3.9'
21 + - 'archlinux:latest'
22 + - 'centos:8'
23 + - 'centos:7'
24 + - 'centos:6'
25 + - 'debian:buster'
26 + - 'debian:jessie'
27 + - 'debian:stretch'
28 + - 'fedora:31'
29 + - 'fedora:30'
30 + - 'fedora:29'
31 + - 'opensuse/leap:15.2'
32 + - 'opensuse/leap:15.1'
33 + - 'opensuse/leap:15.0'
34 + - 'opensuse/tumbleweed:latest'
35 + - 'ubuntu:20.04'
36 + - 'ubuntu:19.10'
37 + - 'ubuntu:19.04'
38 + - 'ubuntu:18.04'
39 + - 'ubuntu:16.04'
40 + include:
41 + - distro: 'alpine:3.11'
42 + pre: 'apk add -U bash'
43 + - distro: 'alpine:3.10'
44 + pre: 'apk add -U bash'
45 + - distro: 'alpine:3.9'
46 + pre: 'apk add -U bash'
47 +
48 + - distro: 'archlinux:latest'
49 + pre: 'pacman --noconfirm -Sy grep'
50 +
51 + - distro: 'debian:buster'
52 + pre: 'apt-get update'
53 + - distro: 'debian:jessie'
54 + pre: 'apt-get update'
55 + - distro: 'debian:stretch'
56 + pre: 'apt-get update'
57 +
58 + - distro: 'ubuntu:20.04'
59 + pre: 'apt-get update'
60 + - distro: 'ubuntu:19.10'
61 + pre: 'apt-get update'
62 + - distro: 'ubuntu:19.04'
63 + pre: 'apt-get update'
64 + - distro: 'ubuntu:18.04'
65 + pre: 'apt-get update'
66 + - distro: 'ubuntu:16.04'
67 + pre: 'apt-get update'
68 + runs-on: ubuntu-latest
69 + steps:
70 + - uses: actions/checkout@v1
71 + - name: Test installed-required-packages.sh on ${{ matrix.distro }}
72 + env:
73 + PRE: ${{ matrix.pre }}
74 + run: |
75 + docker run --rm -e PRE -v $PWD:/netdata -w /netdata ${{ matrix.distro }} /bin/sh -c '[ -n "${PRE}" ] && ${PRE}; ./packaging/installer/install-required-packages.sh --dont-wait --non-interactive'
packaging/installer/install-required-packages.sh
+216 -124
@@ -32,19 +32,20 @@ PACKAGES_NETDATA_SENSORS=${PACKAGES_NETDATA_SENSORS-0}
32 PACKAGES_NETDATA_DATABASE=${PACKAGES_NETDATA_DATABASE-0}
33
34 # needed commands
35 -lsb_release=$(which lsb_release 2> /dev/null || command -v lsb_release 2> /dev/null)
35 +lsb_release=$(command -v lsb_release 2> /dev/null)
36
37 # Check which package managers are available
38 -apk=$(which apk 2> /dev/null || command -v apk 2> /dev/null)
39 -apt_get=$(which apt-get 2> /dev/null || command -v apt-get 2> /dev/null)
40 -dnf=$(which dnf 2> /dev/null || command -v dnf 2> /dev/null)
41 -emerge=$(which emerge 2> /dev/null || command -v emerge 2> /dev/null)
42 -equo=$(which equo 2> /dev/null || command -v equo 2> /dev/null)
43 -pacman=$(which pacman 2> /dev/null || command -v pacman 2> /dev/null)
44 -yum=$(which yum 2> /dev/null || command -v yum 2> /dev/null)
45 -zypper=$(which zypper 2> /dev/null || command -v zypper 2> /dev/null)
38 +apk=$(command -v apk 2> /dev/null)
39 +apt_get=$(command -v apt-get 2> /dev/null)
40 +dnf=$(command -v dnf 2> /dev/null)
41 +emerge=$(command -v emerge 2> /dev/null)
42 +equo=$(command -v equo 2> /dev/null)
43 +pacman=$(command -v pacman 2> /dev/null)
44 +yum=$(command -v yum 2> /dev/null)
45 +zypper=$(command -v zypper 2> /dev/null)
46
47 distribution=
48 +release=
49 version=
50 codename=
51 package_installer=
@@ -137,10 +138,10 @@ release2lsb_release() {
138 # If it succeeds, it returns 0
139 # otherwise it returns 1
140
140 - local file="${1}" x DISTRIB_ID= DISTRIB_RELEASE= DISTRIB_CODENAME= DISTRIB_DESCRIPTION=
141 + local file="${1}" x DISTRIB_ID="" DISTRIB_RELEASE="" DISTRIB_CODENAME=""
142 echo >&2 "Loading ${file} ..."
143
143 - x="$(cat "${file}" | grep -v "^$" | head -n 1)"
144 + x="$(grep -v "^$" "${file}" | head -n 1)"
145
146 if [[ "${x}" =~ ^.*[[:space:]]+Linux[[:space:]]+release[[:space:]]+.*[[:space:]]+(.*)[[:space:]]*$ ]]; then
147 eval "$(echo "${x}" | sed "s|^\(.*\)[[:space:]]\+Linux[[:space:]]\+release[[:space:]]\+\(.*\)[[:space:]]\+(\(.*\))[[:space:]]*$|DISTRIB_ID=\"\1\"\nDISTRIB_RELEASE=\"\2\"\nDISTRIB_CODENAME=\"\3\"|g" | grep "^DISTRIB")"
@@ -162,38 +163,44 @@ release2lsb_release() {
163 }
164
165 get_os_release() {
165 - # Loads the /etc/os-release file
166 + # Loads the /etc/os-release or /usr/lib/os-release file(s)
167 # Only the required fields are loaded
168 #
168 - # If it manages to load /etc/os-release, it returns 0
169 + # If it manages to load a valid os-release, it returns 0
170 # otherwise it returns 1
171 #
172 # It searches the ID_LIKE field for a compatible distribution
173
173 - local x
174 - if [ -f "/etc/os-release" ]; then
175 - echo >&2 "Loading /etc/os-release ..."
176 -
177 - eval "$(cat /etc/os-release | grep -E "^(NAME|ID|ID_LIKE|VERSION|VERSION_ID)=")"
178 - for x in "${ID}" ${ID_LIKE}; do
179 - case "${x,,}" in
180 - alpine | arch | centos | debian | fedora | gentoo | sabayon | rhel | ubuntu | suse | opensuse-leap | sles)
181 - distribution="${x}"
182 - version="${VERSION_ID}"
183 - codename="${VERSION}"
184 - detection="/etc/os-release"
185 - break
186 - ;;
187 - *)
188 - echo >&2 "Unknown distribution ID: ${x}"
189 - ;;
190 - esac
191 - done
192 - [ -z "${distribution}" ] && echo >&2 "Cannot find valid distribution in: ${ID} ${ID_LIKE}" && return 1
174 + os_release_file=
175 + if [ -s "/etc/os-release" ]; then
176 + os_release_file="/etc/os-release"
177 + elif [ -s "/usr/lib/os-release" ]; then
178 + os_release_file="/usr/lib/os-release"
179 else
194 - echo >&2 "Cannot find /etc/os-release" && return 1
180 + echo >&2 "Cannot find an os-release file ..."
181 + return 1
182 fi
183
184 + local x
185 + echo >&2 "Loading ${os_release_file} ..."
186 +
187 + eval "$(grep -E "^(NAME|ID|ID_LIKE|VERSION|VERSION_ID)=" "${os_release_file}")"
188 + for x in "${ID}" ${ID_LIKE}; do
189 + case "${x,,}" in
190 + alpine | arch | centos | debian | fedora | gentoo | sabayon | rhel | ubuntu | suse | opensuse-leap | sles)
191 + distribution="${x}"
192 + version="${VERSION_ID}"
193 + codename="${VERSION}"
194 + detection="${os_release_file}"
195 + break
196 + ;;
197 + *)
198 + echo >&2 "Unknown distribution ID: ${x}"
199 + ;;
200 + esac
201 + done
202 + [ -z "${distribution}" ] && echo >&2 "Cannot find valid distribution in: ${ID} ${ID_LIKE}" && return 1
203 +
204 [ -z "${distribution}" ] && return 1
205 return 0
206 }
@@ -208,15 +215,15 @@ get_lsb_release() {
215
216 if [ -f "/etc/lsb-release" ]; then
217 echo >&2 "Loading /etc/lsb-release ..."
211 - local DISTRIB_ID= ISTRIB_RELEASE= DISTRIB_CODENAME= DISTRIB_DESCRIPTION=
212 - eval "$(cat /etc/lsb-release | grep -E "^(DISTRIB_ID|DISTRIB_RELEASE|DISTRIB_CODENAME)=")"
218 + local DISTRIB_ID="" DISTRIB_RELEASE="" DISTRIB_CODENAME=""
219 + eval "$(grep -E "^(DISTRIB_ID|DISTRIB_RELEASE|DISTRIB_CODENAME)=" /etc/lsb-release)"
220 distribution="${DISTRIB_ID}"
221 version="${DISTRIB_RELEASE}"
222 codename="${DISTRIB_CODENAME}"
223 detection="/etc/lsb-release"
224 fi
225
219 - if [ -z "${distribution}" -a ! -z "${lsb_release}" ]; then
226 + if [ -z "${distribution}" ] && [ -n "${lsb_release}" ]; then
227 echo >&2 "Cannot find distribution with /etc/lsb-release"
228 echo >&2 "Running command: lsb_release ..."
229 eval "declare -A release=( $(lsb_release -a 2> /dev/null | sed -e "s|^\(.*\):[[:space:]]*\(.*\)$|[\1]=\"\2\"|g") )"
@@ -265,7 +272,14 @@ user_picks_distribution() {
272 echo >&2
273 echo >&2 "I NEED YOUR HELP"
274 echo >&2 "It seems I cannot detect your system automatically."
268 - if [ -z "${equo}" -a -z "${emerge}" -a -z "${apt_get}" -a -z "${yum}" -a -z "${dnf}" -a -z "${pacman}" -a -z "${apk}" ]; then
275 +
276 + if [ "${NON_INTERACTIVE}" -eq 1 ]; then
277 + echo >&2 "Running in non-interactive mode"
278 + echo >&2 " > Bailing out..."
279 + exit 1
280 + fi
281 +
282 + if [ -z "${equo}" ] && [ -z "${emerge}" ] && [ -z "${apt_get}" ] && [ -z "${yum}" ] && [ -z "${dnf}" ] && [ -z "${pacman}" ] && [ -z "${apk}" ]; then
283 echo >&2 "And it seems I cannot find a known package manager in this system."
284 echo >&2 "Please open a github issue to help us support your system too."
285 exit 1
@@ -274,28 +288,30 @@ user_picks_distribution() {
288 local opts=
289 echo >&2 "I found though that the following installers are available:"
290 echo >&2
277 - [ ! -z "${apt_get}" ] && echo >&2 " - Debian/Ubuntu based (installer is: apt-get)" && opts="apt-get ${opts}"
278 - [ ! -z "${yum}" ] && echo >&2 " - Redhat/Fedora/Centos based (installer is: yum)" && opts="yum ${opts}"
279 - [ ! -z "${dnf}" ] && echo >&2 " - Redhat/Fedora/Centos based (installer is: dnf)" && opts="dnf ${opts}"
280 - [ ! -z "${zypper}" ] && echo >&2 " - SuSe based (installer is: zypper)" && opts="zypper ${opts}"
281 - [ ! -z "${pacman}" ] && echo >&2 " - Arch Linux based (installer is: pacman)" && opts="pacman ${opts}"
282 - [ ! -z "${emerge}" ] && echo >&2 " - Gentoo based (installer is: emerge)" && opts="emerge ${opts}"
283 - [ ! -z "${equo}" ] && echo >&2 " - Sabayon based (installer is: equo)" && opts="equo ${opts}"
284 - [ ! -z "${apk}" ] && echo >&2 " - Alpine Linux based (installer is: apk)" && opts="apk ${opts}"
291 + [ -n "${apt_get}" ] && echo >&2 " - Debian/Ubuntu based (installer is: apt-get)" && opts="apt-get ${opts}"
292 + [ -n "${yum}" ] && echo >&2 " - Redhat/Fedora/Centos based (installer is: yum)" && opts="yum ${opts}"
293 + [ -n "${dnf}" ] && echo >&2 " - Redhat/Fedora/Centos based (installer is: dnf)" && opts="dnf ${opts}"
294 + [ -n "${zypper}" ] && echo >&2 " - SuSe based (installer is: zypper)" && opts="zypper ${opts}"
295 + [ -n "${pacman}" ] && echo >&2 " - Arch Linux based (installer is: pacman)" && opts="pacman ${opts}"
296 + [ -n "${emerge}" ] && echo >&2 " - Gentoo based (installer is: emerge)" && opts="emerge ${opts}"
297 + [ -n "${equo}" ] && echo >&2 " - Sabayon based (installer is: equo)" && opts="equo ${opts}"
298 + [ -n "${apk}" ] && echo >&2 " - Alpine Linux based (installer is: apk)" && opts="apk ${opts}"
299 echo >&2
300
301 REPLY=
302 while [ -z "${REPLY}" ]; do
303 echo "To proceed please write one of these:"
290 - echo "${opts}" | sed -e 's/ /, /g'
291 - read -p ">" REPLY
292 - [ $? -ne 0 ] && REPLY= && continue
304 + echo "${opts// /, }"
305 + if ! read -r -p ">" REPLY; then
306 + continue
307 + fi
308
294 - if [ "${REPLY}" = "yum" -a -z "${distribution}" ]; then
309 + if [ "${REPLY}" = "yum" ] && [ -z "${distribution}" ]; then
310 REPLY=
311 while [ -z "${REPLY}" ]; do
297 - read -p "yum in centos, rhel or fedora? > "
298 - [ $? -ne 0 ] && continue
312 + if ! read -r -p "yum in centos, rhel or fedora? > "; then
313 + continue
314 + fi
315
316 case "${REPLY,,}" in
317 fedora | rhel)
@@ -321,7 +337,7 @@ detect_package_manager_from_distribution() {
337 arch* | manjaro*)
338 package_installer="install_pacman"
339 tree="arch"
324 - if [ ${IGNORE_INSTALLED} -eq 0 -a -z "${pacman}" ]; then
340 + if [ "${IGNORE_INSTALLED}" -eq 0 ] && [ -z "${pacman}" ]; then
341 echo >&2 "command 'pacman' is required to install packages on a '${distribution} ${version}' system."
342 exit 1
343 fi
@@ -330,7 +346,7 @@ detect_package_manager_from_distribution() {
346 sabayon*)
347 package_installer="install_equo"
348 tree="sabayon"
333 - if [ ${IGNORE_INSTALLED} -eq 0 -a -z "${equo}" ]; then
349 + if [ "${IGNORE_INSTALLED}" -eq 0 ] && [ -z "${equo}" ]; then
350 echo >&2 "command 'equo' is required to install packages on a '${distribution} ${version}' system."
351 # Maybe offer to fall back on emerge? Both installers exist in Sabayon...
352 exit 1
@@ -340,7 +356,7 @@ detect_package_manager_from_distribution() {
356 alpine*)
357 package_installer="install_apk"
358 tree="alpine"
343 - if [ ${IGNORE_INSTALLED} -eq 0 -a -z "${apk}" ]; then
359 + if [ "${IGNORE_INSTALLED}" -eq 0 ] && [ -z "${apk}" ]; then
360 echo >&2 "command 'apk' is required to install packages on a '${distribution} ${version}' system."
361 exit 1
362 fi
@@ -349,7 +365,7 @@ detect_package_manager_from_distribution() {
365 gentoo*)
366 package_installer="install_emerge"
367 tree="gentoo"
352 - if [ ${IGNORE_INSTALLED} -eq 0 -a -z "${emerge}" ]; then
368 + if [ "${IGNORE_INSTALLED}" -eq 0 ] && [ -z "${emerge}" ]; then
369 echo >&2 "command 'emerge' is required to install packages on a '${distribution} ${version}' system."
370 exit 1
371 fi
@@ -358,7 +374,7 @@ detect_package_manager_from_distribution() {
374 debian* | ubuntu*)
375 package_installer="install_apt_get"
376 tree="debian"
361 - if [ ${IGNORE_INSTALLED} -eq 0 -a -z "${apt_get}" ]; then
377 + if [ "${IGNORE_INSTALLED}" -eq 0 ] && [ -z "${apt_get}" ]; then
378 echo >&2 "command 'apt-get' is required to install packages on a '${distribution} ${version}' system."
379 exit 1
380 fi
@@ -369,7 +385,7 @@ detect_package_manager_from_distribution() {
385 echo >&2 "Check: http://www.tecmint.com/how-to-enable-epel-repository-for-rhel-centos-6-5/"
386 package_installer="install_yum"
387 tree="centos"
372 - if [ ${IGNORE_INSTALLED} -eq 0 -a -z "${yum}" ]; then
388 + if [ "${IGNORE_INSTALLED}" -eq 0 ] && [ -z "${yum}" ]; then
389 echo >&2 "command 'yum' is required to install packages on a '${distribution} ${version}' system."
390 exit 1
391 fi
@@ -378,9 +394,9 @@ detect_package_manager_from_distribution() {
394 fedora* | redhat* | red\ hat* | rhel*)
395 package_installer=
396 tree="rhel"
381 - [ ! -z "${yum}" ] && package_installer="install_yum"
382 - [ ! -z "${dnf}" ] && package_installer="install_dnf"
383 - if [ ${IGNORE_INSTALLED} -eq 0 -a -z "${package_installer}" ]; then
397 + [ -n "${yum}" ] && package_installer="install_yum"
398 + [ -n "${dnf}" ] && package_installer="install_dnf"
399 + if [ "${IGNORE_INSTALLED}" -eq 0 ] && [ -z "${package_installer}" ]; then
400 echo >&2 "command 'yum' or 'dnf' is required to install packages on a '${distribution} ${version}' system."
401 exit 1
402 fi
@@ -389,7 +405,7 @@ detect_package_manager_from_distribution() {
405 suse* | opensuse* | sles*)
406 package_installer="install_zypper"
407 tree="suse"
392 - if [ ${IGNORE_INSTALLED} -eq 0 -a -z "${zypper}" ]; then
408 + if [ "${IGNORE_INSTALLED}" -eq 0 ] && [ -z "${zypper}" ]; then
409 echo >&2 "command 'zypper' is required to install packages on a '${distribution} ${version}' system."
410 exit 1
411 fi
@@ -410,7 +426,7 @@ check_package_manager() {
426
427 case "${1}" in
428 apt-get)
413 - [ ${IGNORE_INSTALLED} -eq 0 -a -z "${apt_get}" ] && echo >&2 "${1} is not available." && return 1
429 + [ "${IGNORE_INSTALLED}" -eq 0 ] && [ -z "${apt_get}" ] && echo >&2 "${1} is not available." && return 1
430 package_installer="install_apt_get"
431 tree="debian"
432 detection="user-input"
@@ -418,7 +434,7 @@ check_package_manager() {
434 ;;
435
436 dnf)
421 - [ ${IGNORE_INSTALLED} -eq 0 -a -z "${dnf}" ] && echo >&2 "${1} is not available." && return 1
437 + [ "${IGNORE_INSTALLED}" -eq 0 ] && [ -z "${dnf}" ] && echo >&2 "${1} is not available." && return 1
438 package_installer="install_dnf"
439 tree="rhel"
440 detection="user-input"
@@ -426,7 +442,7 @@ check_package_manager() {
442 ;;
443
444 apk)
429 - [ ${IGNORE_INSTALLED} -eq 0 -a -z "${apk}" ] && echo >&2 "${1} is not available." && return 1
445 + [ "${IGNORE_INSTALLED}" -eq 0 ] && [ -z "${apk}" ] && echo >&2 "${1} is not available." && return 1
446 package_installer="install_apk"
447 tree="alpine"
448 detection="user-input"
@@ -434,7 +450,7 @@ check_package_manager() {
450 ;;
451
452 equo)
437 - [ ${IGNORE_INSTALLED} -eq 0 -a -z "${equo}" ] && echo >&2 "${1} is not available." && return 1
453 + [ "${IGNORE_INSTALLED}" -eq 0 ] && [ -z "${equo}" ] && echo >&2 "${1} is not available." && return 1
454 package_installer="install_equo"
455 tree="sabayon"
456 detection="user-input"
@@ -442,7 +458,7 @@ check_package_manager() {
458 ;;
459
460 emerge)
445 - [ ${IGNORE_INSTALLED} -eq 0 -a -z "${emerge}" ] && echo >&2 "${1} is not available." && return 1
461 + [ "${IGNORE_INSTALLED}" -eq 0 ] && [ -z "${emerge}" ] && echo >&2 "${1} is not available." && return 1
462 package_installer="install_emerge"
463 tree="gentoo"
464 detection="user-input"
@@ -450,7 +466,7 @@ check_package_manager() {
466 ;;
467
468 pacman)
453 - [ ${IGNORE_INSTALLED} -eq 0 -a -z "${pacman}" ] && echo >&2 "${1} is not available." && return 1
469 + [ "${IGNORE_INSTALLED}" -eq 0 ] && [ -z "${pacman}" ] && echo >&2 "${1} is not available." && return 1
470 package_installer="install_pacman"
471 tree="arch"
472 detection="user-input"
@@ -459,7 +475,7 @@ check_package_manager() {
475 ;;
476
477 zypper)
462 - [ ${IGNORE_INSTALLED} -eq 0 -a -z "${zypper}" ] && echo >&2 "${1} is not available." && return 1
478 + [ "${IGNORE_INSTALLED}" -eq 0 ] && [ -z "${zypper}" ] && echo >&2 "${1} is not available." && return 1
479 package_installer="install_zypper"
480 tree="suse"
481 detection="user-input"
@@ -467,7 +483,7 @@ check_package_manager() {
483 ;;
484
485 yum)
470 - [ ${IGNORE_INSTALLED} -eq 0 -a -z "${yum}" ] && echo >&2 "${1} is not available." && return 1
486 + [ "${IGNORE_INSTALLED}" -eq 0 ] && [ -z "${yum}" ] && echo >&2 "${1} is not available." && return 1
487 package_installer="install_yum"
488 if [ "${distribution}" = "centos" ]; then
489 tree="centos"
@@ -491,13 +507,14 @@ require_cmd() {
507 # If any of them is available, it returns 0
508 # otherwise 1
509
494 - [ ${IGNORE_INSTALLED} -eq 1 ] && return 1
510 + [ "${IGNORE_INSTALLED}" -eq 1 ] && return 1
511
512 local wanted found
513 for wanted in "${@}"; do
498 - found="$(which "${wanted}" 2> /dev/null)"
499 - [ -z "${found}" ] && found="$(command -v "${wanted}" 2> /dev/null)"
500 - [ ! -z "${found}" -a -x "${found}" ] && return 0
514 + if command -v "${wanted}" 2> /dev/null; then
515 + found="$(command -v "$wanted" 2> /dev/null)"
516 + fi
517 + [ -n "${found}" ] && [ -x "${found}" ] && return 0
518 done
519
520 return 1
@@ -957,14 +974,18 @@ declare -A pkg_zip=(
974 ['default']="zip"
975 )
976
977 +validate_package_trees() {
978 + validate_tree_${tree}
979 +}
980 +
981 validate_installed_package() {
982 validate_${package_installer} "${p}"
983 }
984
985 suitable_package() {
965 - local package="${1//-/_}" p= v="${version//.*/}"
986 + local package="${1//-/_}" p="" v="${version//.*/}"
987
967 - # echo >&2 "Searching for ${package}..."
988 + echo >&2 "Searching for ${package} ..."
989
990 eval "p=\${pkg_${package}['${distribution,,}-${version,,}']}"
991 [ -z "${p}" ] && eval "p=\${pkg_${package}['${distribution,,}-${v,,}']}"
@@ -992,7 +1013,7 @@ suitable_package() {
1013 echo >&2
1014 return 1
1015 else
995 - if [ ${IGNORE_INSTALLED} -eq 0 ]; then
1016 + if [ "${IGNORE_INSTALLED}" -eq 0 ]; then
1017 validate_installed_package "${p}"
1018 else
1019 echo "${p}"
@@ -1025,12 +1046,12 @@ packages() {
1046 # -------------------------------------------------------------------------
1047 # debugging tools for development
1048
1028 - if [ ${PACKAGES_DEBUG} -ne 0 ]; then
1049 + if [ "${PACKAGES_DEBUG}" -ne 0 ]; then
1050 require_cmd traceroute || suitable_package traceroute
1051 require_cmd tcpdump || suitable_package tcpdump
1052 require_cmd screen || suitable_package screen
1053
1033 - if [ ${PACKAGES_NETDATA} -ne 0 ]; then
1054 + if [ "${PACKAGES_NETDATA}" -ne 0 ]; then
1055 require_cmd gdb || suitable_package gdb
1056 require_cmd valgrind || suitable_package valgrind
1057 fi
@@ -1039,7 +1060,7 @@ packages() {
1060 # -------------------------------------------------------------------------
1061 # common command line tools
1062
1042 - if [ ${PACKAGES_NETDATA} -ne 0 ]; then
1063 + if [ "${PACKAGES_NETDATA}" -ne 0 ]; then
1064 require_cmd tar || suitable_package tar
1065 require_cmd curl || suitable_package curl
1066 require_cmd gzip || suitable_package gzip
@@ -1049,11 +1070,11 @@ packages() {
1070 # -------------------------------------------------------------------------
1071 # firehol/fireqos/update-ipsets command line tools
1072
1052 - if [ ${PACKAGES_FIREQOS} -ne 0 ]; then
1073 + if [ "${PACKAGES_FIREQOS}" -ne 0 ]; then
1074 require_cmd ip || suitable_package iproute2
1075 fi
1076
1056 - if [ ${PACKAGES_FIREHOL} -ne 0 ]; then
1077 + if [ "${PACKAGES_FIREHOL}" -ne 0 ]; then
1078 require_cmd iptables || suitable_package iptables
1079 require_cmd ipset || suitable_package ipset
1080 require_cmd ulogd ulogd2 || suitable_package ulogd
@@ -1061,7 +1082,7 @@ packages() {
1082 require_cmd bridge || suitable_package bridge-utils
1083 fi
1084
1064 - if [ ${PACKAGES_UPDATE_IPSETS} -ne 0 ]; then
1085 + if [ "${PACKAGES_UPDATE_IPSETS}" -ne 0 ]; then
1086 require_cmd ipset || suitable_package ipset
1087 require_cmd zip || suitable_package zip
1088 require_cmd funzip || suitable_package unzip
@@ -1070,7 +1091,7 @@ packages() {
1091 # -------------------------------------------------------------------------
1092 # netdata libraries
1093
1073 - if [ ${PACKAGES_NETDATA} -ne 0 ]; then
1094 + if [ "${PACKAGES_NETDATA}" -ne 0 ]; then
1095 suitable_package libz-dev
1096 suitable_package libuuid-dev
1097 suitable_package libmnl-dev
@@ -1079,13 +1100,13 @@ packages() {
1100 # -------------------------------------------------------------------------
1101 # sensors
1102
1082 - if [ ${PACKAGES_NETDATA_SENSORS} -ne 0 ]; then
1103 + if [ "${PACKAGES_NETDATA_SENSORS}" -ne 0 ]; then
1104 require_cmd sensors || suitable_package lm_sensors
1105 fi
1106
1107 # -------------------------------------------------------------------------
1108 # sensors
1088 - if [ ${PACKAGES_NETDATA_DATABASE} -ne 0 ]; then
1109 + if [ "${PACKAGES_NETDATA_DATABASE}" -ne 0 ]; then
1110 suitable_package libuv
1111 suitable_package lz4
1112 suitable_package openssl
@@ -1095,43 +1116,43 @@ packages() {
1116 # -------------------------------------------------------------------------
1117 # scripting interpreters for netdata plugins
1118
1098 - if [ ${PACKAGES_NETDATA_NODEJS} -ne 0 ]; then
1119 + if [ "${PACKAGES_NETDATA_NODEJS}" -ne 0 ]; then
1120 require_cmd nodejs node js || suitable_package nodejs
1121 fi
1122
1123 # -------------------------------------------------------------------------
1124 # python2
1125
1105 - if [ ${PACKAGES_NETDATA_PYTHON} -ne 0 ]; then
1126 + if [ "${PACKAGES_NETDATA_PYTHON}" -ne 0 ]; then
1127 require_cmd python || suitable_package python
1128
1108 - [ ${PACKAGES_NETDATA_PYTHON_MONGO} -ne 0 ] && suitable_package python-pymongo
1129 + [ "${PACKAGES_NETDATA_PYTHON_MONGO}" -ne 0 ] && suitable_package python-pymongo
1130 # suitable_package python-requests
1131 # suitable_package python-pip
1132
1112 - [ ${PACKAGES_NETDATA_PYTHON_MYSQL} -ne 0 ] && suitable_package python-mysqldb
1113 - [ ${PACKAGES_NETDATA_PYTHON_POSTGRES} -ne 0 ] && suitable_package python-psycopg2
1133 + [ "${PACKAGES_NETDATA_PYTHON_MYSQL}" -ne 0 ] && suitable_package python-mysqldb
1134 + [ "${PACKAGES_NETDATA_PYTHON_POSTGRES}" -ne 0 ] && suitable_package python-psycopg2
1135 fi
1136
1137 # -------------------------------------------------------------------------
1138 # python3
1139
1119 - if [ ${PACKAGES_NETDATA_PYTHON3} -ne 0 ]; then
1140 + if [ "${PACKAGES_NETDATA_PYTHON3}" -ne 0 ]; then
1141 require_cmd python3 || suitable_package python3
1142
1143 suitable_package python3-pymongo
1123 - [ ${PACKAGES_NETDATA_PYTHON_MONGO} -ne 0 ] && suitable_package python3-pymongo
1144 + [ "${PACKAGES_NETDATA_PYTHON_MONGO}" -ne 0 ] && suitable_package python3-pymongo
1145 # suitable_package python3-requests
1146 # suitable_package python3-pip
1147
1127 - [ ${PACKAGES_NETDATA_PYTHON_MYSQL} -ne 0 ] && suitable_package python3-mysqldb
1128 - [ ${PACKAGES_NETDATA_PYTHON_POSTGRES} -ne 0 ] && suitable_package python3-psycopg2
1148 + [ "${PACKAGES_NETDATA_PYTHON_MYSQL}" -ne 0 ] && suitable_package python3-mysqldb
1149 + [ "${PACKAGES_NETDATA_PYTHON_POSTGRES}" -ne 0 ] && suitable_package python3-psycopg2
1150 fi
1151
1152 # -------------------------------------------------------------------------
1153 # applications needed for the netdata demo sites
1154
1134 - if [ ${PACKAGES_NETDATA_DEMO_SITE} -ne 0 ]; then
1155 + if [ "${PACKAGES_NETDATA_DEMO_SITE}" -ne 0 ]; then
1156 require_cmd sudo || suitable_package sudo
1157 require_cmd jq || suitable_package jq
1158 require_cmd nginx || suitable_package nginx
@@ -1180,23 +1201,80 @@ install_apt_get() {
1201 fi
1202
1203 local opts=""
1183 - if [ ${NON_INTERACTIVE} -eq 1 ]; then
1204 + if [ "${NON_INTERACTIVE}" -eq 1 ]; then
1205 echo >&2 "Running in non-interactive mode"
1206 # http://serverfault.com/questions/227190/how-do-i-ask-apt-get-to-skip-any-interactive-post-install-configuration-steps
1207 export DEBIAN_FRONTEND="noninteractive"
1208 opts="${opts} -yq"
1209 fi
1210
1211 + read -r -a apt_opts <<< "$opts"
1212 +
1213 # install the required packages
1214 for pkg in "${@}"; do
1215 [[ ${DRYRUN} -eq 0 ]] && echo >&2 "Adding package ${pkg}"
1193 - run ${sudo} apt-get ${opts} install "${pkg}"
1216 + run ${sudo} apt-get "${apt_opts[@]}" install "${pkg}"
1217 done
1218 }
1219
1220 # -----------------------------------------------------------------------------
1221 # centos / rhel
1222
1223 +prompt() {
1224 + if [ "${NON_INTERACTIVE}" -eq 1 ]; then
1225 + echo >&2 "Running in non-interactive mode, assuming yes (y)"
1226 + echo >&2 " > Would have promptedfor ${1} ..."
1227 + return 0
1228 + fi
1229 +
1230 + while true; do
1231 + read -r -p "${1} [y/n] " yn
1232 + case $yn in
1233 + [Yy]*) return 0 ;;
1234 + [Nn]*) return 1 ;;
1235 + *) echo >&2 "Please answer with yes (y) or no (n)." ;;
1236 + esac
1237 + done
1238 +}
1239 +
1240 +validate_tree_centos() {
1241 + local opts=
1242 + if [ "${NON_INTERACTIVE}" -eq 1 ]; then
1243 + echo >&2 "Running in non-interactive mode"
1244 + opts="-y"
1245 + fi
1246 +
1247 + echo >&2 " > Checking for epel ..."
1248 + if ! rpm -qa | grep epel > /dev/null; then
1249 + if prompt "epel not found, shall I install it?"; then
1250 + run ${sudo} yum ${opts} install epel-release
1251 + fi
1252 + fi
1253 +
1254 + if [ "$VERSION_ID" -eq 8 ]; then
1255 + echo >&2 " > Checking for config-manager ..."
1256 + if ! run yum ${sudo} config-manager; then
1257 + if prompt "config-manager not found, shall I install it?"; then
1258 + run ${sudo} yum ${opts} install 'dnf-command(config-manager)'
1259 + fi
1260 + fi
1261 +
1262 + echo >&2 " > Checking for PowerTools ..."
1263 + if ! run yum ${sudo} repolist | grep PowerTools; then
1264 + if prompt "PowerTools not found, shall I install it?"; then
1265 + run ${sudo} yum ${opts} config-manager --set-enabled PowerTools
1266 + fi
1267 + fi
1268 +
1269 + echo >&2 " > Checking for getpagespeed-extras ..."
1270 + if ! run yum ${sudo} repolist | grep 'getpagespeed-extras'; then
1271 + if prompt "PowerTools not found, shall I install it?"; then
1272 + run ${sudo} yum ${opts} install https://extras.getpagespeed.com/release-el8-latest.rpm
1273 + fi
1274 + fi
1275 + fi
1276 +}
1277 +
1278 validate_install_yum() {
1279 echo >&2 " > Checking if package '${*}' is installed..."
1280 yum list installed "${*}" > /dev/null 2>&1 || echo "${*}"
@@ -1212,14 +1290,16 @@ install_yum() {
1290 fi
1291
1292 local opts=
1215 - if [ ${NON_INTERACTIVE} -eq 1 ]; then
1293 + if [ "${NON_INTERACTIVE}" -eq 1 ]; then
1294 echo >&2 "Running in non-interactive mode"
1295 # http://unix.stackexchange.com/questions/87822/does-yum-have-an-equivalent-to-apt-aptitudes-debian-frontend-noninteractive
1296 opts="-y"
1297 fi
1298
1299 + read -r -a yum_opts <<< "${opts}"
1300 +
1301 # install the required packages
1222 - run ${sudo} yum ${opts} install "${@}" # --enablerepo=epel-testing
1302 + run ${sudo} yum "${yum_opts[@]}" install "${@}" # --enablerepo=epel-testing
1303 }
1304
1305 # -----------------------------------------------------------------------------
@@ -1240,7 +1320,7 @@ install_dnf() {
1320 fi
1321
1322 local opts=
1243 - if [ ${NON_INTERACTIVE} -eq 1 ]; then
1323 + if [ "${NON_INTERACTIVE}" -eq 1 ]; then
1324 echo >&2 "Running in non-interactive mode"
1325 # man dnf
1326 opts="-y"
@@ -1251,7 +1331,8 @@ install_dnf() {
1331 # installing whatever is available
1332 # even if a package is not found
1333 opts="$opts --setopt=strict=0"
1254 - run ${sudo} dnf ${opts} install "${@}"
1334 + read -r -a dnf_opts <<< "$opts"
1335 + run ${sudo} dnf "${dnf_opts[@]}" install "${@}"
1336 }
1337
1338 # -----------------------------------------------------------------------------
@@ -1274,15 +1355,17 @@ install_emerge() {
1355 fi
1356
1357 local opts="--ask"
1277 - if [ ${NON_INTERACTIVE} -eq 1 ]; then
1358 + if [ "${NON_INTERACTIVE}" -eq 1 ]; then
1359 echo >&2 "Running in non-interactive mode"
1360 opts=""
1361 fi
1362
1363 + read -r -a emerge_opts <<< "$opts"
1364 +
1365 # install the required packages
1366 for pkg in "${@}"; do
1367 [[ ${DRYRUN} -eq 0 ]] && echo >&2 "Adding package ${pkg}"
1285 - run ${sudo} emerge ${opts} -v --noreplace "${pkg}"
1368 + run ${sudo} emerge "${emerge_opts[@]}" -v --noreplace "${pkg}"
1369 done
1370 }
1371
@@ -1303,14 +1386,16 @@ install_apk() {
1386 fi
1387
1388 local opts="--force-broken-world"
1306 - if [ ${NON_INTERACTIVE} -eq 1 ]; then
1389 + if [ "${NON_INTERACTIVE}" -eq 1 ]; then
1390 echo >&2 "Running in non-interactive mode"
1391 else
1392 opts="${opts} -i"
1393 fi
1394
1395 + read -r -a apk_opts <<< "$opts"
1396 +
1397 # install the required packages
1313 - run ${sudo} apk add ${opts} "${@}"
1398 + run ${sudo} apk add "${apk_opts[@]}" "${@}"
1399 }
1400
1401 # -----------------------------------------------------------------------------
@@ -1331,15 +1416,17 @@ install_equo() {
1416 fi
1417
1418 local opts="-av"
1334 - if [ ${NON_INTERACTIVE} -eq 1 ]; then
1419 + if [ "${NON_INTERACTIVE}" -eq 1 ]; then
1420 echo >&2 "Running in non-interactive mode"
1421 opts="-v"
1422 fi
1423
1424 + read -r -a equo_opts <<< "$opts"
1425 +
1426 # install the required packages
1427 for pkg in "${@}"; do
1428 [[ ${DRYRUN} -eq 0 ]] && echo >&2 "Adding package ${pkg}"
1342 - run ${sudo} equo i ${opts} "${pkg}"
1429 + run ${sudo} equo i "${equo_opts[@]}" "${pkg}"
1430 done
1431 }
1432
@@ -1351,8 +1438,9 @@ validate_install_pacman() {
1438
1439 if [ ${PACMAN_DB_SYNCED} -eq 0 ]; then
1440 echo >&2 " > Running pacman -Sy to sync the database"
1354 - local x=$(pacman -Sy)
1355 - [ ! -n "${x}" ] && echo "${*}"
1441 + local x
1442 + x=$(pacman -Sy)
1443 + [ -z "${x}" ] && echo "${*}"
1444 PACMAN_DB_SYNCED=1
1445 fi
1446 echo >&2 " > Checking if package '${*}' is installed..."
@@ -1379,7 +1467,7 @@ validate_install_pacman() {
1467 ;;
1468 esac
1469
1382 - [ ! -n "${x}" ] && echo "${*}"
1470 + [ -z "${x}" ] && echo "${*}"
1471 }
1472
1473 install_pacman() {
@@ -1392,7 +1480,7 @@ install_pacman() {
1480 fi
1481
1482 # install the required packages
1395 - if [ ${NON_INTERACTIVE} -eq 1 ]; then
1483 + if [ "${NON_INTERACTIVE}" -eq 1 ]; then
1484 echo >&2 "Running in non-interactive mode"
1485 # http://unix.stackexchange.com/questions/52277/pacman-option-to-assume-yes-to-every-question/52278
1486 for pkg in "${@}"; do
@@ -1426,14 +1514,16 @@ install_zypper() {
1514 fi
1515
1516 local opts="--ignore-unknown"
1429 - if [ ${NON_INTERACTIVE} -eq 1 ]; then
1517 + if [ "${NON_INTERACTIVE}" -eq 1 ]; then
1518 echo >&2 "Running in non-interactive mode"
1519 # http://unix.stackexchange.com/questions/82016/how-to-use-zypper-in-bash-scripts-for-someone-coming-from-apt-get
1520 opts="${opts} --non-interactive"
1521 fi
1522
1523 + read -r -a zypper_opts <<< "$opts"
1524 +
1525 # install the required packages
1436 - run ${sudo} zypper ${opts} install "${@}"
1526 + run ${sudo} zypper "${zypper_opts[@]}" install "${@}"
1527 }
1528
1529 install_failed() {
@@ -1462,14 +1552,14 @@ What to do now:
1552
1553
1554 EOF
1465 - remote_log "FAILED" ${ret}
1555 + remote_log "FAILED" "${ret}"
1556 exit 1
1557 }
1558
1559 remote_log() {
1560 # log success or failure on our system
1561 # to help us solve installation issues
1472 - 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=${PACKAGE_NETDATA_DATABASE}&firehol=${PACKAGES_FIREHOL}&fireqos=${PACKAGES_FIREQOS}&iprange=${PACKAGES_IPRANGE}&update_ipsets=${PACKAGES_UPDATE_IPSETS}&demo=${PACKAGES_NETDATA_DEMO_SITE}"
1562 + 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}&firehol=${PACKAGES_FIREHOL}&fireqos=${PACKAGES_FIREQOS}&iprange=${PACKAGES_IPRANGE}&update_ipsets=${PACKAGES_UPDATE_IPSETS}&demo=${PACKAGES_NETDATA_DEMO_SITE}"
1563 }
1564
1565 if [ -z "${1}" ]; then
@@ -1481,7 +1571,7 @@ fi
1571 DONT_WAIT=0
1572 NON_INTERACTIVE=0
1573 IGNORE_INSTALLED=0
1484 -while [ ! -z "${1}" ]; do
1574 +while [ -n "${1}" ]; do
1575 case "${1}" in
1576 distribution)
1577 distribution="${2}"
@@ -1617,7 +1707,7 @@ if ! command -v grep > /dev/null 2>&1; then
1707 exit 1
1708 fi
1709
1620 -if [ -z "${package_installer}" -o -z "${tree}" ]; then
1710 +if [ -z "${package_installer}" ] || [ -z "${tree}" ]; then
1711 if [ -z "${distribution}" ]; then
1712 # we dont know the distribution
1713 autodetect_distribution || user_picks_distribution
@@ -1628,6 +1718,8 @@ if [ -z "${package_installer}" -o -z "${tree}" ]; then
1718 detect_package_manager_from_distribution "${distribution}"
1719 fi
1720
1721 + # Validate package manager trees
1722 + validate_package_trees
1723 fi
1724
1725 pv=$(python --version 2>&1)
@@ -1659,27 +1751,27 @@ Codename : ${codename}
1751 Package Manager : ${package_installer}
1752 Packages Tree : ${tree}
1753 Detection Method: ${detection}
1662 -Default Python v: ${pv} $([ ${pv} -eq 2 -a ${PACKAGES_NETDATA_PYTHON3} -eq 1 ] && echo "(will install python3 too)")
1754 +Default Python v: ${pv} $([ ${pv} -eq 2 ] && [ "${PACKAGES_NETDATA_PYTHON3}" -eq 1 ] && echo "(will install python3 too)")
1755
1756 EOF
1757
1666 -PACKAGES_TO_INSTALL=($(packages | sort -u))
1758 +mapfile -t PACKAGES_TO_INSTALL < <(packages | sort -u)
1759
1760 if [ ${#PACKAGES_TO_INSTALL[@]} -gt 0 ]; then
1761 echo >&2
1762 echo >&2 "The following command will be run:"
1763 echo >&2
1764 DRYRUN=1
1673 - ${package_installer} "${PACKAGES_TO_INSTALL[@]}"
1765 + "${package_installer}" "${PACKAGES_TO_INSTALL[@]}"
1766 DRYRUN=0
1767 echo >&2
1768 echo >&2
1769
1678 - if [ ${DONT_WAIT} -eq 0 -a ${NON_INTERACTIVE} -eq 0 ]; then
1679 - read -p "Press ENTER to run it > " || exit 1
1770 + if [ "${DONT_WAIT}" -eq 0 ] && [ "${NON_INTERACTIVE}" -eq 0 ]; then
1771 + read -r -p "Press ENTER to run it > " || exit 1
1772 fi
1773
1682 - ${package_installer} "${PACKAGES_TO_INSTALL[@]}" || install_failed $?
1774 + "${package_installer}" "${PACKAGES_TO_INSTALL[@]}" || install_failed $?
1775
1776 echo >&2
1777 echo >&2 "All Done! - Now proceed to the next step."