[Piuparts-commits] [SCM] piuparts git repository branch, master, updated. eda668423fa87898c59d1075118693714aa5a053
Holger Levsen
holger at layer-acht.org
Fri Dec 23 10:26:54 UTC 2011
The following commit has been merged in the master branch:
commit 8a1e3b79a6bd7fa07b628b9b75089a5f8b24d22f
Author: Scott Schaefer <saschaefer at neurodiverse.org>
Date: Wed Sep 28 20:45:16 2011 -0400
Kill children to insure test doesn't run "forever" (Closes: #640647)
diff --git a/TODO b/TODO
index f7b1cc6..730b9b2 100644
--- a/TODO
+++ b/TODO
@@ -48,6 +48,9 @@ for 0.43:
- sometimes a chroot doesn't get removed on piatti - find out
why and fix it.
+- Adjust report scripts to detect this condition;
+ text in log="*** Process KILLED - exceed maximum run time ***"
+
for 0.44:
@@ -112,16 +115,8 @@ for 0.47 and later:
- a redirect of http://piuparts.d.o/foo to
http://p.d.o/source/f/foo.html would be nice
-- monitor:
- - write slave-watcher to monitor hanging processes, eg.
- looping dpkg-preconfigure
- - Check for and kill extraneous processes afterwards. Perhaps
- by checking whether their working directory is in the
- chroot.
- Introduce a whitelist of processes to wait for and assume
- it's an error if those haven't been killed after $time, ie
- 10min. see #387428
- - master.log grows to fast and there is no mechanism to stop it
+- monitor: master.log grows to fast and there is no mechanism to stop it
+ - use logrotate
for 0.50 and later:
diff --git a/debian/changelog b/debian/changelog
index ff671e1..e7ecb9c 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -36,6 +36,8 @@ piuparts (0.42) UNRELEASED; urgency=low
a) Existing diversions removed/modified, and/or
b) Installed diversions not removed by purge:
(Closes: #588313)
+ * Kill children (hard-coded value, 45 minutes) to insure test doesn't
+ run "forever" (Closes: #640647)
[ Andreas Beckmann ]
* *.py: Add vim modeline.
diff --git a/piuparts-slave.py b/piuparts-slave.py
index 5ccf6fe..f0e430c 100644
--- a/piuparts-slave.py
+++ b/piuparts-slave.py
@@ -28,6 +28,7 @@ import sys
import stat
import time
import logging
+from signal import alarm, signal, SIGALRM, SIGKILL
import subprocess
import ConfigParser
@@ -36,7 +37,7 @@ import piupartslib.packagesdb
CONFIG_FILE = "/etc/piuparts/piuparts.conf"
-
+MAX_WAIT_TEST_RUN = 45*60
def setup_logging(log_level, log_file_name):
logger = logging.getLogger()
@@ -83,6 +84,12 @@ class Config(piupartslib.conf.Config):
}, "")
+class Alarm(Exception):
+ pass
+
+def alarm_handler(signum, frame):
+ raise Alarm
+
class MasterNotOK(Exception):
def __init__(self):
@@ -346,6 +353,41 @@ def upgrade_testable(config, package, packages_files):
else:
return False
+def get_process_children(pid):
+ p = subprocess.Popen('ps --no-headers -o pid --ppid %d' % pid,
+ shell = True, stdout = subprocess.PIPE, stderr = subprocess.PIPE)
+ stdout, stderr = p.communicate()
+ return [int(p) for p in stdout.split()]
+
+def run_test_with_timeout(cmd, maxwait, kill_all):
+ logging.debug("Executing: %s" % cmd)
+
+ stdout = ""
+ sh_cmd = "{ %s; } 2>&1" % cmd
+ p = subprocess.Popen(sh_cmd, shell=True,
+ stdin=subprocess.PIPE, stdout=subprocess.PIPE)
+ if maxwait > 0:
+ signal(SIGALRM, alarm_handler)
+ alarm(maxwait)
+ try:
+ stdout, stderr = p.communicate()
+ if maxwait > 0:
+ alarm(0)
+ except Alarm:
+ pids = [p.pid]
+ if kill_all:
+ pids.extend(get_process_children(p.pid))
+ for pid in pids:
+ if pid > 0:
+ try:
+ os.kill(pid, SIGKILL)
+ except OSError:
+ pass
+ return -1,stdout
+
+ return p.returncode,stdout
+
+
def test_package(config, package, packages_files):
logging.info("Testing package %s/%s %s" % (config.section, package["Package"], package["Version"]))
@@ -360,54 +402,46 @@ def test_package(config, package, packages_files):
output.write("\n")
# omit distro test if chroot-tgz is not specified.
+ ret = 0
if config["chroot-tgz"]:
- command = "%(piuparts-cmd)s -ad %(distro)s -b %(chroot-tgz)s" % \
- config
- if config["keep-sources-list"] in ["yes", "true"]:
- command += " --keep-sources-list "
+ command = "%(piuparts-cmd)s -ad %(distro)s -b %(chroot-tgz)s" % \
+ config
+ if config["keep-sources-list"] in ["yes", "true"]:
+ command += " --keep-sources-list "
+ if config["mirror"]:
+ command += " --mirror %s " % config["mirror"]
+ command += " " + package["Package"]
- if config["mirror"]:
- command += " --mirror %s " % config["mirror"]
- command += " " + package["Package"]
-
- logging.debug("Executing: %s" % command)
- output.write("Executing: %s\n" % command)
- f = os.popen("{ %s; } 2>&1" % command, "r")
- for line in f:
- output.write(line)
- status = f.close()
- if status is None:
- status = 0
- else:
- status = 0
+ output.write("Executing: %s\n" % command)
+ ret,f = run_test_with_timeout(command, MAX_WAIT_TEST_RUN, True)
+ if ret < 0:
+ output.write(f + "\n *** Process KILLED - exceed maximum run time ***\n")
+ else:
+ output.write(f)
- if status == 0 and upgrade_testable(config, package, packages_files):
+ if ret == 0 and upgrade_testable(config, package, packages_files):
distros = config["upgrade-test-distros"].split()
distros = ["-d " + distro.strip() for distro in distros]
distros = " ".join(distros)
command = "%(piuparts-cmd)s -ab %(upgrade-test-chroot-tgz)s " % config
command += distros
-
if config["mirror"]:
command += " --mirror %s " % config["mirror"]
-
command += " " + package["Package"]
- logging.debug("Executing: %s" % command)
- output.write("\nExecuting: %s\n" % command)
- f = os.popen("{ %s; } 2>&1" % command, "r")
- for line in f:
- output.write(line)
+ output.write("Executing: %s\n" % cmd)
+ ret,f = run_test_with_timeout(command, MAX_WAIT_TEST_RUN, True)
+ if ret < 0:
+ output.write(" *** Process KILLED - exceed maximum run time ***\n")
+ else:
+ output.write(f)
output.flush()
- status = f.close()
- if status is None:
- status = 0
output.write("\n")
output.write(time.strftime("End: %Y-%m-%d %H:%M:%S %Z\n",
time.gmtime()))
output.close()
- if not os.WIFEXITED(status) or os.WEXITSTATUS(status) != 0:
+ if ret != 0:
subdir = "fail"
else:
subdir = "pass"
--
piuparts git repository
More information about the Piuparts-commits
mailing list