Назад | Перейти на главную страницу

как отслеживать обновления пакетов linux на нескольких серверах / контейнерах (заменяя apticron)

Я запускаю несколько серверов и в каждом по дюжине контейнеров (lxc). Я все еще использую apticron для получения информации о новых обновлениях пакетов, но я начинаю тонуть в электронных письмах от каждого контейнера, и обычно они сообщают об одном и том же обновлении, поскольку все они похожи.

Что мне действительно нужно знать: какие обновления пакета ожидают на каких узлах (желательно в одном сообщении).

В основном мне нравится apticron, но количество писем выходит из-под контроля.

(думал об использовании icinga2, но ему не хватало информации, а также уведомлений для каждого узла отдельно)

это не отвечает на мой вопрос, и ocsinventory слишком тяжелый для этой работы: Как отслеживать версии пакетов на нескольких (Linux) серверах

поэтому я пошел дальше и создал скрипт Python, который делает трюк
это мой первый питон, так что помилуй

сценарий должен запускаться от имени пользователя root, зависит от установленных apt, apt-listchanges и имеет смысл только при запуске lxc, но я предполагаю, что lxc-attach можно переключить в пользу запуска команды через ssh.

он перечисляет каждый пакет только один раз и какие узлы затронуты, а также подробно перечисляет комбинированные изменения.

вывод:

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

код:

#!/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