X-Git-Url: https://git.decadent.org.uk/gitweb/?a=blobdiff_plain;f=katie;h=4858485042cc9b77fb76397060ee46e2d17e3bf8;hb=e4f2f33a24646716adedd63afa87a672cd6ed599;hp=7a51cd87fb0c64d9ec3eb116dade0220e956e938;hpb=155544a1f9a5bfb0a38a5d6b448cac8aaa362865;p=dak.git diff --git a/katie b/katie index 7a51cd87..48584850 100755 --- a/katie +++ b/katie @@ -2,7 +2,7 @@ # Installs Debian packaes # Copyright (C) 2000 James Troup -# $Id: katie,v 1.21 2001-01-22 22:32:47 troup Exp $ +# $Id: katie,v 1.29 2001-02-09 22:15:45 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,8 +39,6 @@ import utils, db_access ############################################################################### re_isanum = re.compile (r'^\d+$'); -re_isadeb = re.compile (r'.*\.u?deb$'); -re_issource = re.compile (r'(.+)_(.+?)\.(orig\.tar\.gz|diff\.gz|tar\.gz|dsc)'); re_changes = re.compile (r'changes$'); re_default_answer = re.compile(r"\[(.*)\]"); re_fdnic = re.compile("\n\n"); @@ -91,13 +89,14 @@ legacy_source_untouchable = {}; def usage (exit_code): print """Usage: dinstall [OPTION]... [CHANGES]... -a, --automatic automatic run - -d, --debug=VALUE debug - -k, --ack-new acknowledge new packages + -D, --debug=VALUE turn on debugging + -h, --help show this help and exit. + -k, --ack-new acknowledge new packages !! for cron.daily only !! -m, --manual-reject=MSG manual reject with `msg' -n, --no-action don't do anything -p, --no-lock don't check lockfile !! for cron.daily only !! - -r, --no-version-check override version check - -u, --distribution=DIST override distribution to `dist'""" + -u, --distribution=DIST override distribution to `dist' + -v, --version display the version number and exit""" sys.exit(exit_code) def check_signature (filename): @@ -158,18 +157,20 @@ def in_override_p (package, component, suite, binary_type, file): def check_changes(filename): global reject_message, changes, files - # Parse the .changes field into a dictionary [FIXME - need to trap errors, pass on to reject_message etc.] + # Default in case we bail out + changes["maintainer822"] = Cnf["Dinstall::MyEmailAddress"]; + + # Parse the .changes field into a dictionary try: - changes = utils.parse_changes(filename) + changes = utils.parse_changes(filename, 0) except utils.cant_open_exc: reject_message = "Rejected: can't read changes file '%s'.\n" % (filename) return 0; except utils.changes_parse_error_exc, line: reject_message = "Rejected: error parsing changes file '%s', can't grok: %s.\n" % (filename, line) - changes["maintainer822"] = Cnf["Dinstall::MyEmailAddress"]; return 0; - # Parse the Files field from the .changes into another dictionary [FIXME need to trap errors as above] + # Parse the Files field from the .changes into another dictionary try: files = utils.build_file_list(changes, ""); except utils.changes_parse_error_exc, line: @@ -178,12 +179,9 @@ def check_changes(filename): # Check for mandatory fields for i in ("source", "binary", "architecture", "version", "distribution","maintainer", "files"): if not changes.has_key(i): - reject_message = "Rejected: Missing field `%s' in changes file." % (i) + reject_message = "Rejected: Missing field `%s' in changes file.\n" % (i) return 0 # Avoid errors during later tests - # Fix the Maintainer: field to be RFC822 compatible - (changes["maintainer822"], changes["maintainername"], changes["maintaineremail"]) = utils.fix_maintainer (changes["maintainer"]) - # Override the Distribution: field if appropriate if Cnf["Dinstall::Options::Override-Distribution"] != "": reject_message = reject_message + "Warning: Distribution was overriden from %s to %s.\n" % (changes["distribution"], Cnf["Dinstall::Options::Override-Distribution"]) @@ -198,6 +196,17 @@ def check_changes(filename): for j in string.split(o): changes[i][j] = 1 + # Fix the Maintainer: field to be RFC822 compatible + (changes["maintainer822"], changes["maintainername"], changes["maintaineremail"]) = utils.fix_maintainer (changes["maintainer"]) + + # Fix the Changed-By: field to be RFC822 compatible; if it exists. + (changes["changedby822"], changes["changedbyname"], changes["changedbyemail"]) = utils.fix_maintainer(changes.get("changed-by","")); + + # For source uploads the Changed-By field wins; otherwise Maintainer wins. + if changes["architecture"].has_key("source"): + changes["uploader822"] = "To: %s\nCc: %s" % (changes["changedby822"], changes["maintainer822"]); + # changes["uploadername"], changes["uploaderemail"]) = (changes["changedby822"], changes["changedbyname"], changes["changedbyemail"]); + # Ensure all the values in Closes: are numbers if changes.has_key("closes"): for i in changes["closes"].keys(): @@ -221,6 +230,10 @@ def check_changes(filename): if not Cnf.has_key("Suite::%s" % (i)): reject_message = reject_message + "Rejected: Unknown distribution `%s'.\n" % (i) + # Ensure there _is_ a target distribution + if changes["distribution"].keys() == []: + reject_message = reject_message + "Rejected: huh? Distribution field is empty in changes file.\n"; + # Map unreleased arches from stable to unstable if changes["distribution"].has_key("stable"): for i in changes["architecture"].keys(): @@ -283,12 +296,16 @@ def check_files(): files[file]["byhand"] = 1; files[file]["type"] = "byhand"; # Checks for a binary package... - elif re_isadeb.match(file) != None: + elif utils.re_isadeb.match(file) != None: + files[file]["type"] = "deb"; + # Extract package information using dpkg-deb try: control = apt_pkg.ParseSection(apt_inst.debExtractControl(utils.open_file(file,"r"))) except: reject_message = reject_message + "Rejected: %s: debExtractControl() raised %s.\n" % (file, sys.exc_type); + # Can't continue, none of the checks on control would work. + continue; # Check for mandatory fields if control.Find("Package") == None: @@ -327,14 +344,13 @@ def check_files(): files[file]["dbtype"] = "deb"; else: reject_message = reject_message + "Rejected: %s is neither a .deb or a .udeb.\n " % (file); - files[file]["type"] = "deb"; files[file]["fullname"] = "%s_%s_%s.deb" % (control.Find("Package", ""), epochless_version, control.Find("Architecture", "")) files[file]["source"] = control.Find("Source", ""); if files[file]["source"] == "": files[file]["source"] = files[file]["package"]; # Checks for a source package... else: - m = re_issource.match(file) + m = utils.re_issource.match(file) if m != None: files[file]["package"] = m.group(1) files[file]["version"] = m.group(2) @@ -390,11 +406,7 @@ def check_files(): files[file]["oldfiles"][suite] = oldfile # Check versions [NB: per-suite only; no cross-suite checking done (yet)] if apt_pkg.VersionCompare(files[file]["version"], oldfile["version"]) != 1: - if Cnf["Dinstall::Options::No-Version-Check"]: - reject_message = reject_message + "Overriden rejection" - else: - reject_message = reject_message + "Rejected" - reject_message = reject_message + ": %s Old version `%s' >= new version `%s'.\n" % (file, oldfile["version"], files[file]["version"]) + reject_message = reject_message + "Rejected: %s Old version `%s' >= new version `%s'.\n" % (file, oldfile["version"], files[file]["version"]) # Check for existing copies of the file if not changes.has_key("stable upload"): q = projectB.query("SELECT b.id FROM binaries b, architecture a WHERE b.package = '%s' AND b.version = '%s' AND a.arch_string = '%s' AND a.id = b.architecture" % (files[file]["package"], files[file]["version"], files[file]["architecture"])) @@ -415,6 +427,10 @@ def check_files(): if component_id == -1: reject_message = reject_message + "Rejected: file '%s' has unknown component '%s'.\n" % (file, component); continue; + + # Validate the priority + if string.find(files[file]["priority"],'/') != -1: + reject_message = reject_message + "Rejected: file '%s' has invalid priority '%s' [contains '/'].\n" % (file, files[file]["priority"]); # Check the md5sum & size against existing files (if any) location = Cnf["Dir::PoolDir"]; @@ -446,13 +462,16 @@ def check_dsc (): for file in files.keys(): if files[file]["type"] == "dsc": try: - dsc = utils.parse_changes(file) + dsc = utils.parse_changes(file, 1) except utils.cant_open_exc: reject_message = reject_message + "Rejected: can't read changes file '%s'.\n" % (filename) return 0; except utils.changes_parse_error_exc, line: reject_message = reject_message + "Rejected: error parsing changes file '%s', can't grok: %s.\n" % (filename, line) return 0; + except utils.invalid_dsc_format_exc, line: + reject_message = reject_message + "Rejected: syntax error in .dsc file '%s', line %s.\n" % (filename, line) + return 0; try: dsc_files = utils.build_file_list(dsc, 1) except utils.no_files_exc: @@ -490,7 +509,6 @@ def check_dsc (): q = projectB.query("SELECT l.path, f.filename, l.type, f.id FROM files f, location l WHERE (f.filename ~ '/%s$' OR f.filename = '%s') AND l.id = f.location" % (utils.regex_safe(dsc_file), dsc_file)); ql = q.getresult(); - if ql != []: # Unfortunately, we make get more than one match # here if, for example, the package was in potato @@ -538,7 +556,7 @@ def check_dsc (): reject_message = reject_message + "Rejected: %s refers to %s, but I can't find it in Incoming or in the pool.\n" % (file, dsc_file); continue; else: - reject_message = reject_message + "Rejected: %s refers to %s, but I can't find it in Incoming." % (file, dsc_file); + reject_message = reject_message + "Rejected: %s refers to %s, but I can't find it in Incoming.\n" % (file, dsc_file); continue; if actual_md5 != dsc_files[dsc_file]["md5sum"]: reject_message = reject_message + "Rejected: md5sum for %s doesn't match %s.\n" % (found, file); @@ -595,16 +613,18 @@ def check_override (): summary = "" for file in files.keys(): - if not files[file].has_key("new") and (files[file]["type"] == "dsc" or files[file]["type"] == "deb"): + if not files[file].has_key("new") and files[file]["type"] == "deb": section = files[file]["section"]; override_section = files[file]["override section"]; if section != override_section and section != "-": + # Ignore this; it's a common mistake and not worth whining about + if string.lower(section) == "non-us/main" and string.lower(override_section) == "non-us": + continue; summary = summary + "%s: section is overridden from %s to %s.\n" % (file, section, override_section); - if files[file]["type"] == "deb": # don't do priority for source - priority = files[file]["priority"]; - override_priority = files[file]["override priority"]; - if priority != override_priority and priority != "-": - summary = summary + "%s: priority is overridden from %s to %s.\n" % (file, priority, override_priority); + priority = files[file]["priority"]; + override_priority = files[file]["override priority"]; + if priority != override_priority and priority != "-": + summary = summary + "%s: priority is overridden from %s to %s.\n" % (file, priority, override_priority); if summary == "": return; @@ -924,7 +944,7 @@ def stable_install (changes_filename, summary, short_summary): for file in files.keys(): if files[file]["type"] == "deb": new_changelog.write("stable/%s/binary-%s/%s\n" % (files[file]["component"], files[file]["architecture"], file)); - elif re_issource.match(file) != None: + elif utils.re_issource.match(file) != None: new_changelog.write("stable/%s/source/%s\n" % (files[file]["component"], file)); else: new_changelog.write("%s\n" % (file)); @@ -967,15 +987,15 @@ def reject (changes_filename, manual_reject_mail_filename): # Move the .changes files and it's contents into REJECT/ (if we can; errors are ignored) try: utils.move (changes_filename, "%s/REJECT/%s" % (Cnf["Dir::IncomingDir"], base_changes_filename)); - except utils.cant_overwrite_exc: - sys.stderr.write("W: couldn't overwrite existing file '%s/REJECT/%s" % (Cnf["Dir::IncomingDir"], base_changes_filename)); + except: + sys.stderr.write("W: couldn't reject changes file '%s' [Got %s]" % (base_changes_filename, sys.exc_type)); pass; for file in files.keys(): if os.path.exists(file): try: utils.move (file, "%s/REJECT/%s" % (Cnf["Dir::IncomingDir"], file)); - except utils.cant_overwrite_exc: - sys.stderr.write("W: couldn't overwrite existing file '%s/REJECT/%s" % (Cnf["Dir::IncomingDir"], file)); + except: + sys.stderr.write("W: couldn't reject file '%s' [Got %s].\n" % (file, sys.exc_type)); pass; # If this is not a manual rejection generate the .reason file and rejection mail message @@ -1145,7 +1165,7 @@ administrators by mailing ftpmaster@debian.org) control_message = "" for bug in bugs: summary = summary + "%s " % (bug) - control_message = control_message + "severity %s fixed\n" % (bug) + control_message = control_message + "tag %s + fixed\n" % (bug) if action and control_message != "": mail_message = """Return-Path: %s From: %s @@ -1177,17 +1197,18 @@ non-maintainer upload. The .changes file follows. # into the .changes structure and reprocess the .changes file. def process_it (changes_file): - global reprocess, orig_tar_id, changes, dsc, dsc_files, files; + global reprocess, orig_tar_id, changes, dsc, dsc_files, files, reject_message; - reprocess = 1; - orig_tar_id = None; # Reset some globals + reprocess = 1; changes = {}; dsc = {}; dsc_files = {}; files = {}; orig_tar_id = None; legacy_source_untouchable = {}; + reject_message = ""; + orig_tar_id = None; # Absolutize the filename to avoid the requirement of being in the # same directory as the .changes file. @@ -1214,7 +1235,7 @@ def process_it (changes_file): ############################################################################### def main(): - global Cnf, projectB, reject_message, install_bytes, new_ack_old + global Cnf, projectB, install_bytes, new_ack_old apt_pkg.init(); @@ -1228,7 +1249,6 @@ def main(): ('m',"manual-reject","Dinstall::Options::Manual-Reject", "HasArg"), ('n',"no-action","Dinstall::Options::No-Action"), ('p',"no-lock", "Dinstall::Options::No-Lock"), - ('r',"no-version-check", "Dinstall::Options::No-Version-Check"), ('s',"no-mail", "Dinstall::Options::No-Mail"), ('u',"override-distribution", "Dinstall::Options::Override-Distribution", "HasArg"), ('v',"version","Dinstall::Options::Version")]; @@ -1275,7 +1295,6 @@ def main(): # Process the changes files for changes_file in changes_files: - reject_message = "" print "\n" + changes_file; process_it (changes_file);