#!/usr/bin/env python # Check for override mismatches between architectures # Copyright (C) 2005, 2008 Colin Watson # $Id$ # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ################################################################################ import sys, re import utils import apt_pkg import gzip ################################################################################ Cnf = None Options = None ################################################################################ def usage(exit_code=0): print """Usage: architecture-mismatches [OPTIONS] Check for override mismatches between architectures. -h, --help show this help and exit -s, --suite check this suite """ sys.exit(exit_code) ################################################################################ def process(suite, components, arches): global Options archive = "/srv/launchpad.net/ubuntu-archive/ubuntu/" pkgcomp = {} pkgsect = {} pkgprio = {} for component in components: for arch in arches: try: binaries = gzip.open(archive + "dists/%s/%s/binary-%s/Packages.gz" % (suite, component, arch)) except IOError: continue for stanza in re.split(r'\n\n+', binaries.read()): fields = {} for line in stanza.splitlines(): if line.find(": ") != -1: (key, value) = line.split(": ", 1) fields[key.lower()] = value if 'package' in fields: pkg = fields['package'] pkgcomp.setdefault(pkg, {}) pkgcomp[pkg].setdefault(component, []) pkgcomp[pkg][component].append(arch) if 'section' in fields: section = fields['section'] pkgsect.setdefault(pkg, {}) pkgsect[pkg].setdefault(section, []) pkgsect[pkg][section].append(arch) if 'priority' in fields: priority = fields['priority'] pkgprio.setdefault(pkg, {}) pkgprio[pkg].setdefault(priority, []) pkgprio[pkg][priority].append(arch) binaries.close() packages = pkgcomp.keys() packages.sort() print "Packages with inconsistent components between architectures:" print "------------------------------------------------------------" print for pkg in packages: if len(pkgcomp[pkg]) > 1: out = [] for component in sorted(pkgcomp[pkg]): out.append("%s [%s]" % (component, ' '.join(sorted(pkgcomp[pkg][component])))) print "%s: %s" % (pkg, ' '.join(out)) print print "Packages with inconsistent sections between architectures:" print "----------------------------------------------------------" print for pkg in packages: if pkg in pkgsect and len(pkgsect[pkg]) > 1: out = [] for section in sorted(pkgsect[pkg]): out.append("%s [%s]" % (section, ' '.join(sorted(pkgsect[pkg][section])))) print "%s: %s" % (pkg, ' '.join(out)) print print "Packages with inconsistent priorities between architectures:" print "------------------------------------------------------------" print for pkg in packages: if pkg in pkgprio and len(pkgprio[pkg]) > 1: out = [] for priority in sorted(pkgprio[pkg]): out.append("%s [%s]" % (priority, ' '.join(sorted(pkgprio[pkg][priority])))) print "%s: %s" % (pkg, ' '.join(out)) print def main(): global Cnf, Options Cnf = utils.get_conf() Arguments = [('h', "help", "ArchMismatch::Options::Help"), ('s', "suite", "ArchMismatch::Options::Suite", "HasArg")] for i in ["help"]: if not Cnf.has_key("ArchMismatch::Options::%s" % (i)): Cnf["ArchMismatch::Options::%s" % (i)] = "" if not Cnf.has_key("ArchMismatch::Options::Suite"): Cnf["ArchMismatch::Options::Suite"] = "jaunty" # XXX should use site-wide default apt_pkg.ParseCommandLine(Cnf, Arguments, sys.argv) Options = Cnf.SubTree("ArchMismatch::Options") if Options["Help"]: usage() suite = Options["Suite"] components = ["main", "restricted", "universe", "multiverse"] arches = ["amd64", "armel", "hppa", "i386", "ia64", "lpia", "powerpc", "sparc"] process(suite, components, arches) ################################################################################ if __name__ == '__main__': main()