chiark / gitweb /
Allow a subset of checks to be run.
[rcheck] / check.d / 50.updates
CommitLineData
f5f6d9ac
MW
1#! /usr/bin/python
2###
3### Report on available package updates, including security updates.
4
5import time as T
6import os as OS
7import errno as E
8
9import apt_pkg as APT
10import apt.cache as AC
11
12###--------------------------------------------------------------------------
13### Some utility functions.
14
15def cache_up_to_date_p():
16 """Answer whether the cache is up-to-date."""
17
18 ## I use the same stamp file as APT's standard periodic update service.
19 ## This needs prodding via a hook in the APT configuration.
20 now = T.time()
21 try:
22 last = OS.path.getmtime('/var/lib/apt/periodic/update-stamp')
23 except OSError, err:
24 if err.errno == E.ENOENT:
25 return False
26 return now - last < 86400
27
28def upgradable_packages():
29 """Return a list of packages for which updates are available."""
30 cache = AC.Cache()
31 return [pkg for pkg in cache if pkg.is_upgradable]
32
33def security_updates_p(pkg):
34 """Answer whether any update for PKG is security-relevant."""
35
36 ## There doesn't seem to be a good way of doing this. For distributions
37 ## like `testing', security updates are folded into the main distribution
38 ## after the usual triage process, so they stop looking like security
39 ## updates. Worse, for `unstable' there aren't distinct security updates
40 ## anyway: they're all just thrown into the mixer. The good way to tell
41 ## would be to fetch the changelog and look for urgent changes. Debian's
42 ## Aptitude checks explicitly for `security.debian.org'. This check at
43 ## least also captures Ubuntu.
44 for v in pkg.versions:
45 if v < pkg.installed:
46 continue
47 for o in v.origins:
48 if o.site.startswith('security.'):
49 return True
50 return False
51
52###--------------------------------------------------------------------------
53### Main program.
54
55if not cache_up_to_date_p():
56 print 'W: package cache is more than 24 hours of date'
57updates = upgradable_packages()
58if updates:
59 plural = len(updates) != 1
60 print 'I: updates available for %d %s' % \
61 (len(updates), plural and 'packages' or 'package')
62sec = [pkg for pkg in updates if security_updates_p(pkg)]
63if sec:
64 plural = len(sec) != 1
65 print 'W: security updates available for %d %s' % \
66 (len(sec), plural and 'packages' or 'package')
67
68###----- That's all, folks --------------------------------------------------