check_packages2install 8.29 KB
Newer Older
Hahn Axel (hahn)'s avatar
Hahn Axel (hahn) committed
1
2
3
4
#!/bin/bash
# ======================================================================
#
# NAGIOS CLIENT CHECK :: check available package updates
5
# for centos/debian/manjaro/ubuntu
Hahn Axel (hahn)'s avatar
Hahn Axel (hahn) committed
6
7
8
9
10
11
12
13
14
15
16
17
#
# ----------------------------------------------------------------------
#
# 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)
Hahn Axel (hahn)'s avatar
Hahn Axel (hahn) committed
18
# 2021-05-11  v1.4  <axel.hahn@iml.unibe.ch> added centos8 support
Martin's avatar
Martin committed
19
# 2021-08-20  v1.5  <martin.gasser@iml.unibe.ch> bug fixing - missing sudo in yum command
20
# 2021-12-16  v1.6  <axel.hahn@iml.unibe.ch> show filtered overview
21
# 2021-12-17  v1.7  <axel.hahn@iml.unibe.ch> show non matching packages in section "other"
22
# 2021-12-20  v1.8  <axel.hahn@iml.unibe.ch> show all packages if no filter matched
23
# 2022-06-03  v1.9  <axel.hahn@iml.unibe.ch> call yum with path; shellcheck updates; plugin like package managers
Hahn Axel (hahn)'s avatar
Hahn Axel (hahn) committed
24
25
26
# ======================================================================


27
28
29
30
. $( dirname "$0" )/inc_pluginfunctions

readonly iWarnDefault=1
readonly iCriticalDefault=200
Hahn Axel (hahn)'s avatar
Hahn Axel (hahn) committed
31
32
33

typeset -i iCount=0
cronfile=/etc/cron.d/system-updater
34
35
MYhost="localhost"

36
37
dir_pkg="$( dirname $0 )/check_packages2install-pkgmanager"
dir_filter="$( dirname $0 )/check_packages2install-data"
Hahn Axel (hahn)'s avatar
Hahn Axel (hahn) committed
38
39
40
41
42

# ----------------------------------------------------------------------
# functions
# ----------------------------------------------------------------------

43
44
45
46
47
48
# 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
Hahn Axel (hahn)'s avatar
Hahn Axel (hahn) committed
49
    echo Autoupdate ON
50
51
    if grep "\ \-r" ${cronfile} >/dev/null 2>&1
    then
Hahn Axel (hahn)'s avatar
Hahn Axel (hahn) committed
52
53
54
55
56
57
58
59
      echo Autoreboot ON
    else
      echo Autoreboot OFF
    fi
  else
    echo Autoupdate OFF
  fi
}
60

61
# execute a local or a remote command
62
# param  string  commandline with command and its params
63
64
65
66
67
68
69
70
function _exec(){
    if [ ${MYhost} = "localhost" ]; then
        eval "$1"
    else
        ${MYsshprefix}${MYhost} "$1"
    fi
}

71
72
73
74
# check if a given function name exists
# param  string  name of a function
function _functionExists(){
  [[ $(type -t $1) == function ]]
75
76
}

77
78
79
80
81
82
# show help
function showHelp(){
    local _self
    _self=$(basename $0)
cat <<EOF
______________________________________________________________________
83

84
85
CHECK PACKAGES TO INSTALL
Get packages that must be updated on this system
86

87
88
89
(c) Institute for Medical Education - University of Bern
Licence: GNU GPL 3
______________________________________________________________________
90

91
92
Get packages that must be updated on this system ans show found 
packages in groups.
93

94
95
For groups and their search filters see files in subdir 
check_packages2install-data.
96

97
98
99
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.
100

101
On CentOS it switches to ERROR if a critcal update was found.
102

103
104
105
106
107
Tested operating systems:
- Centos
- Debian
- Manjaro
- Ubuntu
Hahn Axel (hahn)'s avatar
Hahn Axel (hahn) committed
108

109
110
SYNTAX:
$_self [options]
Hahn Axel (hahn)'s avatar
Hahn Axel (hahn) committed
111

112
OPTIONS:
Hahn Axel (hahn)'s avatar
Hahn Axel (hahn) committed
113

114
115
116
    -h   show this help
    -w   custom warning level; default: $iWarnDefault
    -c   custom critical level; default: $iCriticalDefault
Hahn Axel (hahn)'s avatar
Hahn Axel (hahn) committed
117

118
PARAMETERS:
Hahn Axel (hahn)'s avatar
Hahn Axel (hahn) committed
119

120
    None.
Hahn Axel (hahn)'s avatar
Hahn Axel (hahn) committed
121

122
EOF
Hahn Axel (hahn)'s avatar
Hahn Axel (hahn) committed
123
124
}

125
126
127
128
129
130
131
132
133
# 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"
Hahn Axel (hahn)'s avatar
Hahn Axel (hahn) committed
134

135
136
    grep $_moreparams -E "^($_filter)"
}
Hahn Axel (hahn)'s avatar
Hahn Axel (hahn) committed
137

138
139
140
141
142
143
144
145
# 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
Hahn Axel (hahn)'s avatar
Hahn Axel (hahn) committed
146
}
147

148
149
150
# ----------------------------------------------------------------------

# show grouped packages by category
151
152
# global  string  dir_filter     directory where to find filters
# global  string  packagemanOut  output of update lister command
153
154
155
function showFilteredPackages(){

  # filtered package view
156
157
158
  if [ ! -z "$packages2install" ]; then
      typeset -i iTotal
      iTotal=$( echo "$packages2install" | wc -l )
159
      typeset -i iFound=0
160
      filterAll=""
161
162

      # show filtered view
163
      for filterfile in $( find "$dir_filter" -name "*txt" | sort )
164
      do
165
166
167
168
169
170
171
          # 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
172
          filterAll="$filterAll $filterdata"
173

174
175
176
          out=$( echo "$packages2install" | _filterPkg "${filterdata}" )
          typeset -i iCount
          iCount=$( echo "$out" | grep "." | wc -l )
177
178
179
180
181
182
183
184
185
186
187

          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
188
          echo "--- All packages (No package matched a group filter):"
189
      else
190
          echo "--- Other packages: $iOther"
191
      fi
192
      echo "$packages2install" | _filterPkg "${filterAll}" "-v" | nl
193
      echo
194
195
196

      # total packages
      echo Total packages to install: $iTotal
197
      ph.perfadd "updates-available" "$iTotal"  ${iWarnLimit} ${iCriticalLimit}
198
199
200
201

  fi

}
Hahn Axel (hahn)'s avatar
Hahn Axel (hahn) committed
202
203
204
205
206

# ----------------------------------------------------------------------
# main
# ----------------------------------------------------------------------

207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
# ----- 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

224
# load functions for the detected package manager
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
. "${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
275

276
fi
Hahn Axel (hahn)'s avatar
Hahn Axel (hahn) committed
277
278
279
280

ph.exit

# ----------------------------------------------------------------------