X-Git-Url: https://git.decadent.org.uk/gitweb/?a=blobdiff_plain;f=jenna;h=0f635cb4a041fe194f856e4c998ee504a152cea3;hb=bdbd8d4b06f3e5316be3a239b511c6d34e781105;hp=d2c8e17cd7bafebc8b0f33c7014fc85655dc3b35;hpb=4b41dc06229eed89f52f397fc7df5d665fa092cf;p=dak.git diff --git a/jenna b/jenna index d2c8e17c..0f635cb4 100755 --- a/jenna +++ b/jenna @@ -1,8 +1,8 @@ #!/usr/bin/env python # Generate file list which is then fed to apt-ftparchive to generate Packages and Sources files -# Copyright (C) 2000 James Troup -# $Id: jenna,v 1.3 2001-01-16 21:52:37 troup Exp $ +# Copyright (C) 2000, 2001 James Troup +# $Id: jenna,v 1.12 2001-06-22 22:53:14 troup Exp $ # 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 @@ -39,109 +39,170 @@ def generate_src_list(suite, component, output, dislocated_files): suite_id = db_access.get_suite_id(suite); if component == "-": - q = projectB.query("SELECT s.source, s.version, l.path, f.filename, s.id, f.id FROM source s, src_associations sa, location l, files f WHERE sa.source = s.id AND sa.suite = '%d' AND l.id = f.location AND s.file = f.id" + q = projectB.query("SELECT s.source, l.path, f.filename, f.id FROM source s, src_associations sa, location l, files f WHERE sa.source = s.id AND sa.suite = '%d' AND l.id = f.location AND s.file = f.id ORDER BY s.source, s.version" % (suite_id)); else: - q = projectB.query("SELECT s.source, s.version, l.path, f.filename, s.id, f.id FROM source s, src_associations sa, location l, component c, files f WHERE lower(c.name) = '%s' AND (c.id = l.component OR l.component = NULL) AND sa.source = s.id AND sa.suite = '%d' AND l.id = f.location AND s.file = f.id" + q = projectB.query("SELECT s.source, l.path, f.filename, f.id FROM source s, src_associations sa, location l, component c, files f WHERE lower(c.name) = '%s' AND (c.id = l.component OR l.component = NULL) AND sa.source = s.id AND sa.suite = '%d' AND l.id = f.location AND s.file = f.id ORDER BY s.source, s.version" % (component, suite_id)); entries = q.getresult(); for entry in entries: - source = entry[0] - version = entry[1] - filename = entry[2]+entry[3]; - id = entry[4] - add_new = 0 - file_id = entry[5]; + (source, path, filename, file_id) = entry; if dislocated_files.has_key(file_id): filename = dislocated_files[file_id]; - if os.path.exists(filename): - if sources.has_key(source): - if apt_pkg.VersionCompare(sources[source]["version"], version) == -1: - if not Cnf.Find("Suite::%s::Untouchable" % (suite)): - print "deleting %s (%s) in favour of newer version %s..." % (source, sources[source]["version"], version) - projectB.query("DELETE FROM src_associations WHERE source = %s AND suite = %d" % (sources[source]["id"], suite_id)) - else: - if Cnf.Find("Jenna::Options::Verbose"): - print "[untouchable] would delete %s (%s) in favour of newer version %s..." % (source, sources[source]["version"], version) - sources[source] = { "id": id, "version": version, "filename": filename } - else: - if not Cnf.Find("Suite::%s::Untouchable" % (suite)): - print "deleting %s (%s) in favour of newer version %s..." % (source, version, sources[source]["version"]) - projectB.query("DELETE FROM src_associations WHERE source = %s AND suite = %d" % (id, suite_id)) - else: - if Cnf.Find("Jenna::Options::Verbose"): - print "[untouchable] would delete %s (%s) in favour of newer version %s..." % (source, version, sources[source]["version"]) - else: - sources[source] = { "id": id, "version": version, "filename": filename } else: - if not Cnf.Find("Suite::%s::Untouchable" % (suite)): - sys.stderr.write("WARNING: deleting %s because it doesn't exist.\n" % (filename)); - projectB.query("DELETE FROM src_associations WHERE source = %s AND suite = %d" % (id, suite_id)) + filename = path + filename; + if sources.has_key(source): + utils.warn("%s in %s / %s / source is duplicated." % (source, suite, component)); + else: + sources[source] = filename; # Write the list of files out source_keys = sources.keys(); source_keys.sort(); for source in source_keys: - output.write(sources[source]["filename"]+'\n') + output.write(sources[source]+'\n') +######################################################################################### + def generate_bin_list(suite, component, architecture, output, type, dislocated_files): packages = {} suite_id = db_access.get_suite_id(suite); if component == "-": - q = projectB.query("SELECT b.package, b.version, l.path, f.filename, b.id, f.id FROM architecture a, binaries b, bin_associations ba, location l, files f WHERE ( a.arch_string = '%s' OR a.arch_string = 'all' ) AND a.id = b.architecture AND ba.bin = b.id AND ba.suite = '%d' AND l.id = f.location AND b.file = f.id AND b.type = '%s'" % (architecture, suite_id, type)); + q = projectB.query("SELECT b.package, l.path, f.filename, f.id FROM architecture a, binaries b, bin_associations ba, location l, files f WHERE ( a.arch_string = '%s' OR a.arch_string = 'all' ) AND a.id = b.architecture AND ba.bin = b.id AND ba.suite = '%d' AND l.id = f.location AND b.file = f.id AND b.type = '%s' ORDER BY b.package, b.version, a.arch_string" % (architecture, suite_id, type)); else: - q = projectB.query("SELECT b.package, b.version, l.path, f.filename, b.id, f.id FROM architecture a, binaries b, bin_associations ba, location l, component c, files f WHERE lower(c.name) = '%s' AND (c.id = l.component OR l.component = NULL) AND (a.arch_string = '%s' OR a.arch_string = 'all') AND a.id = b.architecture AND ba.bin = b.id AND ba.suite = '%d' AND l.id = f.location AND b.file = f.id AND b.type = '%s'" % (component, architecture, suite_id, type)); + q = projectB.query("SELECT b.package, l.path, f.filename, f.id FROM architecture a, binaries b, bin_associations ba, location l, component c, files f WHERE lower(c.name) = '%s' AND (c.id = l.component OR l.component = NULL) AND (a.arch_string = '%s' OR a.arch_string = 'all') AND a.id = b.architecture AND ba.bin = b.id AND ba.suite = '%d' AND l.id = f.location AND b.file = f.id AND b.type = '%s' ORDER BY b.package, b.version, a.arch_string" % (component, architecture, suite_id, type)); entries = q.getresult(); for entry in entries: - package = entry[0] - version = entry[1] - filename = entry[2]+entry[3]; - id = entry[4] - add_new = 0 - file_id = entry[5]; + (package, path, filename, file_id) = entry; if dislocated_files.has_key(file_id): filename = dislocated_files[file_id]; + else: + filename = path + filename; + if packages.has_key(package): + utils.warn("%s in %s / %s / %s / %s is duplicated." % (package, suite, component, architecture, type)); + else: + packages[package] = filename; + # Write the list of files out + package_keys = packages.keys(); + package_keys.sort(); + for package in package_keys: + output.write(packages[package]+'\n') + +######################################################################################### + +########## +# I'm doing it in python btw.. nothing against your monster +# SQL, but the python wins in terms of speed and readiblity +# bah +# you suck!!!!! +# sorry :( +# you are not!!! +# you mock my SQL!!!! +# you want have contest of skillz?????? +# all your skillz are belong to my sql!!!! +# yo momma are belong to my python!!!! +# yo momma was SQLin' like a pig last night! +########## + +# If something has gone from arch:all to arch:any or vice-versa, +# clean out the old versions here. The rest of jenna won't do this +# because it's lame. I have no idea. + +def clean_duplicate_packages(suite): + print "Cleaning duplicate packages for %s..." % (suite) + + suite_id = db_access.get_suite_id(suite) + q = projectB.query(""" +SELECT b1.package, + b1.id, b1.version, a1.arch_string, + b2.id, b2.version, a2.arch_string + FROM bin_associations ba1, binaries b1, architecture a1, + bin_associations ba2, binaries b2, architecture a2 + WHERE ba1.suite = ba2.suite AND ba1.suite = %s + AND ba1.bin = b1.id AND b1.architecture = a1.id + AND ba2.bin = b2.id AND b2.architecture = a2.id + AND b1.package = b2.package + AND (a1.id = a2.id OR a1.arch_string = 'all' OR a2.arch_string = 'all') + AND b1.id != b2.id + AND versioncmp(b1.version, b2.version) <= 0 +ORDER BY b1.package, b1.version, a1.arch_string;""" % (suite_id)) + + ql = q.getresult() + seen = {} + for i in ql: + (package, oldid, oldver, oldarch, newid, newver, newarch) = i + if not seen.has_key(oldid): + seen[oldid] = newid + print "Removing %s %s on %s (ifo %s/%s)" % (package, oldver, oldarch, newver, newarch) + projectB.query("DELETE FROM bin_associations WHERE suite = %s AND bin = %s" % (suite_id, oldid)) + else: + print "%s %s on %s also superceded by %s/%s" % (package, oldver, oldarch, newver, newarch) + +# If something has moved from one component to another we need to +# clean out the old versions here. The rest of jenna won't do this +# because it works on a per-component level for flexibility. + +def clean_suite (suite): + print "Cleaning out packages for %s..." % (suite) + + suite_id = db_access.get_suite_id(suite) + q = projectB.query(""" +SELECT b.id, b.package, a.arch_string, b.version, l.path, f.filename, c.name + FROM binaries b, bin_associations ba, files f, location l, architecture a, component c + WHERE ba.suite = %s AND ba.bin = b.id AND b.file = f.id AND + f.location = l.id AND l.component = c.id AND b.architecture = a.id +UNION +SELECT s.id, s.source, 'source', s.version, l.path, f.filename, c.name + FROM source s, src_associations sa, files f, location l, component c + WHERE sa.suite = %s AND sa.source = s.id AND s.file = f.id AND + f.location = l.id AND l.component = c.id;""" % (suite_id, suite_id)); + ql = q.getresult(); + d = {}; + for i in ql: + (id, package, architecture, version, path, filename, component) = i; + filename = path + filename; + if architecture == "source": + delete_table = "src_associations"; + delete_col = "source"; + else: + delete_table = "bin_associations"; + delete_col = "bin"; + key = "%s~%s" % (package, architecture); if os.path.exists(filename): - if packages.has_key(package): - if apt_pkg.VersionCompare(packages[package]["version"], version) == -1: - if not Cnf.Find("Suite::%s::Untouchable" % (suite)): - print "deleting %s (%s) in favour of newer version %s..." % (package, packages[package]["version"], version) - projectB.query("DELETE FROM bin_associations WHERE bin = %s AND suite = %d" % (packages[package]["id"], suite_id)) - else: - if Cnf.Find("Jenna::Options::Verbose"): - print "[untouchable] would delete %s (%s) in favour of newer version %s..." % (package, packages[package]["version"], version) - packages[package] = { "id": id, "version": version, "filename": filename } + if d.has_key(key): + (other_version, other_component, other_id) = d[key]; + if apt_pkg.VersionCompare(version, other_version) != 1: + (keep_version, keep_component) = (other_version, other_component) + (delete_id, delete_version, delete_component) = (id, version, component) else: - if not Cnf.Find("Suite::%s::Untouchable" % (suite)): - print "deleting %s (%s) in favour of newer version %s..." % (package, version, packages[package]["version"]) - projectB.query("DELETE FROM bin_associations WHERE bin = %s AND suite = %d" % (id, suite_id)) - else: - if Cnf.Find("Jenna::Options::Verbose"): - print "[untochable] would delete %s (%s) in favour of newer version %s..." % (package, version, packages[package]["version"]) + (keep_version, keep_component) = (version, component) + (delete_id, delete_version, delete_component) = (other_id, other_version, other_component) + d[key] = (version, component, id); + if not Cnf.Find("Suite::%s::Untouchable" % (suite)): + print "deleting %s on %s (%s [%s]) in favour of newer version %s [%s]..." \ + % (package, architecture, delete_version, delete_component, keep_version, keep_component); + projectB.query("DELETE FROM %s WHERE suite = %s AND %s = %s" % (delete_table, suite_id, delete_col, delete_id)); + else: + print "[untouchable] would delete %s on %s (%s [%s]) in favour of newer version %s [%s]..." \ + % (package, architecture, delete_version, delete_component, keep_version, keep_component); else: - packages[package] = { "id": id, "version": version, "filename": filename } + d[key] = (version, component, id); else: if not Cnf.Find("Suite::%s::Untouchable" % (suite)): sys.stderr.write("WARNING: deleting %s because it doesn't exist.\n" % (filename)); - projectB.query("DELETE FROM bin_associations WHERE bin = %s AND suite = %d" % (id, suite_id)) + projectB.query("DELETE FROM %s WHERE suite = %s AND %s = %s" % (delete_table, suite_id, delete_col, delete_id)); + else: + sys.stderr.write("WARNING: [untouchable] would delete %s because it doesn't exist.\n" % (filename)); - # Write the list of files out - package_keys = packages.keys(); - package_keys.sort(); - for package in package_keys: - output.write(packages[package]["filename"]+'\n') - - +######################################################################################### def main(): global Cnf, projectB; dislocated_files = {}; - projectB = pg.connect('projectb', 'localhost'); - apt_pkg.init(); Cnf = apt_pkg.newConfiguration(); @@ -157,6 +218,7 @@ def main(): apt_pkg.ParseCommandLine(Cnf,Arguments,sys.argv); + projectB = pg.connect(Cnf["DB::Name"], Cnf["DB::Host"], int(Cnf["DB::Port"])); db_access.init(Cnf, projectB); if Cnf["Jenna::Options::Suite"] == "": @@ -164,7 +226,12 @@ def main(): for suite in string.split(Cnf["Jenna::Options::Suite"]): suite = string.lower(suite); if suite == 'stable': + print "Undoing dislocation..." dislocated_files = claire.find_dislocated_stable(Cnf, projectB); + else: + dislocated_files = {}; + clean_suite(suite); + clean_duplicate_packages(suite) components = Cnf["Jenna::Options::Component"]; if not Cnf.has_key("Suite::%s::Components" % (suite)): components = "-"; @@ -189,12 +256,13 @@ def main(): output = utils.open_file("%s/%s_%s_binary-%s.list" % (Cnf["Dir::ListsDir"], suite, component, architecture), "w"); generate_bin_list(suite, component, architecture, output, "deb", dislocated_files); output.close(); - if component == "main": # FIXME: must be a cleaner way to say debian-installer is main only? + if component == "main" and (suite == "unstable" or suite == "testing"): # FIXME: must be a cleaner way to say debian-installer is main only? print "Processing dists/%s/%s/debian-installer/binary-%s..." % (suite,component, architecture); output = utils.open_file("%s/%s_%s_debian-installer_binary-%s.list" % (Cnf["Dir::ListsDir"], suite, component, architecture), "w"); generate_bin_list(suite, component, architecture, output, "udeb", dislocated_files); output.close(); +######################################################################################### + if __name__ == '__main__': main() -