#!/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 # ====================================================================== . $( 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 # ----------------------------------------------------------------------