3
from __future__ import print_function
7
from contextlib import closing
8
from optparse import OptionParser
13
from urllib.request import urlretrieve
15
from urllib import urlretrieve
18
from launchpadlib.launchpad import Launchpad
29
tempdir = tempfile.mkdtemp(prefix="orphaned-sources")
30
atexit.register(shutil.rmtree, tempdir)
33
def decompress_open(tagfile):
34
if tagfile.startswith("http:") or tagfile.startswith("ftp:"):
36
tagfile = urlretrieve(url)[0]
38
if tagfile.endswith(".bz2"):
40
decompressed = tempfile.mktemp(dir=tempdir)
41
with closing(bz2.BZ2File(tagfile)) as fin:
42
with open(decompressed, "wb") as fout:
43
fout.write(fin.read())
44
return open(decompressed, "r")
46
return open(tagfile, "r")
49
def archive_base(archtag):
50
if archtag in ("amd64", "i386", "src"):
51
return "http://archive.ubuntu.com/ubuntu"
53
return "http://ports.ubuntu.com/ubuntu-ports"
56
def source_names(options):
58
for component in "main", "restricted", "universe", "multiverse":
59
url = "%s/dists/%s/%s/source/Sources.bz2" % (
60
archive_base("src"), options.suite, component)
61
print("Reading %s ..." % url, file=sys.stderr)
62
for section in apt_pkg.TagFile(decompress_open(url)):
63
sources.add(section["Package"])
67
def referenced_sources(options):
69
for component in "main", "restricted", "universe", "multiverse":
70
for arch in options.architectures:
71
archtag = arch.architecture_tag
72
for suffix in "", "/debian-installer":
73
url = "%s/dists/%s/%s%s/binary-%s/Packages.bz2" % (
74
archive_base(archtag), options.suite, component, suffix,
76
print("Reading %s ..." % url, file=sys.stderr)
77
for section in apt_pkg.TagFile(decompress_open(url)):
78
if "Source" in section:
79
sources.add(section["Source"].split(" ", 1)[0])
81
sources.add(section["Package"])
86
parser = OptionParser(
87
description="Check for sources without any remaining binaries.")
89
"-l", "--launchpad", dest="launchpad_instance", default="production")
90
parser.add_option("-s", "--suite", help="check this suite")
91
options, _ = parser.parse_args()
93
options.distribution = "ubuntu"
94
options.launchpad = Launchpad.login_anonymously(
95
"orphaned-sources", options.launchpad_instance)
96
lputils.setup_location(options)
98
if options.pocket != "Release":
99
parser.error("cannot run on non-release pocket")
101
orphaned_sources = source_names(options) - referenced_sources(options)
102
for source in sorted(orphaned_sources):
106
if __name__ == '__main__':