[Treepkg-commits] r16 - in trunk: bin test treepkg

scm-commit@wald.intevation.org scm-commit at wald.intevation.org
Tue Sep 11 19:24:56 CEST 2007


Author: bh
Date: 2007-09-11 19:24:56 +0200 (Tue, 11 Sep 2007)
New Revision: 16

Added:
   trunk/bin/telltreepkg.py
Modified:
   trunk/test/test_packager.py
   trunk/treepkg/packager.py
   trunk/treepkg/readconfig.py
Log:
Implement a way to stop a running treepackager.


Added: trunk/bin/telltreepkg.py
===================================================================
--- trunk/bin/telltreepkg.py	2007-09-11 13:58:28 UTC (rev 15)
+++ trunk/bin/telltreepkg.py	2007-09-11 17:24:56 UTC (rev 16)
@@ -0,0 +1,31 @@
+#! /usr/bin/python2.4
+# Copyright (C) 2007 by Intevation GmbH
+# Authors:
+# Bernhard Herzog <bh at intevation.de>
+#
+# This program is free software under the GPL (>=v2)
+# Read the file COPYING coming with the software for details.
+
+"""Sends instructions to a running packager"""
+
+import sys
+
+import treepkgcmd
+from treepkg.options import create_parser
+from treepkg.readconfig import read_config
+from treepkg.util import writefile
+
+def main():
+    options, args = create_parser().parse_args()
+
+    if len(args) != 1:
+        print >>sys.stderr, "The command to send to treepkg must be given"
+        sys.exit(1)
+
+    treepkg_opts, packager_opts = read_config(options.config_file)
+
+    filename = treepkg_opts.get("instructions_file")
+    if filename:
+        writefile(filename, args[0])
+
+main()


Property changes on: trunk/bin/telltreepkg.py
___________________________________________________________________
Name: svn:executable
   + *
Name: svn:keywords
   + Id Revision
Name: svn:eol-style
   + native

Modified: trunk/test/test_packager.py
===================================================================
--- trunk/test/test_packager.py	2007-09-11 13:58:28 UTC (rev 15)
+++ trunk/test/test_packager.py	2007-09-11 17:24:56 UTC (rev 16)
@@ -131,7 +131,76 @@
                           ["testpkg_2-kk1_all.deb",
                            "testpkg_2-kk1_i386.changes"])
 
+class StoppingPackager(treepkg.packager.RevisionPackager):
 
+    def package(self):
+        pass
+
+class StoppingTrack(treepkg.packager.PackageTrack):
+
+    def __init__(self, do_package, do_stop, instructions_file, name, trackdir):
+        super(StoppingTrack, self).__init__(name, trackdir, "", "", "",
+                                            "", "")
+        self.do_package = do_package
+        self.do_stop = do_stop
+        self.instructions_file = instructions_file
+
+    def package_if_updated(self, revision):
+        if self.do_stop:
+            writefile(self.instructions_file, "stop")
+        if self.do_package:
+            return StoppingPackager(self, 1)
+        else:
+            return None
+
+
+class TestPackageGroupStop(unittest.TestCase, FileTestMixin):
+
+    def setUp(self):
+        self.trackdir = self.create_temp_dir(self.id() + "-track")
+        self.instructions_file = os.path.join(self.trackdir, "instructions")
+
+    def group(self, do_package=True, do_stop=True):
+        return PackagerGroup([StoppingTrack(do_package, do_stop,
+                                            self.instructions_file,
+                                            "test", self.trackdir)],
+                             1, instructions_file=self.instructions_file)
+
+    def test_stop(self):
+        group = self.group(do_package=True, do_stop=True)
+        self.failUnless(group.check_package_tracks())
+
+    def test_no_stop(self):
+        group = self.group(do_package=True, do_stop=False)
+        self.failIf(group.check_package_tracks())
+
+    def test_instruction_removal(self):
+        # run once with stopping
+        group = self.group(do_package=True, do_stop=True)
+        self.failUnless(group.check_package_tracks())
+
+        # run again without stopping but using the same files.  The
+        # instructions file should be removed automatically
+        group = self.group(do_package=True, do_stop=False)
+        self.failIf(group.check_package_tracks())
+
+    def test_stopping_without_packaging(self):
+        group = self.group(do_package=False, do_stop=True)
+        self.failUnless(group.check_package_tracks())
+
+    def test_stopping_between_checks(self):
+        group = self.group(do_package=False, do_stop=False)
+        # run check_package_tracks once
+        self.failIf(group.check_package_tracks())
+
+        # tell treepkg to stop
+        writefile(self.instructions_file, "stop")
+
+        # check again.  The check_package_tracks() may remove the
+        # instructions file but it must do so only the first time
+        self.failUnless(group.check_package_tracks())
+
+
 class TestPackageTrack(unittest.TestCase, FileTestMixin):
 
     def setUp(self):

Modified: trunk/treepkg/packager.py
===================================================================
--- trunk/treepkg/packager.py	2007-09-11 13:58:28 UTC (rev 15)
+++ trunk/treepkg/packager.py	2007-09-11 17:24:56 UTC (rev 16)
@@ -396,10 +396,13 @@
 
 class PackagerGroup(object):
 
-    def __init__(self, package_tracks, check_interval, revision=None):
+    def __init__(self, package_tracks, check_interval, revision=None,
+                 instructions_file=None):
         self.package_tracks = package_tracks
         self.check_interval = check_interval
         self.revision = revision
+        self.instructions_file = instructions_file
+        self.instructions_file_removed = False
 
     def run(self):
         """Runs the packager group indefinitely"""
@@ -409,7 +412,8 @@
         while 1:
             now = time.time()
             if now > last_check + self.check_interval:
-                self.check_package_tracks()
+                if self.check_package_tracks():
+                    break
                 last_check = now
                 next_check = now + self.check_interval
                 to_sleep = next_check - time.time()
@@ -420,14 +424,21 @@
                     time.sleep(to_sleep)
                 else:
                     logging.info("Next check now")
+                if self.should_stop():
+                    logging.info("Received stop instruction.  Stopping.")
+                    return
 
     def check_package_tracks(self):
         logging.info("Checking package tracks")
+        self.clear_instruction()
         for track in self.package_tracks:
             try:
                 packager = track.package_if_updated(revision=self.revision)
                 if packager:
                     packager.package()
+                if self.should_stop():
+                    logging.info("Received stop instruction.  Stopping.")
+                    return True
             except:
                 logging.exception("An error occurred while"
                                   " checking packager track %r", track.name)
@@ -435,3 +446,25 @@
 
     def get_package_tracks(self):
         return self.package_tracks
+
+    def read_instruction(self):
+        if not self.instructions_file:
+            return ""
+        try:
+            f = open(self.instructions_file)
+        except (IOError, OSError):
+            return ""
+        try:
+            return f.read().strip()
+        finally:
+            f.close()
+            self.clear_instruction()
+
+    def clear_instruction(self, force=False):
+        if self.instructions_file and (not self.instructions_file_removed
+                                       or force):
+            util.writefile(self.instructions_file, "")
+            self.instructions_file_removed = True
+
+    def should_stop(self):
+        return self.read_instruction() == "stop"

Modified: trunk/treepkg/readconfig.py
===================================================================
--- trunk/treepkg/readconfig.py	2007-09-11 13:58:28 UTC (rev 15)
+++ trunk/treepkg/readconfig.py	2007-09-11 17:24:56 UTC (rev 16)
@@ -23,6 +23,7 @@
 
 treepkg_desc = [
     ("check_interval", int),
+    "instructions_file",
     ]
 
 



More information about the Treepkg-commits mailing list