check_packages2install 8.71 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
24
25
# 2022-06-07  v1.10 <axel.hahn@iml.unibe.ch> fix iPkg2Update on empty package list
#                                            rename package manager functions
Hahn Axel (hahn)'s avatar
Hahn Axel (hahn) committed
26
27
28
# ======================================================================


29
30
31
32
. $( dirname "$0" )/inc_pluginfunctions

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

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

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

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

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

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

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

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

86
87
CHECK PACKAGES TO INSTALL
Get packages that must be updated on this system
88

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

93
Get packages that must be updated on this system and show found 
94
packages in groups.
95

96
97
98
99
100
101
102
103
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.
104

105
106
107
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.
108

109
On CentOS it switches to ERROR if a critcal update was found.
110

111
112
113
114
115
Tested operating systems:
- Centos
- Debian
- Manjaro
- Ubuntu
Hahn Axel (hahn)'s avatar
Hahn Axel (hahn) committed
116

117
118
SYNTAX:
$_self [options]
Hahn Axel (hahn)'s avatar
Hahn Axel (hahn) committed
119

120
OPTIONS:
Hahn Axel (hahn)'s avatar
Hahn Axel (hahn) committed
121

122
123
    -w   custom warning level; default: $iWarnDefault
    -c   custom critical level; default: $iCriticalDefault
Hahn Axel (hahn)'s avatar
Hahn Axel (hahn) committed
124

125
PARAMETERS:
Hahn Axel (hahn)'s avatar
Hahn Axel (hahn) committed
126

127
    -h   show this help
Hahn Axel (hahn)'s avatar
Hahn Axel (hahn) committed
128

129
EOF
Hahn Axel (hahn)'s avatar
Hahn Axel (hahn) committed
130
131
}

132
133
134
135
136
137
138
139
140
# 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
141

142
143
    grep $_moreparams -E "^($_filter)"
}
Hahn Axel (hahn)'s avatar
Hahn Axel (hahn) committed
144

145
146
147
148
149
150
151
152
# 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
153
}
154

155
156
157
# ----------------------------------------------------------------------

# show grouped packages by category
158
159
# global  string  dir_filter     directory where to find filters
# global  string  packagemanOut  output of update lister command
160
161
162
function showFilteredPackages(){

  # filtered package view
163
  if [ -n "$packages2install" ]; then
164
165
      typeset -i iTotal
      iTotal=$( echo "$packages2install" | wc -l )
166
      typeset -i iFound=0
167
      filterAll=""
168
169

      # show filtered view
170
      for filterfile in $( find "$dir_filter" -name "*txt" | sort )
171
      do
172
173
174
175
176
177
178
          # 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
179
          filterAll="$filterAll $filterdata"
180

181
182
183
          out=$( echo "$packages2install" | _filterPkg "${filterdata}" )
          typeset -i iCount
          iCount=$( echo "$out" | grep "." | wc -l )
184
185
186
187
188
189
190
191
192
193
194

          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
195
          echo "--- All packages (No package matched a group filter):"
196
      else
197
          echo "--- Other packages: $iOther"
198
      fi
199
      echo "$packages2install" | _filterPkg "${filterAll}" "-v" | nl
200
      echo
201
202
203
204
205
206
207

      # total packages
      echo Total packages to install: $iTotal

  fi

}
Hahn Axel (hahn)'s avatar
Hahn Axel (hahn) committed
208
209
210
211
212

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

213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
# ----- 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

230
# load functions for the detected package manager
231
232
. "${dir_pkg}/${pkgmanager}.sh" || exit 2

233
packagemanOut=$( ${pkgmanager}.GetUpdates )
234
235
236
237
238
239
240

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
241
242
243
  function2install="${pkgmanager}.getPackageList"
  _functionExists "${pkgmanager}.getStatusLine"    && functionStatus="${pkgmanager}.getStatusLine"
  _functionExists "${pkgmanager}.getCriticalList"  && functionCritical="${pkgmanager}.getCriticalList"
244
245
246
247
248
249
250

  # count of packages ... to install ... critical (centos only)
  typeset -i iPkg2Update=0
  typeset -i iPkgCritical=0

  # get list of packages 2 install
  packages2install=$( $function2install )
251
  iPkg2Update=$( test -n "$packages2install" && echo "$packages2install" | wc -l )
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267

  # 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
268
  ph.perfadd "updates-available" "${iPkg2Update}" "${iWarnLimit}" "${iCriticalLimit}"
269
270
271
272
273
274
275
276
277
278
279
280
281

  # 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
282

283
fi
Hahn Axel (hahn)'s avatar
Hahn Axel (hahn) committed
284
285
286
287

ph.exit

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