0

I run multiple servers and in each a dozen containers (lxc). I'm still using apticron to get informations about new package updates but I start to drown in emails from each and every container and usually they report the same update since they're all similar.

What I really need to know is: what package updates are pending on which nodes (preferably in one message).

Basically I like apticron but the number of emails is getting out of hand.

(thought about using icinga2 but it would lack information and also notify for each node individually)

this doesn't answer my question and ocsinventory is to heavy for this job: How to monitor package versions across multiple (Linux) servers

greenone83
  • 209
  • 1
  • 7

1 Answers1

0

so I went ahead and built a python script which does the trick
it's my first python so have mercy

the script has to run as root, depends on apt, apt-listchanges being installed and makes only sense if you run lxc, but i guess the lxc-attach could be switched in favor of running the command over ssh.

it lists each package only once and which hosts are affected, also it lists the combined changes in detail.

output:

apt-monitor on ***
2017-04-16 20:28:25.394625 UTC

----- packages -----

linux-image-4.9.0-0.bpo.2-amd64
    version old: 4.9.13-1~bpo8+1
    version new: 4.9.18-1~bpo8+1
    affected hosts:
     - master

tzdata
    version old: 2017a-0+deb8u1
    version new: 2017b-0+deb8u1
    affected hosts:
     - master
     - service-mysql
     - www-stage

----- changes -----
linux-signed (4.4~bpo8+1) jessie-backports; urgency=medium

  * Rebuild for jessie-backports
  * Update to linux version 4.9.18-1~bpo8+1

 -- Ben Hutchings <ben@decadent.org.uk>  Wed, 12 Apr 2017 15:50:11 +0100

linux-signed (4.4) unstable; urgency=medium

  * Update to linux version 4.9.18-1

 -- Ben Hutchings <ben@decadent.org.uk>  Thu, 30 Mar 2017 17:43:56 +0100

tzdata (2017b-0+deb8u1) stable; urgency=medium

  * New upstream version, affecting the following future timestamp:
    - Haiti resumed observance of DST in 2017.

 -- Aurelien Jarno <aurel32@debian.org>  Thu, 06 Apr 2017 11:53:44 +0200

code:

#!/usr/bin/python

import re
import string
import subprocess
import sys
import datetime
import socket

# extract updates from apt output
def collect_upgrades(host, changes, upgrades, is_lxc):
  changes = changes.split('\n')
  pattern = re.compile('^Inst ([\S]+) \[([^\]]+)\] \(([\S]+) [^\[]*\[([^\]]+)\]\)')
  for change in changes:
    if pattern.match(change):
      matches = pattern.search(change)    
      upgrade = {'name' : matches.group(1), 'version_old' : matches.group(2), 'version_new' : matches.group(3), 'suffix' : matches.group(4), 'hosts' : [], 'is_lxc' : is_lxc}
      key = upgrade['name']+'_'+upgrade['version_new']
      if not key in upgrades:
        upgrades[key] = upgrade
      upgrades[key]['hosts'] += [host]

# distinct package update lookup
upgrades = {}

# gather changes from host and containers
changes = subprocess.check_output(['apt-get', '--just-print', 'dist-upgrade'])
collect_upgrades('master', changes, upgrades, False)

containers = subprocess.check_output(['lxc-ls', '-1']).strip().split('\n')
for container in containers:
  changes = subprocess.check_output(['lxc-attach', '-n', container, '--', 'apt-get', '--just-print', 'dist-upgrade'])
  collect_upgrades(container, changes, upgrades, True)

# if upgrades is empty we can exit
if not bool(upgrades):
  sys.exit(0)

# collect details apt-listchanges output for each package update
# also print upgrades

# print header


print 'apt-monitor on '+socket.gethostname()
print str(datetime.datetime.utcnow())+' UTC'
print ''
print '----- packages -----'

apt_changes = ''
for key, upgrade in upgrades.iteritems():
  deb_file = '/var/cache/apt/archives/'+upgrade['name']+'_'+upgrade['version_new']+'_'+upgrade['suffix']+'.deb'
  if upgrade['is_lxc']:
    container = upgrade['hosts'][0]
    apt_changes += subprocess.check_output(['lxc-attach', '-n', container, '--', 'apt-listchanges', '-f', 'text', deb_file])
  else:
    apt_changes += subprocess.check_output(['apt-listchanges', '-f', 'text', deb_file])  
  print ''
  print upgrade['name']
  print '    version old: '+upgrade['version_old']
  print '    version new: '+upgrade['version_new']
  print '    affected hosts:'
  for host in upgrade['hosts']:
    print '     - '+host

print ''
print '----- changes -----'
print apt_changes
greenone83
  • 209
  • 1
  • 7