Commit 9610acf5 authored by Hahn Axel (hahn)'s avatar Hahn Axel (hahn)
Browse files

rewrite with pkg managers plugins like

parent e96d5682
......@@ -2,7 +2,7 @@
# ======================================================================
#
# NAGIOS CLIENT CHECK :: check available package updates
# requires no root for yum ... apt I must verify
# for centos/debian/manjaro/ubuntu
#
# ----------------------------------------------------------------------
#
......@@ -20,27 +20,35 @@
# 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
# ======================================================================
. `dirname $0`/inc_pluginfunctions
. $( dirname "$0" )/inc_pluginfunctions
readonly iWarnDefault=1
readonly iCriticalDefault=200
typeset -i iCount=0
tmpfile=/tmp/packages2install.log
cronfile=/etc/cron.d/system-updater
MYhost="localhost"
dir_pkg="$( dirname $0 )/check_packages2install-pkgmanager"
dir_filter="$( dirname $0 )/check_packages2install-data"
# ----------------------------------------------------------------------
# functions
# ----------------------------------------------------------------------
function showAutoupdate(){
ls ${cronfile} >/dev/null 2>&1
if [ $? -eq 0 ]; then
# 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
grep "\ \-r" ${cronfile} >/dev/null 2>&1
if [ $? -eq 0 ]; then
if grep "\ \-r" ${cronfile} >/dev/null 2>&1
then
echo Autoreboot ON
else
echo Autoreboot OFF
......@@ -49,7 +57,9 @@ function showAutoupdate(){
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"
......@@ -58,141 +68,83 @@ function _exec(){
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)
# param2 text additional grep params; "-v" to invert filtering
function _filterPkg(){
local _filter=$( echo $1 | tr " " "|" )
local _moreparams=$2
grep $_moreparams -E "^($_filter)"
# check if a given function name exists
# param string name of a function
function _functionExists(){
[[ $(type -t $1) == function ]]
}
# 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
}
# show help
function showHelp(){
local _self
_self=$(basename $0)
cat <<EOF
______________________________________________________________________
# Debian like Linux
# - Debian 10
# - Debian 11
# - Ubuntu
function pkgApt(){
CHECK PACKAGES TO INSTALL
Get packages that must be updated on this system
local sum=$( _exec "sudo apt-get -u upgrade --assume-no" )
(c) Institute for Medical Education - University of Bern
Licence: GNU GPL 3
______________________________________________________________________
# 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 ':' )
Get packages that must be updated on this system ans show found
packages in groups.
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(){
For groups and their search filters see files in subdir
check_packages2install-data.
# local sum=$( _exec "sudo dnf check-update" )
local sum=$( _exec "sudo yum -y check-update" )
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.
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='$'
On CentOS it switches to ERROR if a critcal update was found.
echo "$sum" | sed -n ${iStart},${sEnd}p
# echo "show lines ${iStart} -> ${sEnd}"
Tested operating systems:
- Centos
- Debian
- Manjaro
- Ubuntu
}
# 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
SYNTAX:
$_self [options]
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 " "`
OPTIONS:
ph.setStatusByLimit ${iPkg2Update} ${iWarnLimit} ${iCriticalLimit}
ph.perfadd "updates-available" "${iPkg2Update}" ${iWarnLimit} ${iCriticalLimit}
-h show this help
-w custom warning level; default: $iWarnDefault
-c custom critical level; default: $iCriticalDefault
# --- output
ph.status "$summary"
echo "[apt]"
echo
PARAMETERS:
fi
None.
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"
# 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 )
local summary=$( /usr/bin/yum --bugfix check-update 2>&1 | 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
# III No security updates needed, but 61 updates available << centos 8 stream
typeset -i local iPkgSecurity
iPkgSecurity=$( echo "$summary" | cut -f 1 -d ' ' | sed "s#[^0-9]##g")
typeset -i local iPkg2Update
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
grep $_moreparams -E "^($_filter)"
}
echo
# 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
......@@ -200,42 +152,49 @@ function checkYum(){
function showFilteredPackages(){
# filtered package view
if [ ! -z "$pkgsum" ]; then
typeset -i iTotal=$( echo "$pkgsum" | wc -l )
if [ ! -z "$packages2install" ]; then
typeset -i iTotal
iTotal=$( echo "$packages2install" | wc -l )
typeset -i iFound=0
filterAll=""
# show filtered view
for filterfile in $( ls -1 $0-data/*txt | sort )
local _selfdir=$( dirname "$0" )
for filterfile in $( find $dir_filter -name "*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]" )
# 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 "$pkgsum" | _filterPkg "${filterdata}" )
typeset -i iCount=$( echo "$out" | grep "." | wc -l )
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 "Remark: No package matched a group filter."
echo "--- All packages:"
echo "--- All packages (No package matched a group filter):"
else
echo "--- Other packages: $iOther"
fi
echo "$pkgsum" | _filterPkg "${filterAll}" "-v" | nl
echo "$packages2install" | _filterPkg "${filterAll}" "-v" | nl
echo
# total packages
echo Total packages to install: $iTotal
ph.perfadd "updates-available" "$iTotal" ${iWarnLimit} ${iCriticalLimit}
fi
......@@ -245,36 +204,75 @@ function showFilteredPackages(){
# 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
. "${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}Packages"
_functionExists "${pkgmanager}Status" && functionStatus="${pkgmanager}Status"
_functionExists "${pkgmanager}Critical" && functionCritical="${pkgmanager}Critical"
# 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=$( 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
# 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
# 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")
checkApt
pkgsum=$( pkgApt )
;;
"pamac")
# pkgstatus=""
pkgsum=$( pkgPamac )
;;
"yum")
checkYum
pkgsum=$( pkgYum )
;;
*)
ph.abort "UNKNOWN: package manager [$pgkman] was not detected or is not supported yet."
;;
esac
# echo "$pkgstatus"
echo
showAutoupdate
echo
showFilteredPackages
fi
ph.exit
......
#!/bin/bash
# ===============================================================
#
# PACKAGE MANAGER: APT
# Debian, Ubuntu
#
# included by ../check_packages2install
#
# ---------------------------------------------------------------
# ah <axel.hahn@iml.unibe.ch>
# 2022-06-03 v1.0 ah first version
# ===============================================================
# ---------------------------------------------------------------
# command to list of updates
function aptGetUpdates(){
sudo apt-get -u upgrade --assume-no
}
# ---------------------------------------------------------------
# extract list of packages 2 install
# global string packagemanOut output of update lister command
function aptPackages(){
# detect number of line containing "The following packages will be upgraded:"
typeset -i local iStart
iStart=$( echo "$packagemanOut" | 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 "$packagemanOut" | sed -n $iStart,\$p | grep "^\ \ " | sed "s#^\ \ ##g" | tr " " "\n"
fi
}
# ---------------------------------------------------------------
# get status line on apt based systems (debian, ubuntu)
# global string packagemanOut output of update lister command
function aptStatus(){
echo "$packagemanOut" | grep "upgraded.*installed"
}
# ---------------------------------------------------------------
#!/bin/bash
# ===============================================================
#
# PACKAGE MANAGER: PAMAC
# Manjaro
#
# included by ../check_packages2install
#
# ---------------------------------------------------------------
# ah <axel.hahn@iml.unibe.ch>
# 2022-06-03 v1.0 ah first version
# ===============================================================
# ---------------------------------------------------------------
# command to list of updates
function pamacGetUpdates(){
pamac checkupdates
}
# ---------------------------------------------------------------
# extract list of packages 2 install
function pamacPackages(){
echo "$packagemanOut" | grep -- '->'
}
# ---------------------------------------------------------------
#!/bin/bash
# ===============================================================
#
# PACKAGE MANAGER: YUM
# CentOS
#
# included by ../check_packages2install
#
# ---------------------------------------------------------------
# ah <axel.hahn@iml.unibe.ch>
# 2022-06-03 v1.0 ah first version
# ===============================================================
# ---------------------------------------------------------------
# command to list of updates
function yumGetUpdates(){
sudo /usr/bin/yum -y check-update
}
# ---------------------------------------------------------------
# extract list of packages 2 install
# global string packagemanOut output of update lister command
function yumPackages(){
local iStart=3
# detect number of line containing "Obsoleting Packages"
typeset -i iEnd=$( echo "$packagemanOut" | grep -n '^Obsoleting Packages' | cut -f 1 -d ':' )-1
local sEnd=$iEnd
test "$iEnd" = "-1" && sEnd='$'
echo "$packagemanOut" | sed -n ${iStart},${sEnd}p
}
# ---------------------------------------------------------------
# get custom status
function yumStatus(){
if ! /usr/bin/yum --bugfix check-update 2>&1 | grep security; then
echo "Ooops - no output from [/usr/bin/yum --bugfix check-update]"
fi
}
# ---------------------------------------------------------------
# extract count of critical
# param string text to extract critical counter from
function yumCritical(){
local summary="$1"
# example outputs:
# I No packages needed for security; 223 packages available
# II 2 package(s) needed for security, out of 237 available
# III No security updates needed, but 61 updates available << centos 8 stream
echo "$summary" | cut -f 1 -d ' ' | sed "s#[^0-9]##g"
}
# ---------------------------------------------------------------
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment