我运行多个服务器,每个服务器中有十几个容器 (lxc)。我仍然使用 apticron 获取有关新软件包更新的信息,但我开始被来自每个容器的电子邮件淹没,而且通常它们报告相同的更新,因为它们都很相似。
我真正需要知道的是:哪些节点上有哪些软件包更新待处理(最好在一条消息中)。
基本上我喜欢 apticron,但电子邮件的数量已经失控了。
(考虑使用 icinga2 但是它缺少信息并且还会单独通知每个节点)
这并没有回答我的问题,并且 ocsinventory 对于这项工作来说太重了:如何监控多个 (Linux) 服务器上的软件包版本
答案1
所以我继续编写了一个 Python 脚本,它能解决这个问题,
这是我的第一个 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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