X-Git-Url: https://git.decadent.org.uk/gitweb/?p=dak.git;a=blobdiff_plain;f=dak%2Fnew_security_install.py;h=7d4603d5811ebcc21b3dc5b24e9f3a4cb77ba5eb;hp=b1a47dba8f2527bbe733afea5f014f064acf4634;hb=17c5cab4eb8d5181ec7a81267a4e2e6b43c0fc65;hpb=74c5a1256401a709d74c496b972cc0bd38decaa8 diff --git a/dak/new_security_install.py b/dak/new_security_install.py index b1a47dba..7d4603d5 100755 --- a/dak/new_security_install.py +++ b/dak/new_security_install.py @@ -1,426 +1,61 @@ #!/usr/bin/env python -""" Wrapper for Debian Security team """ -# Copyright (C) 2006 Anthony Towns +""" +Do whatever is needed to get a security upload released + +@contact: Debian FTP Master +@copyright: 2010 Joerg Jaspert +@license: GNU General Public License version 2 or later +""" # 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. +# 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 +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +################################################################################ + ################################################################################ -import apt_pkg, os, sys, pwd, time, commands +import os +import sys +import time +import apt_pkg +import commands from daklib import queue -from daklib import logging +from daklib import daklog from daklib import utils -from daklib import database +from daklib.dbconn import * from daklib.regexes import re_taint_free +from daklib.config import Config -Cnf = None Options = None -Upload = None Logger = None - -advisory = None +Queue = None changes = [] -srcverarches = {} - -def init(): - global Cnf, Upload, Options, Logger - - Cnf = utils.get_conf() - Cnf["Dinstall::Options::No-Mail"] = "y" - Arguments = [('h', "help", "Security-Install::Options::Help"), - ('a', "automatic", "Security-Install::Options::Automatic"), - ('n', "no-action", "Security-Install::Options::No-Action"), - ('s', "sudo", "Security-Install::Options::Sudo"), - (' ', "no-upload", "Security-Install::Options::No-Upload"), - ('u', "fg-upload", "Security-Install::Options::Foreground-Upload"), - (' ', "drop-advisory", "Security-Install::Options::Drop-Advisory"), - ('A', "approve", "Security-Install::Options::Approve"), - ('R', "reject", "Security-Install::Options::Reject"), - ('D', "disembargo", "Security-Install::Options::Disembargo") ] - - for i in Arguments: - Cnf[i[2]] = "" - - arguments = apt_pkg.ParseCommandLine(Cnf, Arguments, sys.argv) - - Options = Cnf.SubTree("Security-Install::Options") - - whoami = os.getuid() - whoamifull = pwd.getpwuid(whoami) - username = whoamifull[0] - if username != "dak": - print "Non-dak user: %s" % username - Options["Sudo"] = "y" - - if Options["Help"]: - print "help yourself" - sys.exit(0) - - if len(arguments) == 0: - utils.fubar("Process what?") - Upload = queue.Upload(Cnf) - if Options["No-Action"]: - Options["Sudo"] = "" - if not Options["Sudo"] and not Options["No-Action"]: - Logger = Upload.Logger = logging.Logger(Cnf, "new-security-install") +def usage(): + print """Usage: dak security-install [OPTIONS] changesfiles +Do whatever there is to do for a security release - return arguments + -h, --help show this help and exit + -n, --no-action don't commit changes + -s, --sudo dont bother, used internally -def quit(): - if Logger: - Logger.close() - sys.exit(0) +""" + sys.exit() -def load_args(arguments): - global advisory, changes - - adv_ids = {} - if not arguments[0].endswith(".changes"): - adv_ids [arguments[0]] = 1 - arguments = arguments[1:] - - null_adv_changes = [] - - changesfiles = {} - for a in arguments: - if "/" in a: - utils.fubar("can only deal with files in the current directory") - if not a.endswith(".changes"): - utils.fubar("not a .changes file: %s" % (a)) - Upload.init_vars() - Upload.pkg.changes_file = a - Upload.update_vars() - if "adv id" in Upload.pkg.changes: - changesfiles[a] = 1 - adv_ids[Upload.pkg.changes["adv id"]] = 1 - else: - null_adv_changes.append(a) - - adv_ids = adv_ids.keys() - if len(adv_ids) > 1: - utils.fubar("multiple advisories selected: %s" % (", ".join(adv_ids))) - if adv_ids == []: - advisory = None - else: - advisory = adv_ids[0] - - changes = changesfiles.keys() - return null_adv_changes - -def load_adv_changes(): - global srcverarches, changes - - for c in os.listdir("."): - if not c.endswith(".changes"): continue - Upload.init_vars() - Upload.pkg.changes_file = c - Upload.update_vars() - if "adv id" not in Upload.pkg.changes: - continue - if Upload.pkg.changes["adv id"] != advisory: - continue - - if c not in changes: changes.append(c) - srcver = "%s %s" % (Upload.pkg.changes["source"], - Upload.pkg.changes["version"]) - srcverarches.setdefault(srcver, {}) - for arch in Upload.pkg.changes["architecture"].keys(): - srcverarches[srcver][arch] = 1 - -def advisory_info(): - if advisory != None: - print "Advisory: %s" % (advisory) - print "Changes:" - for c in changes: - print " %s" % (c) - - print "Packages:" - svs = srcverarches.keys() - svs.sort() - for sv in svs: - as = srcverarches[sv].keys() - as.sort() - print " %s (%s)" % (sv, ", ".join(as)) - -def prompt(opts, default): - p = "" - v = {} - for o in opts: - v[o[0].upper()] = o - if o[0] == default: - p += ", [%s]%s" % (o[0], o[1:]) - else: - p += ", " + o - p = p[2:] + "? " - a = None - - if Options["Automatic"]: - a = default - - while a not in v: - a = utils.our_raw_input(p) + default - a = a[:1].upper() - - return v[a] - -def add_changes(extras): - for c in extras: - changes.append(c) - Upload.init_vars() - Upload.pkg.changes_file = c - Upload.update_vars() - srcver = "%s %s" % (Upload.pkg.changes["source"], Upload.pkg.changes["version"]) - srcverarches.setdefault(srcver, {}) - for arch in Upload.pkg.changes["architecture"].keys(): - srcverarches[srcver][arch] = 1 - Upload.pkg.changes["adv id"] = advisory - Upload.dump_vars(os.getcwd()) - -def yes_no(prompt): - if Options["Automatic"]: return True - while 1: - answer = utils.our_raw_input(prompt + " ").lower() - if answer in "yn": - return answer == "y" - print "Invalid answer; please try again." - -def do_upload(): - if Options["No-Upload"]: - print "Not uploading as requested" - elif Options["Foreground-Upload"]: - actually_upload(changes) - else: - child = os.fork() - if child == 0: - actually_upload(changes) - os._exit(0) - print "Uploading in the background" - -def actually_upload(changes_files): - file_list = "" - suites = {} - component_mapping = {} - for component in Cnf.SubTree("Security-Install::ComponentMappings").List(): - component_mapping[component] = Cnf["Security-Install::ComponentMappings::%s" % (component)] - uploads = {}; # uploads[uri] = file_list - changesfiles = {}; # changesfiles[uri] = file_list - package_list = {} # package_list[source_name][version] - changes_files.sort(utils.changes_compare) - for changes_file in changes_files: - changes_file = utils.validate_changes_file_arg(changes_file) - # Reset variables - components = {} - upload_uris = {} - file_list = [] - Upload.init_vars() - # Parse the .dak file for the .changes file - Upload.pkg.changes_file = changes_file - Upload.update_vars() - files = Upload.pkg.files - changes = Upload.pkg.changes - dsc = Upload.pkg.dsc - # Build the file list for this .changes file - for file in files.keys(): - poolname = os.path.join(Cnf["Dir::Root"], Cnf["Dir::PoolRoot"], - utils.poolify(changes["source"], files[file]["component"]), - file) - file_list.append(poolname) - orig_component = files[file].get("original component", files[file]["component"]) - components[orig_component] = "" - # Determine the upload uri for this .changes file - for component in components.keys(): - upload_uri = component_mapping.get(component) - if upload_uri: - upload_uris[upload_uri] = "" - num_upload_uris = len(upload_uris.keys()) - if num_upload_uris == 0: - utils.fubar("%s: No valid upload URI found from components (%s)." - % (changes_file, ", ".join(components.keys()))) - elif num_upload_uris > 1: - utils.fubar("%s: more than one upload URI (%s) from components (%s)." - % (changes_file, ", ".join(upload_uris.keys()), - ", ".join(components.keys()))) - upload_uri = upload_uris.keys()[0] - # Update the file list for the upload uri - if not uploads.has_key(upload_uri): - uploads[upload_uri] = [] - uploads[upload_uri].extend(file_list) - # Update the changes list for the upload uri - if not changesfiles.has_key(upload_uri): - changesfiles[upload_uri] = [] - changesfiles[upload_uri].append(changes_file) - # Remember the suites and source name/version - for suite in changes["distribution"].keys(): - suites[suite] = "" - # Remember the source name and version - if changes["architecture"].has_key("source") and \ - changes["distribution"].has_key("testing"): - if not package_list.has_key(dsc["source"]): - package_list[dsc["source"]] = {} - package_list[dsc["source"]][dsc["version"]] = "" - - for uri in uploads.keys(): - uploads[uri].extend(changesfiles[uri]) - (host, path) = uri.split(":") - # file_list = " ".join(uploads[uri]) - print "Moving files to UploadQueue" - for filename in uploads[uri]: - utils.copy(filename, Cnf["Dir::Upload"]) - # .changes files have already been moved to queue/done by p-a - if not filename.endswith('.changes'): - remove_from_buildd(suites, filename) - #spawn("lftp -c 'open %s; cd %s; put %s'" % (host, path, file_list)) - - if not Options["No-Action"]: - filename = "%s/testing-processed" % (Cnf["Dir::Log"]) - file = utils.open_file(filename, 'a') - for source in package_list.keys(): - for version in package_list[source].keys(): - file.write(" ".join([source, version])+'\n') - file.close() - -def remove_from_buildd(suites, filename): - """Check the buildd dir for each suite and remove the file if needed""" - builddbase = Cnf["Dir::QueueBuild"] - filebase = os.path.basename(filename) - for s in suites: - try: - os.unlink(os.path.join(builddbase, s, filebase)) - except OSError, e: - utils.warn("Problem removing %s from buildd queue %s [%s]" % (filebase, s, str(e))) - - -def generate_advisory(template): - global changes, advisory - - adv_packages = [] - updated_pkgs = {}; # updated_pkgs[distro][arch][file] = {path,md5,size} - - for arg in changes: - arg = utils.validate_changes_file_arg(arg) - Upload.pkg.changes_file = arg - Upload.init_vars() - Upload.update_vars() - - src = Upload.pkg.changes["source"] - src_ver = "%s (%s)" % (src, Upload.pkg.changes["version"]) - if src_ver not in adv_packages: - adv_packages.append(src_ver) - - suites = Upload.pkg.changes["distribution"].keys() - for suite in suites: - if not updated_pkgs.has_key(suite): - updated_pkgs[suite] = {} - - files = Upload.pkg.files - for file in files.keys(): - arch = files[file]["architecture"] - md5 = files[file]["md5sum"] - size = files[file]["size"] - poolname = Cnf["Dir::PoolRoot"] + \ - utils.poolify(src, files[file]["component"]) - if arch == "source" and file.endswith(".dsc"): - dscpoolname = poolname - for suite in suites: - if not updated_pkgs[suite].has_key(arch): - updated_pkgs[suite][arch] = {} - updated_pkgs[suite][arch][file] = { - "md5": md5, "size": size, "poolname": poolname } - - dsc_files = Upload.pkg.dsc_files - for file in dsc_files.keys(): - arch = "source" - if not dsc_files[file].has_key("files id"): - continue - - # otherwise, it's already in the pool and needs to be - # listed specially - md5 = dsc_files[file]["md5sum"] - size = dsc_files[file]["size"] - for suite in suites: - if not updated_pkgs[suite].has_key(arch): - updated_pkgs[suite][arch] = {} - updated_pkgs[suite][arch][file] = { - "md5": md5, "size": size, "poolname": dscpoolname } - - if os.environ.has_key("SUDO_UID"): - whoami = long(os.environ["SUDO_UID"]) - else: - whoami = os.getuid() - whoamifull = pwd.getpwuid(whoami) - username = whoamifull[4].split(",")[0] - - Subst = { - "__ADVISORY__": advisory, - "__WHOAMI__": username, - "__DATE__": time.strftime("%B %d, %Y", time.gmtime(time.time())), - "__PACKAGE__": ", ".join(adv_packages), - "__DAK_ADDRESS__": Cnf["Dinstall::MyEmailAddress"] - } - - if Cnf.has_key("Dinstall::Bcc"): - Subst["__BCC__"] = "Bcc: %s" % (Cnf["Dinstall::Bcc"]) - - adv = "" - archive = Cnf["Archive::%s::PrimaryMirror" % (utils.where_am_i())] - for suite in updated_pkgs.keys(): - ver = Cnf["Suite::%s::Version" % suite] - if ver != "": ver += " " - suite_header = "%s %s(%s)" % (Cnf["Dinstall::MyDistribution"], - ver, suite) - adv += "%s\n%s\n\n" % (suite_header, "-"*len(suite_header)) - - arches = Cnf.ValueList("Suite::%s::Architectures" % suite) - if "source" in arches: - arches.remove("source") - if "all" in arches: - arches.remove("all") - arches.sort() - - adv += "%s updates are available for %s.\n\n" % ( - suite.capitalize(), utils.join_with_commas_and(arches)) - - for a in ["source", "all"] + arches: - if not updated_pkgs[suite].has_key(a): - continue - - if a == "source": - adv += "Source archives:\n\n" - elif a == "all": - adv += "Architecture independent packages:\n\n" - else: - adv += "%s architecture (%s)\n\n" % (a, - Cnf["Architectures::%s" % a]) - - for file in updated_pkgs[suite][a].keys(): - adv += " http://%s/%s%s\n" % ( - archive, updated_pkgs[suite][a][file]["poolname"], file) - adv += " Size/MD5 checksum: %8s %s\n" % ( - updated_pkgs[suite][a][file]["size"], - updated_pkgs[suite][a][file]["md5"]) - adv += "\n" - adv = adv.rstrip() - - Subst["__ADVISORY_TEXT__"] = adv - - adv = utils.TemplateSubst(Subst, template) - return adv def spawn(command): if not re_taint_free.match(command): @@ -433,7 +68,6 @@ def spawn(command): if (result != 0): utils.fubar("Invocation of '%s' failed:\n%s\n" % (command, output), result) - ##################### ! ! ! N O T E ! ! ! ##################### # # These functions will be reinvoked by semi-priveleged users, be careful not @@ -443,10 +77,8 @@ def spawn(command): def sudo(arg, fn, exit): if Options["Sudo"]: - if advisory == None: - utils.fubar("Must set advisory name") os.spawnl(os.P_WAIT, "/usr/bin/sudo", "/usr/bin/sudo", "-u", "dak", "-H", - "/usr/local/bin/dak", "new-security-install", "-"+arg, "--", advisory) + "/usr/local/bin/dak", "new-security-install", "-"+arg) else: fn() if exit: @@ -454,221 +86,110 @@ def sudo(arg, fn, exit): def do_Approve(): sudo("A", _do_Approve, True) def _do_Approve(): - # 1. dump advisory in drafts - draft = "/org/security.debian.org/advisories/drafts/%s" % (advisory) - print "Advisory in %s" % (draft) - if not Options["No-Action"]: - adv_file = "./advisory.%s" % (advisory) - if not os.path.exists(adv_file): - adv_file = Cnf["Dir::Templates"]+"/security-install.advisory" - adv_fd = os.open(draft, os.O_RDWR|os.O_CREAT|os.O_EXCL, 0664) - os.write(adv_fd, generate_advisory(adv_file)) - os.close(adv_fd) - adv_fd = None - - # 2. run dak process-accepted on changes - print "Accepting packages..." - spawn("dak process-accepted -pa %s" % (" ".join(changes))) - - # 3. run dak make-suite-file-list / apt-ftparchve / dak generate-releases - print "Updating file lists for apt-ftparchive..." - spawn("dak make-suite-file-list") - print "Updating Packages and Sources files..." - spawn("apt-ftparchive generate %s" % (utils.which_apt_conf_file())) - print "Updating Release files..." - spawn("dak generate-releases") - print "Triggering security mirrors..." - spawn("sudo -u archvsync -H /home/archvsync/signal_security") - - # 4. chdir to done - do upload - if not Options["No-Action"]: - os.chdir(Cnf["Dir::Queue::Done"]) - do_upload() - -def do_Disembargo(): sudo("D", _do_Disembargo, True) -def _do_Disembargo(): - if os.getcwd() != Cnf["Dir::Queue::Embargoed"].rstrip("/"): - utils.fubar("Can only disembargo from %s" % Cnf["Dir::Queue::Embargoed"]) - - dest = Cnf["Dir::Queue::Unembargoed"] - emb_q = database.get_or_set_queue_id("embargoed") - une_q = database.get_or_set_queue_id("unembargoed") - - for c in changes: - print "Disembargoing %s" % (c) - - Upload.init_vars() - Upload.pkg.changes_file = c - Upload.update_vars() - - if "source" in Upload.pkg.changes["architecture"].keys(): - print "Adding %s %s to disembargo table" % (Upload.pkg.changes["source"], Upload.pkg.changes["version"]) - Upload.projectB.query("INSERT INTO disembargo (package, version) VALUES ('%s', '%s')" % (Upload.pkg.changes["source"], Upload.pkg.changes["version"])) - - files = {} - for suite in Upload.pkg.changes["distribution"].keys(): - if suite not in Cnf.ValueList("Dinstall::QueueBuildSuites"): - continue - dest_dir = Cnf["Dir::QueueBuild"] - if Cnf.FindB("Dinstall::SecurityQueueBuild"): - dest_dir = os.path.join(dest_dir, suite) - for file in Upload.pkg.files.keys(): - files[os.path.join(dest_dir, file)] = 1 - - files = files.keys() - Upload.projectB.query("BEGIN WORK") - for f in files: - Upload.projectB.query("UPDATE queue_build SET queue = %s WHERE filename = '%s' AND queue = %s" % (une_q, f, emb_q)) - Upload.projectB.query("COMMIT WORK") - - for file in Upload.pkg.files.keys(): - utils.copy(file, os.path.join(dest, file)) - os.unlink(file) - - for c in changes: - utils.copy(c, os.path.join(dest, c)) - os.unlink(c) - k = c[:-8] + ".dak" - utils.copy(k, os.path.join(dest, k)) - os.unlink(k) - -def do_Reject(): sudo("R", _do_Reject, True) -def _do_Reject(): - global changes - for c in changes: - print "Rejecting %s..." % (c) - Upload.init_vars() - Upload.pkg.changes_file = c - Upload.update_vars() - files = {} - for suite in Upload.pkg.changes["distribution"].keys(): - if suite not in Cnf.ValueList("Dinstall::QueueBuildSuites"): - continue - dest_dir = Cnf["Dir::QueueBuild"] - if Cnf.FindB("Dinstall::SecurityQueueBuild"): - dest_dir = os.path.join(dest_dir, suite) - for file in Upload.pkg.files.keys(): - files[os.path.join(dest_dir, file)] = 1 - - files = files.keys() - - aborted = Upload.do_reject() - if not aborted: - os.unlink(c[:-8]+".dak") - for f in files: - Upload.projectB.query( - "DELETE FROM queue_build WHERE filename = '%s'" % (f)) - os.unlink(f) - - print "Updating buildd information..." - spawn("/org/security.debian.org/dak/config/debian-security/cron.buildd") - - adv_file = "./advisory.%s" % (advisory) - if os.path.exists(adv_file): - os.unlink(adv_file) - -def do_DropAdvisory(): - for c in changes: - Upload.init_vars() - Upload.pkg.changes_file = c - Upload.update_vars() - del Upload.pkg.changes["adv id"] - Upload.dump_vars(os.getcwd()) - quit() - -def do_Edit(): - adv_file = "./advisory.%s" % (advisory) - if not os.path.exists(adv_file): - utils.copy(Cnf["Dir::Templates"]+"/security-install.advisory", adv_file) - editor = os.environ.get("EDITOR", "vi") - result = os.system("%s %s" % (editor, adv_file)) - if result != 0: - utils.fubar("%s invocation failed for %s." % (editor, adv_file)) - -def do_Show(): - adv_file = "./advisory.%s" % (advisory) - if not os.path.exists(adv_file): - adv_file = Cnf["Dir::Templates"]+"/security-install.advisory" - print "====\n%s\n====" % (generate_advisory(adv_file)) - -def do_Quit(): - quit() + print "Locking unchecked" + lockfile='/srv/security-master.debian.org/lock/unchecked.lock' + spawn("lockfile -r42 {0}".format(lockfile)) + + try: + # 1. Install accepted packages + print "Installing accepted packages into security archive" + for queue in ("embargoed",): + spawn("dak process-policy {0}".format(queue)) + + # 3. Run all the steps that are needed to publish the changed archive + print "Domination" + spawn("dak dominate") + print "Updating Packages and Sources files... This may take a while, be patient" + spawn("/srv/security-master.debian.org/dak/config/debian-security/map.sh") + spawn("dak generate-packages-sources2 -a security") + print "Updating Release files..." + spawn("dak generate-releases -a security") + print "Triggering security mirrors... (this may take a while)" + spawn("/srv/security-master.debian.org/dak/config/debian-security/make-mirror.sh") + spawn("sudo -u archvsync -H /home/archvsync/signal_security") + print "Triggering metadata export for packages.d.o and other consumers" + spawn("/srv/security-master.debian.org/dak/config/debian-security/export.sh") + finally: + os.unlink(lockfile) + print "Lock released." + +######################################################################## +######################################################################## def main(): - global changes - - args = init() - extras = load_args(args) - if advisory: - load_adv_changes() - if extras: - if not advisory: - changes = extras - else: - if srcverarches == {}: - if not yes_no("Create new advisory %s?" % (advisory)): - print "Not doing anything, then" - quit() - else: - advisory_info() - doextras = [] - for c in extras: - if yes_no("Add %s to %s?" % (c, advisory)): - doextras.append(c) - extras = doextras - add_changes(extras) - - if not advisory: - utils.fubar("Must specify an advisory id") - - if not changes: - utils.fubar("No changes specified") + global Options, Logger, Queue, changes + cnf = Config() + + Arguments = [('h', "Help", "Security::Options::Help"), + ('n', "No-Action", "Security::Options::No-Action"), + ('c', 'Changesfile', "Security::Options::Changesfile"), + ('s', "Sudo", "Security::Options::Sudo"), + ('A', "Approve", "Security::Options::Approve") + ] + + for i in ["Help", "No-Action", "Changesfile", "Sudo", "Approve"]: + if not cnf.has_key("Security::Options::%s" % (i)): + cnf["Security::Options::%s" % (i)] = "" + changes_files = apt_pkg.parse_commandline(cnf.Cnf, Arguments, sys.argv) + + Options = cnf.subtree("Security::Options") + if Options['Help']: + usage() + + changesfiles={} + for a in changes_files: + if not a.endswith(".changes"): + utils.fubar("not a .changes file: %s" % (a)) + changesfiles[a]=1 + changes = changesfiles.keys() + + username = utils.getusername() + if username != "dak": + print "Non-dak user: %s" % username + Options["Sudo"] = "y" + + if Options["No-Action"]: + Options["Sudo"] = "" + + if not Options["Sudo"] and not Options["No-Action"]: + Logger = daklog.Logger("security-install") + + session = DBConn().session() + + # If we call ourselve to approve, we do just that and exit if Options["Approve"]: - advisory_info() do_Approve() - elif Options["Reject"]: - advisory_info() - do_Reject() - elif Options["Disembargo"]: - advisory_info() - do_Disembargo() - elif Options["Drop-Advisory"]: - advisory_info() - do_DropAdvisory() + sys.exit() + + if len(changes) == 0: + utils.fubar("Need changes files as arguments") + + # Yes, we could do this inside do_Approve too. But this way we see who exactly + # called it (ownership of the file) + + acceptfiles={} + for change in changes: + dbchange=get_dbchange(os.path.basename(change), session) + # strip epoch from version + version=dbchange.version + version=version[(version.find(':')+1):] + acceptfilename="%s/COMMENTS/ACCEPT.%s_%s" % (os.path.dirname(os.path.abspath(changes[0])), dbchange.source, version) + acceptfiles[acceptfilename]=1 + + print "Would create %s now and then go on to accept this package, if you allow me to." % (acceptfiles.keys()) + if Options["No-Action"]: + sys.exit(0) else: - while 1: - default = "Q" - opts = ["Approve", "Edit advisory"] - if os.path.exists("./advisory.%s" % advisory): - default = "A" - else: - default = "E" - if os.getcwd() == Cnf["Dir::Queue::Embargoed"].rstrip("/"): - opts.append("Disembargo") - opts += ["Show advisory", "Reject", "Quit"] - - advisory_info() - what = prompt(opts, default) - - if what == "Quit": - do_Quit() - elif what == "Approve": - do_Approve() - elif what == "Edit advisory": - do_Edit() - elif what == "Show advisory": - do_Show() - elif what == "Disembargo": - do_Disembargo() - elif what == "Reject": - do_Reject() - else: - utils.fubar("Impossible answer '%s', wtf?" % (what)) + raw_input("Press Enter to continue") + + for acceptfilename in acceptfiles.keys(): + accept_file = file(acceptfilename, "w") + accept_file.write("OK\n") + accept_file.close() + + do_Approve() -################################################################################ if __name__ == '__main__': main() - -################################################################################