-
Hahn Axel (hahn) authoredHahn Axel (hahn) authored
check_packages2install 8.80 KiB
#!/bin/bash
# ======================================================================
#
# NAGIOS CLIENT CHECK :: check available package updates
# for centos/debian/manjaro/ubuntu
#
# ----------------------------------------------------------------------
#
# ah=axel.hahn@iml.unibe.ch
# ds=daniel.schueler@iml.unibe.ch
#
# 2016-12-23 v0.3 ah,ds
# 2018-12-18 v1.0 ah added check for auto update (IML specific)
# 2019-03-26 v1.1 ah fix apt-get (not all constellations worked)
# 2019-04-29 v1.2 ah yum: supress error channel output (task #2959)
# 2020-03-05 v1.3 <axel.hahn@iml.unibe.ch> switch to ph.* helper functions
# 2020-03-11 v1.4 <axel.hahn@iml.unibe.ch> add -c -w limits; added perfdata (yum)
# 2021-05-11 v1.4 <axel.hahn@iml.unibe.ch> added centos8 support
# 2021-08-20 v1.5 <martin.gasser@iml.unibe.ch> bug fixing - missing sudo in yum command
# 2021-12-16 v1.6 <axel.hahn@iml.unibe.ch> show filtered overview
# 2021-12-17 v1.7 <axel.hahn@iml.unibe.ch> show non matching packages in section "other"
# 2021-12-20 v1.8 <axel.hahn@iml.unibe.ch> show all packages if no filter matched
# 2022-06-03 v1.9 <axel.hahn@iml.unibe.ch> call yum with path; shellcheck updates; plugin like package managers
# 2022-06-07 v1.10 <axel.hahn@iml.unibe.ch> fix iPkg2Update on empty package list
# rename package manager functions
# 2022-10-21 v1.11 <axel.hahn@unibe.ch> remove grep: warning: stray \ before white space
# ======================================================================
. $( dirname "$0" )/inc_pluginfunctions
readonly iWarnDefault=1
readonly iCriticalDefault=200
typeset -i iCount=0
cronfile=/etc/cron.d/system-updater
MYhost="localhost"
dir_pkg="$( dirname $0 )/check_packages2install-pkgmanager"
dir_filter="$( dirname $0 )/check_packages2install-data"
# ----------------------------------------------------------------------
# functions
# ----------------------------------------------------------------------
# show if auto update ist enabled here by searching for a cronjob
# see global var cronfile
# global string cronfile filename of the cronjob to detect
function _showAutoupdate(){
if ls ${cronfile} >/dev/null 2>&1
then
echo Autoupdate ON
if grep -- " -r" ${cronfile} >/dev/null 2>&1
then
echo Autoreboot ON
else
echo Autoreboot OFF
fi
else
echo Autoupdate OFF
fi
}
# execute a local or a remote command
# param string commandline with command and its params
function _exec(){
if [ ${MYhost} = "localhost" ]; then
eval "$1"
else
${MYsshprefix}${MYhost} "$1"
fi
}
# check if a given function name exists
# param string name of a function
function _functionExists(){
[[ $(type -t $1) == function ]]
}
# show help
function showHelp(){
local _self
_self=$(basename $0)
cat <<EOF
______________________________________________________________________
CHECK PACKAGES TO INSTALL
Get packages that must be updated on this system
(c) Institute for Medical Education - University of Bern
Licence: GNU GPL 3
______________________________________________________________________
Get packages that must be updated on this system and show found
packages in groups.
RELATED FILES:
1) For groups and their search filters see files in subdir
check_packages2install-data.
2) In the subdir check_packages2install-pkgmanager are scripts
for supported package managers (with aded ".sh").
OUTPUT:
It returns UNKNOWN if package manager is not supported.
It returns OK if the system is up to date.
It returns WARNING or ERROR if count of found pakackes is greater than
given warn level.
On CentOS it switches to ERROR if a critcal update was found.
Tested operating systems:
- Centos
- Debian
- Manjaro
- Ubuntu
SYNTAX:
$_self [options]
OPTIONS:
-w custom warning level; default: $iWarnDefault
-c custom critical level; default: $iCriticalDefault
PARAMETERS:
-h show this help
EOF
}
# apply filter on incoming piped data
# filter is a param with spaced keywords that will be transformed
# to a regex
# param1 text if filter keywords (seperated by space)
# param2 text additional grep params; "-v" to invert filtering
function _filterPkg(){
local _filter
_filter=$( echo $1 | tr " " "|" )
local _moreparams="$2"
grep $_moreparams -E "^($_filter)"
}
# autodetect a package manager using which with
# a list of known pkg managers
function _detectPkgManager(){
find $dir_pkg -name "*.sh" | while read incfile
do
pkgmanager=$( basename $incfile | sed "s#.sh##" )
which "$pkgmanager" > /dev/null 2>&1 && echo "$pkgmanager"
done
}
# ----------------------------------------------------------------------
# show grouped packages by category
# global string dir_filter directory where to find filters
# global string packagemanOut output of update lister command
function showFilteredPackages(){
# filtered package view
if [ -n "$packages2install" ]; then
typeset -i iTotal
iTotal=$( echo "$packages2install" | wc -l )
typeset -i iFound=0
filterAll=""
# show filtered view
for filterfile in $( find "$dir_filter" -name "*txt" | sort )
do
# get group name from filename
filtername=$( echo "$filterfile" | rev | cut -f 1 -d "/" | rev | sed "s#.txt\$##g" | sed "s#^[0-9]*_##g" )
# get filter for this group
filterdata=$( cat "${filterfile}" | grep "^[a-zA-Z]" )
# build a "total filter" with all group filters - used to grep -v later
filterAll="$filterAll $filterdata"
out=$( echo "$packages2install" | _filterPkg "${filterdata}" )
typeset -i iCount
iCount=$( echo "$out" | grep "." | wc -l )
test $iCount -ne 0 && (
echo --- $( echo "$filtername" | sed "s#MYfilter##g" ): $iCount
echo "$out" | nl; echo
)
iFound=$iFound+$iCount
done
# show count of non matching packages
typeset -i iOther=$iTotal-$iFound
if [ $iFound -eq 0 ]; then
echo "--- All packages (No package matched a group filter):"
else
echo "--- Other packages: $iOther"
fi
echo "$packages2install" | _filterPkg "${filterAll}" "-v" | nl
echo
# total packages
echo Total packages to install: $iTotal
fi
}
# ----------------------------------------------------------------------
# main
# ----------------------------------------------------------------------
# ----- help wanted?
if [ "$1" = "-h" ]; then
showHelp; exit 0
fi
# ----- set default / override from command line params
typeset -i iWarnLimit
typeset -i iCriticalLimit
iWarnLimit=$( ph.getValueWithParam $iWarnDefault w "$@")
iCriticalLimit=$( ph.getValueWithParam $iCriticalDefault c "$@")
# ----- handle output of different package managers
pkgmanager=$( _detectPkgManager )
if [ -z "$pkgmanager" ]; then
ph.abort "UNKNOWN: the package manager was not detected/ is not supported."
fi
# load functions for the detected package manager
. "${dir_pkg}/${pkgmanager}.sh" || exit 2
packagemanOut=$( ${pkgmanager}.getUpdates )
if [ -z "$packagemanOut" ]; then
ph.setStatus "critical"
ph.status "[$pkgmanager] ERROR: failed to get output from package manager."
else
# generated function names - package manager is prefix
function2install="${pkgmanager}.getPackageList"
_functionExists "${pkgmanager}.getStatusLine" && functionStatus="${pkgmanager}.getStatusLine"
_functionExists "${pkgmanager}.getCriticalList" && functionCritical="${pkgmanager}.getCriticalList"
# count of packages ... to install ... critical (centos only)
typeset -i iPkg2Update=0
typeset -i iPkgCritical=0
# get list of packages 2 install
packages2install=$( $function2install )
iPkg2Update=$( test -n "$packages2install" && echo "$packages2install" | wc -l )
# custom: status text
test -n "$functionStatus" && statusLabel="[$pkgmanager] $( $functionStatus )"
# custom: get count of critical packages
if [ -n "$functionCritical" ]; then
iPkgCritical=$( $functionCritical "$statusLabel" )
ph.perfadd "updates-security" "${iPkgCritical}" 1 1
fi
# set statuscode by found updates
if [ $iPkgCritical -gt 0 ]; then
ph.setStatus "critical"
else
ph.setStatusByLimit ${iPkg2Update} ${iWarnLimit} ${iCriticalLimit}
fi
ph.perfadd "updates-available" "${iPkg2Update}" "${iWarnLimit}" "${iCriticalLimit}"
# set label for status line
if [ -z "$statusLabel" ]; then
test $iPkgCritical -gt 0 && statusLabel="[$pkgmanager] $iPkg2Update updates; $iPkgCritical critcal detected"
test $iPkgCritical -gt 0 || statusLabel="[$pkgmanager] $iPkg2Update updates"
fi
ph.status "$statusLabel"
# ----- show auto update info and found packages
echo
_showAutoupdate
echo
showFilteredPackages
fi
ph.exit
# ----------------------------------------------------------------------