Skip to content

Instantly share code, notes, and snippets.

Last active Dec 9, 2020
What would you like to do?
python script to help with debugging unattended-upgrade filtering issues.
# running with no arguments will dump all the origins known by apt
# running with a list of package names as arguments will dump the sources for those packages and the known versions for those packages.
import os
import re
import string
import subprocess
import sys
import apt
import apt_pkg
# stolen form "unattended-upgrade"
DISTRO_CODENAME = subprocess.check_output(
["lsb_release", "-c", "-s"], universal_newlines=True).strip()
DISTRO_ID = subprocess.check_output(
["lsb_release", "-i", "-s"], universal_newlines=True).strip()
def substitute(line):
""" substitude known mappings and return a new string
Currently supported ${distro-release}
mapping = {"distro_codename": get_distro_codename(),
"distro_id": get_distro_id()}
return string.Template(line).substitute(mapping)
def get_distro_codename():
def get_distro_id():
return DISTRO_ID
def get_allowed_origins_legacy():
""" legacy support for old Allowed-Origins var """
allowed_origins = []
for s in apt_pkg.config.value_list("Unattended-Upgrade::Allowed-Origins"):
# if there is a ":" use that as seperator, else use spaces
if ":" in s:
(distro_id, distro_codename) = s.split(':')
(distro_id, distro_codename) = s.split()
# escape "," (see LP: #824856) - i wonder if there is a simpler way?
distro_id = re.sub(r'([^\\]),', r'\1\\,', distro_id)
distro_codename = re.sub(r'([^\\]),', r'\1\\,', distro_codename)
# convert to new format
allowed_origins.append("o=%s,a=%s" % (substitute(distro_id),
return allowed_origins
def get_allowed_origins():
""" return a list of allowed origins from apt.conf
This will take substitutions (like distro_id) into account.
allowed_origins = get_allowed_origins_legacy()
for s in apt_pkg.config.value_list("Unattended-Upgrade::Origins-Pattern"):
return allowed_origins
print ('Allowed origins:')
origins = list(set(get_allowed_origins()))
for i in origins:
cache = apt.Cache()
each = False
# check for subset
if len(sys.argv) >1:
pkg_list = sys.argv[1:]
each = True
pkg_list = cache.keys()
sources = set()
for i in pkg_list:
pkg = cache[i]
for version in pkg.versions:
for origin in
o = "o={}, l={}, a={}, c={}, site={}, n={}".format(origin.origin, origin.label, origin.archive, origin.component,, origin.codename)
if each:
o = "{} : {} : ".format(pkg, version.version) + o
if each:
print('Package : Version : Origin')
print ('System package origins:')
sources = list(sources)
for i in sources:
print (i)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment