<html>
  <head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
  </head>
  <body bgcolor="#FFFFFF" text="#000000">
    <div class="moz-cite-prefix">On 01/10/2014 04:16 PM, Royce Lv wrote:<br>
    </div>
    <blockquote cite="mid:52CFAC79.5060207@linux.vnet.ibm.com"
      type="cite">On 2014年01月10日 09:00, <a class="moz-txt-link-abbreviated" href="mailto:shaohef@linux.vnet.ibm.com">shaohef@linux.vnet.ibm.com</a>
      wrote:
      <br>
      <blockquote type="cite">From: ShaoHe Feng
        <a class="moz-txt-link-rfc2396E" href="mailto:shaohef@linux.vnet.ibm.com">&lt;shaohef@linux.vnet.ibm.com&gt;</a>
        <br>
        <br>
        We need a common function to execute shell command.
        <br>
        We also need timeout when execute shell command.
        <br>
        <br>
        A threading.Timer is used to send signal.SIGKILL to kill the
        command
        <br>
        when timeout.
        <br>
        <br>
        Signed-off-by: Royce Lv <a class="moz-txt-link-rfc2396E" href="mailto:lvroyce@linux.vnet.ibm.com">&lt;lvroyce@linux.vnet.ibm.com&gt;</a>
        <br>
        Signed-off-by: ShaoHe Feng <a class="moz-txt-link-rfc2396E" href="mailto:shaohef@linux.vnet.ibm.com">&lt;shaohef@linux.vnet.ibm.com&gt;</a>
        <br>
        ---
        <br>
          src/kimchi/utils.py | 39
        +++++++++++++++++++++++++++++++++++++++
        <br>
          1 file changed, 39 insertions(+)
        <br>
        <br>
        diff --git a/src/kimchi/utils.py b/src/kimchi/utils.py
        <br>
        index af245c6..94097ad 100644
        <br>
        --- a/src/kimchi/utils.py
        <br>
        +++ b/src/kimchi/utils.py
        <br>
        @@ -23,6 +23,7 @@
        <br>
        <br>
          import cherrypy
        <br>
          import os
        <br>
        +import subprocess
        <br>
          import urllib2
        <br>
        <br>
        <br>
        @@ -30,6 +31,7 @@ from cherrypy.lib.reprconf import Parser
        <br>
        <br>
        <br>
          from kimchi import config
        <br>
        +from threading import Timer
        <br>
        <br>
        <br>
          kimchi_log = cherrypy.log.error_log
        <br>
        @@ -96,3 +98,40 @@ def check_url_path(path):
        <br>
                  return False
        <br>
        <br>
              return True
        <br>
        +
        <br>
        +
        <br>
        +def run_command(cmd, timeout=None):
        <br>
        +    def kill_proc(proc, timeout_flag):
        <br>
        +        timeout_flag[0] = True
        <br>
        +        proc.kill()
        <br>
        +
        <br>
        +    proc = None
        <br>
        +    timer = None
        <br>
        +    timeout_flag = [False]
        <br>
        +
        <br>
        +    try:
        <br>
        +        proc = subprocess.Popen(cmd, stdout=subprocess.PIPE,
        <br>
        +                                stderr=subprocess.PIPE)
        <br>
        +        if timeout is not None:
        <br>
        +            timer = Timer(timeout, kill_proc, [proc,
        timeout_flag])
        <br>
        +            timer.start()
        <br>
      </blockquote>
      I like the idea of using timer, I think the only thing we need to
      take care is check timeout happens and report a specific error.
      <br>
      Or when we kill the proc and it is blocked, the proc.communicate()
      error will not be 'timeout happens'
      <br>
    </blockquote>
    <br>
    when we kill the proc, the <font size="3"><font color="#909090">proc.returncode
        will be -9 and </font></font><font size="3"><font
        color="#909090">timeout_flag[0] is True.</font></font><br>
    <br>
    so we can log the timeout <br>
    <br>
    <font size="3"><font color="#909090">if proc.returncode == -9 and
        timeout_flag[0] is True:<br>
             kimchi_log.error("process is killed by signal.SIGKILL for
        timeout %s seconds", timeout)<br>
      </font></font><br>
    or raise a TimeoutError:<br>
    we can define a new Exception TimeoutError.<br>
    <font size="3"><font color="#909090"><font size="3"><font
            color="#909090"></font></font>if proc.returncode == -9 and
        timeout_flag[0] is True:<br>
             raise TimeoutError("process is killed by signal.SIGKILL for
        timeout %s seconds" % timeout)<br>
        <br>
      </font></font>
    <blockquote cite="mid:52CFAC79.5060207@linux.vnet.ibm.com"
      type="cite">
      <blockquote type="cite">+
        <br>
        +        out, error = proc.communicate()
        <br>
        +        kimchi_log.debug("Run command '%s'", " ".join(cmd))
        <br>
        +
        <br>
        +        if out or error:
        <br>
        +            kimchi_log.debug("out:\n %s\nerror:\n %s", out,
        error)
        <br>
        +
        <br>
        +        return out, error, proc.returncode, timeout_flag[0]
        <br>
        +    except Exception as e:
        <br>
        +        msg = "Failed to run command: %s." % " ".join(cmd)
        <br>
        +        msg = msg if proc is None else msg + "\n  error code:
        %s."
        <br>
        +        kimchi_log.error("%s\n  %s", msg, e)
        <br>
        +
        <br>
        +        if proc:
        <br>
        +            return out, error, proc.returncode, timeout_flag[0]
        <br>
        +        else:
        <br>
        +            return None, None, None, timeout_flag[0]
        <br>
        +    finally:
        <br>
        +        if timer and not timeout_flag[0]:
        <br>
        +            timer.cancel()
        <br>
      </blockquote>
      <br>
      <br>
      <br>
    </blockquote>
    <br>
    <br>
    <pre class="moz-signature" cols="72">-- 
Thanks and best regards!

Sheldon Feng(冯少合)<a class="moz-txt-link-rfc2396E" href="mailto:shaohef@linux.vnet.ibm.com">&lt;shaohef@linux.vnet.ibm.com&gt;</a>
IBM Linux Technology Center</pre>
  </body>
</html>