Well, after some more refining I think I finally have a script I ain’t never gonna touch again (unless something breaks, which can happen quick as we all know).

The script now uses a sysconfig file for the common settings (like sender, receipents, categories to scan for), so it may be deployed en mass.

/etc/sysconfig/zypper-update-report

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
## Type: string
## Default: root
## Config: ""
#
# Sender address for the update report
FROM="Yourupdatemonkey "

## Type: string
## Default: root
## Config: ""
#
# Receiver address for the update report
#RECEIPENTS="tehsysadmin@barfoo.org"

## Type: string
## Default: "securty recommended optional"
## Config: ""
#
# List of groups, to include in the report
CLASSES="security recommended optional"

/usr/local/sbin/zypper-update-report

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#!/bin/bash

# Checks the output of `zypper pch` for security/recommended/optional updates
# and prepares a detailed report to be mailed to the administrators

[ -f /etc/sysconfig/update-report ] || exit 1

source /etc/sysconfig/update-report

# Temporary files
TMPDIR="$( mktemp -d /tmp/update-report.XXXXXX )"
ZYPP_LIST="$TMPDIR/zypper-list"
ZYPP_DETAILS="$TMPDIR/zypper-details"
ZYPP_REPORT="$TMPDIR/zypper-report"
zypper pch 2>/dev/null > $ZYPP_LIST

# Figure out how much updates are still pending
PENDING="$( cat $ZYPP_LIST | grep "| Needed" | wc -l )"

if [ $PENDING -eq 0 ] ; then
  exit 0
fi

echo > $ZYPP_REPORT
echo " Pending updates for $( domainname -f ) on $( date )" >> $ZYPP_REPORT

for severity in $CLASSES; do
  PACKAGES="$( cat $ZYPP_LIST | egrep "${severity}(.*)| Needed" | cut -d| -f2 | sed "s,^ ,," | sort -u )"
  [ -n "$PACKAGES" ] && echo
  [ -n "$PACKAGES" ] && echo "  Category: $severity"
  for package in $PACKAGES; do
    zypper patch-info $package 2>/dev/null > $ZYPP_DETAILS
    echo ""
    echo "  * Patch: $package"
    echo "    Needs reboot: $( cat $ZYPP_DETAILS | grep "Reboot Required:" | sed -e "s,Reboot Required: ,," )"
    echo "    Affected packages: "
    for atom in $( cat $ZYPP_DETAILS | grep "^atom:" | cut -d  -f2 | sort ); do
      # Let's check whether or not the package listed in atom is installed ...
      # If installed, echo the atom, otherwise don't as we don't need to update
      # the package.
      RPM_STATUS=$( rpm -qi $atom )
      if [ "$RPM_STATUS" != "package $atom is not installed" ] ; then
        echo "    - $atom "
      fi
    done
  done
done >> $ZYPP_REPORT

if [ -n "$RECEIPENTS" ] ; then
  cat $ZYPP_REPORT | mail -r "$FROM" -s "[$( date +%F )] Update report for $( domainname -f )" $RECEIPENTS
fi

trap "rm -rf "$TMPDIR" >/dev/null 2>&1" ERR EXIT
# vim: set tw=80 ts=2 sw=2 et softtabstop=2