################################################################################
+from __future__ import with_statement
+
import copy
import errno
import os
import stat
import sys
import time
+import contextlib
+import pwd
import apt_pkg, apt_inst
import examine_package
from daklib import database
from daklib import queue
from daklib import utils
from daklib.regexes import re_no_epoch, re_default_answer, re_isanum
-from daklib.dak_exceptions import CantOpenError
+from daklib.dak_exceptions import CantOpenError, AlreadyLockedError, CantGetLockError
# Globals
Cnf = None #: Configuration, apt_pkg.Configuration
def edit_note(note):
# Write the current data to a temporary file
(fd, temp_filename) = utils.temp_filename()
- temp_file = os.fdopen(fd, 'w')
- if len(note) > 0:
- for line in note:
- temp_file.write(line)
- temp_file.close()
editor = os.environ.get("EDITOR","vi")
answer = 'E'
while answer == 'E':
os.system("%s %s" % (editor, temp_filename))
temp_file = utils.open_file(temp_filename)
- note = temp_file.read().rstrip()
+ newnote = temp_file.read().rstrip()
temp_file.close()
- print "Note:"
- print utils.prefix_multi_line_string(note," ")
+ print "New Note:"
+ print utils.prefix_multi_line_string(newnote," ")
prompt = "[D]one, Edit, Abandon, Quit ?"
answer = "XXX"
while prompt.find(answer) == -1:
elif answer == 'Q':
end()
sys.exit(0)
- database.add_new_comment(Upload.pkg.changes["source"], Upload.pkg.changes["version"], note, utils.whoami())
+ database.add_new_comment(Upload.pkg.changes["source"], Upload.pkg.changes["version"], newnote, utils.whoami())
################################################################################
################################################################################
-def prod_maintainer ():
+def prod_maintainer (note):
# Here we prepare an editor and get them ready to prod...
(fd, temp_filename) = utils.temp_filename()
+ temp_file = os.fdopen(fd, 'w')
+ if len(note) > 0:
+ for line in note:
+ temp_file.write(line)
+ temp_file.close()
editor = os.environ.get("EDITOR","vi")
answer = 'E'
while answer == 'E':
os.system("%s %s" % (editor, temp_filename))
- f = os.fdopen(fd)
- prod_message = "".join(f.readlines())
- f.close()
+ temp_fh = utils.open_file(temp_filename)
+ prod_message = "".join(temp_fh.readlines())
+ temp_fh.close()
print "Prod message:"
print utils.prefix_multi_line_string(prod_message," ",include_blank_lines=1)
prompt = "[P]rod, Edit, Abandon, Quit ?"
if answer == "":
answer = m.group(1)
answer = answer[:1].upper()
- os.unlink(temp_filename)
- if answer == 'A':
- return
- elif answer == 'Q':
- end()
- sys.exit(0)
+ os.unlink(temp_filename)
+ if answer == 'A':
+ return
+ elif answer == 'Q':
+ end()
+ sys.exit(0)
# Otherwise, do the proding...
user_email_address = utils.whoami() + " <%s>" % (
Cnf["Dinstall::MyAdminAddress"])
answer = answer[:1].upper()
if answer == 'A' and not Options["Trainee"]:
- done = add_overrides (new)
+ try:
+ check_daily_lock()
+ done = add_overrides (new)
+ except CantGetLockError:
+ print "Hello? Operator! Give me the number for 911!"
+ print "Dinstall in the locked area, cant process packages, come back later"
elif answer == 'C':
check_pkg()
elif answer == 'E' and not Options["Trainee"]:
new = edit_overrides (new)
elif answer == 'M' and not Options["Trainee"]:
- aborted = Upload.do_reject(1, Options["Manual-Reject"])
+ aborted = Upload.do_reject(manual=1,
+ reject_message=Options["Manual-Reject"],
+ note=database.get_new_comments(changes.get("source", "")))
if not aborted:
os.unlink(Upload.pkg.changes_file[:-8]+".dak")
done = 1
elif answer == 'N':
edit_note(database.get_new_comments(changes.get("source", "")))
elif answer == 'P' and not Options["Trainee"]:
- prod_maintainer()
- elif answer == 'R':
+ prod_maintainer(database.get_new_comments(changes.get("source", "")))
+ elif answer == 'R' and not Options["Trainee"]:
confirm = utils.our_raw_input("Really clear note (y/N)? ").lower()
if confirm == "y":
database.delete_new_comments(changes.get("source"), changes.get("version"))
try:
Logger = Upload.Logger = logging.Logger(Cnf, "process-new")
except CantOpenError, e:
- Options["Trainee"] = True
+ Options["Trainee"] = "Oh yes"
projectB = Upload.projectB
################################################################################
-def get_accept_lock():
- retry = 0
- while retry < 10:
- try:
- os.open(Cnf["Process-New::AcceptedLockFile"], os.O_RDONLY | os.O_CREAT | os.O_EXCL)
- retry = 10
- except OSError, e:
- if e.errno == errno.EACCES or e.errno == errno.EEXIST:
- retry += 1
- if (retry >= 10):
- utils.fubar("Couldn't obtain lock; assuming 'dak process-unchecked' is already running.")
- else:
- print("Unable to get accepted lock (try %d of 10)" % retry)
- time.sleep(60)
- else:
- raise
+def check_daily_lock():
+ """
+ Raises CantGetLockError if the dinstall daily.lock exists.
+ """
+
+ try:
+ os.open(Cnf["Process-New::DinstallLockFile"], os.O_RDONLY | os.O_CREAT | os.O_EXCL)
+ except OSError, e:
+ if e.errno == errno.EEXIST or e.errno == errno.EACCES:
+ raise CantGetLockError
+
+ os.unlink(Cnf["Process-New::DinstallLockFile"])
+
+
+@contextlib.contextmanager
+def lock_package(package):
+ """
+ Lock C{package} so that noone else jumps in processing it.
+
+ @type package: string
+ @param package: source package name to lock
+ """
+
+ path = os.path.join(Cnf["Process-New::LockDir"], package)
+ try:
+ fd = os.open(path, os.O_CREAT | os.O_EXCL | os.O_RDONLY)
+ except OSError, e:
+ if e.errno == errno.EEXIST or e.errno == errno.EACCES:
+ user = pwd.getpwuid(os.stat(path)[stat.ST_UID])[4].split(',')[0].replace('.', '')
+ raise AlreadyLockedError, user
+
+ try:
+ yield fd
+ finally:
+ os.unlink(path)
def move_to_dir (dest, perms=0660, changesperms=0664):
utils.move (Upload.pkg.changes_file, dest, perms=changesperms)
if Options["No-Action"]:
return
(summary, short_summary) = Upload.build_summaries()
- Upload.accept(summary, short_summary)
+ Upload.accept(summary, short_summary, targetdir=Cnf["Dir::Queue::Newstage"])
os.unlink(Upload.pkg.changes_file[:-8]+".dak")
def do_accept_stableupdate(suite, q):
def do_accept():
print "ACCEPT"
if not Options["No-Action"]:
- get_accept_lock()
(summary, short_summary) = Upload.build_summaries()
- try:
- if Cnf.FindB("Dinstall::SecurityQueueHandling"):
- Upload.dump_vars(Cnf["Dir::Queue::Embargoed"])
- move_to_dir(Cnf["Dir::Queue::Embargoed"])
- Upload.queue_build("embargoed", Cnf["Dir::Queue::Embargoed"])
- # Check for override disparities
- Upload.Subst["__SUMMARY__"] = summary
- else:
- # Stable updates need to be copied to proposed-updates holding
- # area instead of accepted. Sourceful uploads need to go
- # to it directly, binaries only if the source has not yet been
- # accepted into p-u.
- for suite, q in [("proposed-updates", "ProposedUpdates"),
- ("oldstable-proposed-updates", "OldProposedUpdates")]:
- if not Upload.pkg.changes["distribution"].has_key(suite):
- continue
- return do_accept_stableupdate(suite, q)
- # Just a normal upload, accept it...
- _accept()
- finally:
- if not Options["No-Action"]:
- os.unlink(Cnf["Process-New::AcceptedLockFile"])
+ if Cnf.FindB("Dinstall::SecurityQueueHandling"):
+ Upload.dump_vars(Cnf["Dir::Queue::Embargoed"])
+ move_to_dir(Cnf["Dir::Queue::Embargoed"])
+ Upload.queue_build("embargoed", Cnf["Dir::Queue::Embargoed"])
+ # Check for override disparities
+ Upload.Subst["__SUMMARY__"] = summary
+ else:
+ # Stable updates need to be copied to proposed-updates holding
+ # area instead of accepted. Sourceful uploads need to go
+ # to it directly, binaries only if the source has not yet been
+ # accepted into p-u.
+ for suite, q in [("proposed-updates", "ProposedUpdates"),
+ ("oldstable-proposed-updates", "OldProposedUpdates")]:
+ if not Upload.pkg.changes["distribution"].has_key(suite):
+ continue
+ return do_accept_stableupdate(suite, q)
+ # Just a normal upload, accept it...
+ _accept()
def check_status(files):
new = byhand = 0
Upload.update_subst()
files = Upload.pkg.files
- if not recheck():
- return
-
- (new, byhand) = check_status(files)
- if new or byhand:
- if new:
- do_new()
- if byhand:
- do_byhand()
- (new, byhand) = check_status(files)
+ try:
+ check_daily_lock()
+ except CantGetLockError:
+ print "Hello? Operator! Give me the number for 911!"
+ print "Dinstall in the locked area, cant process packages, come back later"
+ sys.exit(1)
- if not new and not byhand:
- do_accept()
+ try:
+ with lock_package(Upload.pkg.changes["source"]):
+ if not recheck():
+ return
+
+ (new, byhand) = check_status(files)
+ if new or byhand:
+ if new:
+ do_new()
+ if byhand:
+ do_byhand()
+ (new, byhand) = check_status(files)
+
+ if not new and not byhand:
+ do_accept()
+ except AlreadyLockedError, e:
+ print "Seems to be locked by %s already, skipping..." % (e)
################################################################################
sys.stderr.write("Accepted %d package %s, %s.\n" % (accept_count, sets, utils.size_type(int(accept_bytes))))
Logger.log(["total",accept_count,accept_bytes])
- if not Options["No-Action"]:
+ if not Options["No-Action"] and not Options["Trainee"]:
Logger.close()
################################################################################
if not changes_file:
continue
print "\n" + changes_file
+
do_pkg (changes_file)
end()