[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

[PATCH 1/3] Implement wb --transactional



From: Joachim Breitner <mail@joachim-breitner.de>

When called with this flag, wb will lock all wanna-build databases at
the beginning, and remove them at the end.
If wb crashes for some reason, the locks will be stale and automatically
removed by the next invocation of wanna-build.
---
 scripts/wb |   76 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 71 insertions(+), 5 deletions(-)

diff --git a/scripts/wb b/scripts/wb
index 37f58b2..8572d18 100755
--- a/scripts/wb
+++ b/scripts/wb
@@ -38,6 +38,14 @@ them with a dash, like this:
 
 Extra options, like -d 'stable' or -m 'message', can be passed by appending
 them to the end of the line, with an extra dot.
+
+To use wb interactively, while keeping a long-running lock on the wanna-build
+database, use
+
+    % wb --transaction
+
+This will lock the databases for all arches until wb finishes.
+
 """
 
 # TODO
@@ -64,11 +72,19 @@ from subprocess import PIPE
 def main():
     args = sys.argv[1:]
 
+    transactional = False
+    if args == ["--transaction"]:
+        transactional = True
+        args = []
+
     if args:
         do_command(args)
     else:
         isatty = os.isatty(sys.stdin.fileno())
 
+        if transactional:
+            get_transaction_locks()
+
         while True:
             if isatty:
                 try:
@@ -89,13 +105,18 @@ def main():
 
             # shlex.split() handles -m 'foo bar' correctly
             words = shlex.split(line, comments=True)
-            do_command(words, fatal_errors=False)
+            do_command(words, fatal_errors=False, transactional=transactional)
+
+
+        if transactional:
+            release_transaction_locks()
+
 
 ##
 
 commands = [ 'bp', 'gb', 'dw', 'nmu', 'fail', 'forget', 'info', 'help' ]
 
-def do_command(args, fatal_errors=True):
+def do_command(args, fatal_errors=True, transactional=False):
     try:
         command = args.pop(0)
     except IndexError:
@@ -210,7 +231,7 @@ def do_command(args, fatal_errors=True):
             srcver = None
 
         for arch in sorted(arches):
-            info = get_wb_info(pkg, dist, arch)
+            info = get_wb_info(pkg, dist, arch, transactional=transactional)
 
             if not info.has_key('Version'):
                 print >>sys.stderr, "W: can't get version info for %s/%s" % (pkg, arch)
@@ -220,6 +241,9 @@ def do_command(args, fatal_errors=True):
 
             cmd = [ 'wanna-build', '-b', '%s/build-db' % arch ]
 
+            if transactional:
+                cmd.extend([ '--act-on-behalve-of', str(os.getpid()) ])
+
             if command in ['gb', 'dw', 'fail']:
                 builder = info.get('Builder', None)
 
@@ -275,8 +299,50 @@ def do_command(args, fatal_errors=True):
 
 ##
 
-def get_wb_info(pkg, dist, arch):
-    cmd = [ 'wanna-build', '-b', '%s/build-db' % arch, '-d', dist, '--info', pkg ]
+def get_transaction_locks():
+    for arch in DEFAULT_ARCHITECTURES:
+            cmd = [ 'wanna-build', '-b', '%s/build-db' % arch ]
+
+            cmd.extend(['--lock-for', str(os.getpid())])
+
+            p = subprocess.Popen(cmd, stdout=PIPE, stderr=PIPE)
+            status = p.wait()
+            output = p.stdout.readlines() + p.stderr.readlines()
+
+            if status or output:
+                print '* Aquiring lock for %s%s' % (arch,
+                        status and ': exit status %d' % status or '')
+                if output:
+                    print ''.join('  | ' + x for x in output)
+
+##
+
+def release_transaction_locks():
+    for arch in DEFAULT_ARCHITECTURES:
+            cmd = [ 'wanna-build', '-b', '%s/build-db' % arch ]
+
+            cmd.extend(['--unlock-for', str(os.getpid())])
+
+            p = subprocess.Popen(cmd, stdout=PIPE, stderr=PIPE)
+            status = p.wait()
+            output = p.stdout.readlines() + p.stderr.readlines()
+
+            if status or output:
+                print '* Releasing lock for %s%s' % (arch,
+                        status and ': exit status %d' % status or '')
+                if output:
+                    print ''.join('  | ' + x for x in output)
+
+##
+
+def get_wb_info(pkg, dist, arch, transactional=False):
+    cmd = [ 'wanna-build', '-b', '%s/build-db' % arch, '-d', dist]
+
+    if transactional:
+        cmd.extend([ '--act-on-behalve-of', str(os.getpid()) ])
+
+    cmd.extend(['--info', pkg])
+
     p = subprocess.Popen(cmd, stdout=subprocess.PIPE)
     p.wait()
 
-- 
1.6.3.3


Reply to: