[Piuparts-commits] [SCM] piuparts git repository branch, develop, updated. 0.44-679-g25460c0

Andreas Beckmann debian at abeckmann.de
Tue Jun 5 07:42:18 UTC 2012


The following commit has been merged in the develop branch:
commit 45bd5facf78c9d47165376db580ce0a74c459c19
Author: Andreas Beckmann <debian at abeckmann.de>
Date:   Sun Jun 3 19:28:06 2012 +0200

    p: run(): add timeout option
    
    Terminate command after timeout was reached.
    
    Signed-off-by: Andreas Beckmann <debian at abeckmann.de>

diff --git a/debian/changelog b/debian/changelog
index 67054ba..b2725ee 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -51,6 +51,7 @@ piuparts (0.45) UNRELEASED; urgency=low
       + /var/lib/nagios/                        (Closes: #668756)
       + /var/lib/openvswitch/(pki/.*)?
       + /var/spool/powerdns/                    (Closes: #531134, #531135)
+    - Implement a timeout for commands being run in the chroot.
   * piuparts.conf:
     - Make master-command a [global] instead of a [section] setting.
       The section name will be given as an argument to this command.
diff --git a/piuparts.py b/piuparts.py
index df960fb..54451cc 100644
--- a/piuparts.py
+++ b/piuparts.py
@@ -49,7 +49,7 @@ import subprocess
 import unittest
 import urllib
 import uuid
-from signal import signal, SIGTERM, SIGKILL
+from signal import alarm, signal, SIGALRM, SIGTERM, SIGKILL
 
 try:
     from debian import deb822
@@ -384,7 +384,14 @@ def indent_string(str):
     return "\n".join(["  " + line for line in str.split("\n")])
 
 
-def run(command, ignore_errors=False):
+class Alarm(Exception):
+    pass
+
+def alarm_handler(signum, frame):
+    raise Alarm
+
+
+def run(command, ignore_errors=False, timeout=0):
     """Run an external command and die with error message if it fails."""
 
     def kill_subprocess(p, reason):
@@ -411,6 +418,9 @@ def run(command, ignore_errors=False):
                          stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
     output = ""
     excessive_output = False
+    if timeout > 0:
+        signal(SIGALRM, alarm_handler)
+        alarm(timeout)
     try:
         while p.poll() is None:
             """Read 64 KB chunks, but depending on the output buffering behavior
@@ -419,12 +429,14 @@ def run(command, ignore_errors=False):
             output += p.stdout.read(1 << 16)
             if (len(output) > settings.max_command_output_size):
                 excessive_output = True
+                alarm(0)
                 kill_subprocess(p, "excessive output")
                 break
         if not excessive_output:
             output += p.stdout.read(settings.max_command_output_size)
-    except None:
-        pass
+        alarm(0)
+    except Alarm:
+        kill_subprocess(p, "excessive runtime")
     devnull.close()
 
     if output:

-- 
piuparts git repository



More information about the Piuparts-commits mailing list