]> git-server-git.apps.pok.os.sepia.ceph.com Git - teuthology.git/commitdiff
test
authorPatrick Donnelly <pdonnell@redhat.com>
Thu, 11 Apr 2024 20:14:05 +0000 (16:14 -0400)
committerPatrick Donnelly <pdonnell@redhat.com>
Thu, 11 Apr 2024 20:14:05 +0000 (16:14 -0400)
teuthology/task/install/bin/stdin-killer

index d1c9ba4ec2d1a77ce57b2262cde33a560d2f36fb..16a5e0f151d06a57ae0fb3285c5f216614b64d0d 100755 (executable)
@@ -146,8 +146,57 @@ def listen_for_events(sigfdr, p, timeout):
                         NS.timeout,
                     )
 
+def do_exec(NS):
+    cargs = NS.cmd + NS.args
+    popen_kwargs = {
+        "stdin": subprocess.PIPE,
+    }
 
-if __name__ == "__main__":
+    if NS.setpgrp == "self":
+        pgrp = os.getpgrp()
+        if pgrp != os.getpid():
+            os.setpgrp()
+            pgrp = os.getpgrp()
+    elif NS.setpgrp == "child":
+        popen_kwargs["preexec_fn"] = os.setpgrp
+        pgrp = None
+    elif NS.setpgrp == "no":
+        pgrp = 0
+    else:
+        assert False
+
+    log.debug("executing %s", cargs)
+    p = subprocess.Popen(cargs, **popen_kwargs)
+    if pgrp is None:
+        pgrp = p.pid
+    flags = fcntl.fcntl(p.stdin.fileno(), fcntl.F_GETFL)
+    fcntl.fcntl(p.stdin.fileno(), fcntl.F_SETFL, flags | os.O_NONBLOCK)
+
+    listen_for_events(sigfdr, p, NS.timeout)
+
+    if p.returncode is None:
+        log.error("timeout expired: sending signal %d to command and myself", NS.signal)
+        if pgrp == 0:
+            os.kill(p.pid, NS.signal)
+        else:
+            os.killpg(pgrp, NS.signal)  # should kill me too
+        os.kill(os.getpid(), NS.signal)  # to exit abnormally with same signal
+        log.error("signal did not cause termination, sending myself SIGKILL")
+        os.kill(os.getpid(), signal.SIGKILL)  # failsafe
+    rc = p.returncode
+    log.debug("rc = %d", rc)
+    assert rc is not None
+    if rc < 0:
+        log.error("command terminated with signal %d: sending same signal to myself!", -rc)
+        os.kill(os.getpid(), -rc)  # kill myself with the same signal
+        log.error("signal did not cause termination, sending myself SIGKILL")
+        os.kill(os.getpid(), signal.SIGKILL)  # failsafe
+    else:
+        log.info("command exited with status %d: exiting normally with same code!", rc)
+        return rc
+
+
+def main():
     signal.signal(signal.SIGPIPE, signal.SIG_IGN)
     try:
         (sigfdr, sigfdw) = os.pipe2(os.O_NONBLOCK | os.O_CLOEXEC)
@@ -186,6 +235,7 @@ if __name__ == "__main__":
         default=signal.SIGKILL,
     )
     P.add_argument("--verbose", action="store_true", help="increase debugging")
+    P.add_argument("--reboot-on-exit0", dest='reboot', action="store_true", help="reboot command on exit 0")
     P.add_argument(
         "--setpgrp",
         action="store",
@@ -214,50 +264,10 @@ if __name__ == "__main__":
     logargs["datefmt"] = "%Y-%m-%dT%H:%M:%S"
     logging.basicConfig(**logargs)
 
-    cargs = NS.cmd + NS.args
-    popen_kwargs = {
-        "stdin": subprocess.PIPE,
-    }
-
-    if NS.setpgrp == "self":
-        pgrp = os.getpgrp()
-        if pgrp != os.getpid():
-            os.setpgrp()
-            pgrp = os.getpgrp()
-    elif NS.setpgrp == "child":
-        popen_kwargs["preexec_fn"] = os.setpgrp
-        pgrp = None
-    elif NS.setpgrp == "no":
-        pgrp = 0
-    else:
-        assert False
-
-    log.debug("executing %s", cargs)
-    p = subprocess.Popen(cargs, **popen_kwargs)
-    if pgrp is None:
-        pgrp = p.pid
-    flags = fcntl.fcntl(p.stdin.fileno(), fcntl.F_GETFL)
-    fcntl.fcntl(p.stdin.fileno(), fcntl.F_SETFL, flags | os.O_NONBLOCK)
-
-    listen_for_events(sigfdr, p, NS.timeout)
+    while True:
+        rc = do_exec(NS)
+        if rc != 0 or not NS.reboot:
+            sys.exit(rc)
 
-    if p.returncode is None:
-        log.error("timeout expired: sending signal %d to command and myself", NS.signal)
-        if pgrp == 0:
-            os.kill(p.pid, NS.signal)
-        else:
-            os.killpg(pgrp, NS.signal)  # should kill me too
-        os.kill(os.getpid(), NS.signal)  # to exit abnormally with same signal
-        log.error("signal did not cause termination, sending myself SIGKILL")
-        os.kill(os.getpid(), signal.SIGKILL)  # failsafe
-    rc = p.returncode
-    log.debug("rc = %d", rc)
-    assert rc is not None
-    if rc < 0:
-        log.error("command terminated with signal %d: sending same signal to myself!", -rc)
-        os.kill(os.getpid(), -rc)  # kill myself with the same signal
-        log.error("signal did not cause termination, sending myself SIGKILL")
-        os.kill(os.getpid(), signal.SIGKILL)  # failsafe
-    else:
-        log.info("command exited with status %d: exiting normally with same code!", rc)
-        sys.exit(rc)
+if __name__ == "__main__":
+    main()