-
Hahn Axel (hahn) authoredHahn Axel (hahn) authored
check_packages2install 7.34 KiB
#!/bin/bash
# ======================================================================
#
# NAGIOS CLIENT CHECK :: check available package updates
# requires no root for yum ... apt I must verify
#
# ----------------------------------------------------------------------
#
# 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
# ======================================================================
. `dirname $0`/inc_pluginfunctions
typeset -i iCount=0
tmpfile=/tmp/packages2install.log
cronfile=/etc/cron.d/system-updater
MYhost="localhost"
# ----------------------------------------------------------------------
# functions
# ----------------------------------------------------------------------
function showAutoupdate(){
ls ${cronfile} >/dev/null 2>&1
if [ $? -eq 0 ]; then
echo Autoupdate ON
grep "\ \-r" ${cronfile} >/dev/null 2>&1
if [ $? -eq 0 ]; then
echo Autoreboot ON
else
echo Autoreboot OFF
fi
else
echo Autoupdate OFF
fi
}
# execute a local or a remote command
function _exec(){
if [ ${MYhost} = "localhost" ]; then
eval "$1"
else
${MYsshprefix}${MYhost} "$1"
fi
}
# 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)
function _filterPkg(){
local _filter=$( echo $1 | tr " " "|" )
grep -E "^($_filter)"
}
# autodetect a package manager using which with
# a list of known pkg managers
function detectPkgManager(){
local _list="apt yum pamac"
local out=$( _exec "which $_list 2>/dev/null" )
for mypkg in $_list
do
echo "$out" | grep "/$mypkg" > /dev/null && echo $mypkg
done
}
# Debian like Linux
# - Debian 11
function pkgApt(){
local sum=$( _exec "sudo apt-get -u upgrade --assume-no" )
# detect number of line containing "The following packages will be upgraded:"
typeset -i local iStart=$( echo "$sum" | grep -n '^The following packages will be upgraded:' | cut -f 1 -d ':' )
if [ $iStart -eq 0 ]; then
echo "Nothing to install"
else
# show packages = text starting with 2 spaces below start line
# packages are delimited with space -> replace with new line
echo "$sum" | sed -n $iStart,\$p | grep "^\ \ " | sed "s#^\ \ ##g" | tr " " "\n"
fi
}
# Arch Linux, Manjaro
function pkgPamac(){
_exec "pamac checkupdates | grep -- '->'"
}
# RedHat like Linux
# - Centos 8
function pkgYum(){
# local sum=$( _exec "sudo dnf check-update" )
local sum=$( _exec "sudo yum -y check-update" )
local iStart=3
# detect number of line containing "Obsoleting Packages"
typeset -i iEnd=$( echo "$sum" | grep -n '^Obsoleting Packages' | cut -f 1 -d ':' )-1
local sEnd=$iEnd
test "$iEnd" = "-1" && sEnd='$'
echo "$sum" | sed -n ${iStart},${sEnd}p
# echo "show lines ${iStart} -> ${sEnd}"
}
# check updates with apt and exit script
function checkApt(){
# bug #2818
sudo apt-get -v >/dev/null
if [ $? -ne 0 ]; then
ph.setStatus "error"
echo "ERROR: failed to run apt-get"
echo "OUTPUT is:"
sudo apt-get -v
else
summary=`ph.execIfReady "sudo apt-get -u upgrade --assume-no | grep installed | grep upgraded" `
# example output:
# 0 upgraded, 0 newly installed, 0 to remove and 3 not upgraded.
typeset -i local iPkg2Update=`echo $summary | cut -f 1 -d " "`
ph.setStatusByLimit ${iPkg2Update} ${iWarnLimit} ${iCriticalLimit}
ph.perfadd "updates-available" "${iPkg2Update}" ${iWarnLimit} ${iCriticalLimit}
# --- output
ph.status "$summary"
echo "[apt]"
echo
fi
}
# check updates with yum and exit script
function checkYum(){
local _yumout=/tmp/yumoutput.log
# summary=`ph.execIfReady "/usr/bin/yum --security check-update 2>&1 | fgrep 'security'" `
# summary=`ph.execIfReady "/usr/bin/yum --security check-update 2>&1 | fgrep 'security'" `
ph.execIfReady "sudo /usr/bin/yum --security check-update > $_yumout 2>&1"
local summary=$( cat $_yumout | grep security )
test -z "$summary" && summary='no data .. no packages to install'
# example outputs:
# I No packages needed for security; 223 packages available
# II 2 package(s) needed for security, out of 237 available
typeset -i local iPkgSecurity=` echo $summary | cut -f 1 -d ' ' | sed "s#[^0-9]##g"`
typeset -i local iPkg2Update=` echo $summary | cut -f 2- -d ' ' | sed "s#[^0-9]##g"`
# step I: check limits with packages to update:
ph.setStatusByLimit ${iPkg2Update} ${iWarnLimit} ${iCriticalLimit}
# step II: security packages switch to "critical"
# remark: a warn level does not exist
if [ ${iPkgSecurity} -ne 0 ]; then
ph.setStatus "critical"
fi
ph.perfadd "updates-available" "${iPkg2Update}" ${iWarnLimit} ${iCriticalLimit}
ph.perfadd "updates-security" "${iPkgSecurity}" 1 1
ph.status "$summary"
echo "[yum]"
cat $_yumout
rm -f yumout
echo
}
# ----------------------------------------------------------------------
# main
# ----------------------------------------------------------------------
# set default / override from command line params
typeset -i iWarnLimit=` ph.getValueWithParam 1 w "$@"`
typeset -i iCriticalLimit=` ph.getValueWithParam 200 c "$@"`
# ----- try package manager apt
pgkman=$( detectPkgManager )
case $pgkman in
"apt")
pkgstatus=$( checkApt )
pkgsum=$( pkgApt )
;;
"pamac")
pkgstatus=""
pkgsum=$( pkgPamac )
;;
"yum")
pkgstatus=$( checkYum )
pkgsum=$( pkgYum )
;;
*)
ph.abort "UNKNOWN: package manager [$pgkman] was not detected or is not supported yet."
;;
esac
echo "$pkgstatus"
echo
showAutoupdate
echo
# filtered package view
if [ ! -z "$pkgsum" ]; then
typeset -i iTotal=$( echo "$pkgsum" | wc -l )
typeset -i iFound=0
# show filtered view
for filterfile in $( ls -1 $0-data/*txt | sort )
do
filtername=$( echo $filterfile | rev | cut -f 1 -d "/" | rev | sed "s#.txt\$##g" | sed "s#^[0-9]*_##g" )
filterdata=$( cat ${filterfile} | grep "^[a-zA-Z]" )
out=$( echo "$pkgsum" | _filterPkg "${filterdata}" )
typeset -i 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 "No package matched a group filter."
else
echo "Other packages: $iOther"
fi
# total packages
echo Total packages to install: $iTotal
fi
ph.exit
# ----------------------------------------------------------------------