1*03514f19SPatrick WilliamsFrom 8a18a6c1dea7cce6669d0eeb4230e85aa88d8e44 Mon Sep 17 00:00:00 2001 2eb8dc403SDave CobbleyFrom: Hongxu Jia <hongxu.jia@windriver.com> 319323693SBrad BishopDate: Fri, 23 Nov 2018 17:03:58 +0800 41a4b7ee2SBrad BishopSubject: [PATCH 02/11] run_program support timeout 5eb8dc403SDave Cobbley 6eb8dc403SDave CobbleyUpstream-Status: Pending 7eb8dc403SDave Cobbley 8eb8dc403SDave CobbleySigned-off-by: Hongxu Jia <hongxu.jia@windriver.com> 9eb8dc403SDave Cobbley--- 10*03514f19SPatrick Williams blivet/util.py | 70 +++++++++++++++++++++++++++++--------------------- 1119323693SBrad Bishop 1 file changed, 41 insertions(+), 29 deletions(-) 12eb8dc403SDave Cobbley 13eb8dc403SDave Cobbleydiff --git a/blivet/util.py b/blivet/util.py 14*03514f19SPatrick Williamsindex f8a8f88..a5da7b6 100644 15eb8dc403SDave Cobbley--- a/blivet/util.py 16eb8dc403SDave Cobbley+++ b/blivet/util.py 17*03514f19SPatrick Williams@@ -171,6 +171,30 @@ class Path(str): 18eb8dc403SDave Cobbley def __hash__(self): 19eb8dc403SDave Cobbley return self._path.__hash__() 20eb8dc403SDave Cobbley 21eb8dc403SDave Cobbley+def timeout_command(argv, timeout, *args, **kwargs): 22eb8dc403SDave Cobbley+ """call shell-command and either return its output or kill it 23eb8dc403SDave Cobbley+ if it doesn't normally exit within timeout seconds and return None""" 24eb8dc403SDave Cobbley+ import subprocess, datetime, os, time, signal 25eb8dc403SDave Cobbley+ start = datetime.datetime.now() 26eb8dc403SDave Cobbley+ 27eb8dc403SDave Cobbley+ try: 28eb8dc403SDave Cobbley+ proc = subprocess.Popen(argv, *args, **kwargs) 29eb8dc403SDave Cobbley+ while proc.poll() is None: 30eb8dc403SDave Cobbley+ time.sleep(0.1) 31eb8dc403SDave Cobbley+ now = datetime.datetime.now() 32eb8dc403SDave Cobbley+ if (now - start).seconds> timeout: 33eb8dc403SDave Cobbley+ os.kill(proc.pid, signal.SIGKILL) 34eb8dc403SDave Cobbley+ os.waitpid(-1, os.WNOHANG) 35eb8dc403SDave Cobbley+ program_log.debug("%d seconds timeout" % timeout) 36eb8dc403SDave Cobbley+ return (-1, None) 37eb8dc403SDave Cobbley+ 38eb8dc403SDave Cobbley+ 39eb8dc403SDave Cobbley+ except OSError as e: 40eb8dc403SDave Cobbley+ program_log.error("Error running %s: %s", argv[0], e.strerror) 41eb8dc403SDave Cobbley+ raise 42eb8dc403SDave Cobbley+ 43eb8dc403SDave Cobbley+ program_log.debug("Return code: %d", proc.returncode) 44eb8dc403SDave Cobbley+ return (proc.returncode, proc.stdout.read()) 45eb8dc403SDave Cobbley 46eb8dc403SDave Cobbley def _run_program(argv, root='/', stdin=None, env_prune=None, stderr_to_stdout=False, binary_output=False): 47eb8dc403SDave Cobbley if env_prune is None: 48*03514f19SPatrick Williams@@ -193,35 +217,23 @@ def _run_program(argv, root='/', stdin=None, env_prune=None, stderr_to_stdout=Fa 49eb8dc403SDave Cobbley stderr_dir = subprocess.STDOUT 50eb8dc403SDave Cobbley else: 51eb8dc403SDave Cobbley stderr_dir = subprocess.PIPE 52eb8dc403SDave Cobbley- try: 5319323693SBrad Bishop- proc = subprocess.Popen(argv, # pylint: disable=subprocess-popen-preexec-fn 54eb8dc403SDave Cobbley- stdin=stdin, 55eb8dc403SDave Cobbley- stdout=subprocess.PIPE, 56eb8dc403SDave Cobbley- stderr=stderr_dir, 57eb8dc403SDave Cobbley- close_fds=True, 58eb8dc403SDave Cobbley- preexec_fn=chroot, cwd=root, env=env) 59eb8dc403SDave Cobbley- 60eb8dc403SDave Cobbley- out, err = proc.communicate() 61eb8dc403SDave Cobbley- if not binary_output and six.PY3: 62eb8dc403SDave Cobbley- out = out.decode("utf-8") 63eb8dc403SDave Cobbley- if out: 64eb8dc403SDave Cobbley- if not stderr_to_stdout: 65eb8dc403SDave Cobbley- program_log.info("stdout:") 66eb8dc403SDave Cobbley- for line in out.splitlines(): 67eb8dc403SDave Cobbley- program_log.info("%s", line) 68eb8dc403SDave Cobbley- 69eb8dc403SDave Cobbley- if not stderr_to_stdout and err: 70eb8dc403SDave Cobbley- program_log.info("stderr:") 71eb8dc403SDave Cobbley- for line in err.splitlines(): 72eb8dc403SDave Cobbley- program_log.info("%s", line) 73eb8dc403SDave Cobbley- 74eb8dc403SDave Cobbley- except OSError as e: 75eb8dc403SDave Cobbley- program_log.error("Error running %s: %s", argv[0], e.strerror) 76eb8dc403SDave Cobbley- raise 77eb8dc403SDave Cobbley- 78eb8dc403SDave Cobbley- program_log.debug("Return code: %d", proc.returncode) 79eb8dc403SDave Cobbley- 80eb8dc403SDave Cobbley- return (proc.returncode, out) 8119323693SBrad Bishop+ 82eb8dc403SDave Cobbley+ res, out = timeout_command(argv, 10, 83eb8dc403SDave Cobbley+ stdin=stdin, 84eb8dc403SDave Cobbley+ stdout=subprocess.PIPE, 85eb8dc403SDave Cobbley+ stderr=stderr_dir, 86eb8dc403SDave Cobbley+ close_fds=True, 87eb8dc403SDave Cobbley+ preexec_fn=chroot, cwd=root, env=env) 88eb8dc403SDave Cobbley+ if not binary_output and six.PY3: 89eb8dc403SDave Cobbley+ out = out.decode("utf-8") 90eb8dc403SDave Cobbley+ if out: 91eb8dc403SDave Cobbley+ if not stderr_to_stdout: 92eb8dc403SDave Cobbley+ program_log.info("stdout:") 93eb8dc403SDave Cobbley+ for line in out.splitlines(): 94eb8dc403SDave Cobbley+ program_log.info("%s", line) 95eb8dc403SDave Cobbley+ 96eb8dc403SDave Cobbley+ return (res, out) 9719323693SBrad Bishop+ 9819323693SBrad Bishop 99eb8dc403SDave Cobbley 100eb8dc403SDave Cobbley def run_program(*args, **kwargs): 101