diff mbox series

[v2,3/3] prserv: add --status to list running servers

Message ID 20260915160633.7-4-bbnpreetsingh@gmail.com
State New
Headers show
Series prserv: add --status, and make --start notice a dead server | expand

Commit Message

Babanpreet Singh Sept. 15, 2026, 4:06 p.m. UTC
Add `prserv --status` to report running servers and stale pidfiles, with lifecycle tests for both running and stopped states.

[YOCTO #10865]

AI-Generated: Uses Claude (claude-fable-5-1)
Signed-off-by: Babanpreet Singh <bbnpreetsingh@gmail.com>
---
 bin/bitbake-prserv  |  7 +++++++
 lib/prserv/serv.py  | 23 +++++++++++++++++++++++
 lib/prserv/tests.py | 18 +++++++++++++++++-
 3 files changed, 47 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/bin/bitbake-prserv b/bin/bitbake-prserv
index e666fef06..5775f47fb 100755
--- a/bin/bitbake-prserv
+++ b/bin/bitbake-prserv
@@ -64,6 +64,11 @@  def main():
         action="store_true",
         help="stop daemon",
     )
+    parser.add_argument(
+        "--status",
+        action="store_true",
+        help="list PR servers running on this machine",
+    )
     parser.add_argument(
         "--host",
         help="ip address to bind",
@@ -102,6 +107,8 @@  def main():
         )
     elif args.stop:
         ret=prserv.serv.stop_daemon(args.host, args.port)
+    elif args.status:
+        ret=prserv.serv.status_daemon()
     else:
         ret=parser.print_help()
     return ret
diff --git a/lib/prserv/serv.py b/lib/prserv/serv.py
index 6aba1c3e0..a49faeb4a 100644
--- a/lib/prserv/serv.py
+++ b/lib/prserv/serv.py
@@ -427,6 +427,29 @@  def stop_daemon(host, port):
 
     return 0
 
+def status_daemon():
+    import glob
+    running = 0
+    for pidfile in sorted(glob.glob(PIDPREFIX % ("*", "*"))):
+        root, _ = os.path.splitext(os.path.basename(pidfile))
+        parts = root.split("_")
+        ip, port = "_".join(parts[1:-1]), parts[-1]
+        try:
+            with open(pidfile) as pf:
+                pid = int(pf.readline().strip())
+        except (IOError, ValueError):
+            sys.stderr.write("Ignoring unreadable pidfile %s\n" % pidfile)
+            continue
+        if is_running(pid):
+            print("PRServer running at %s:%s (pid %s)" % (ip, port, pid))
+            running += 1
+        else:
+            print("Stale pidfile %s (pid %s not running)" % (pidfile, pid))
+    if not running:
+        print("No PRServer running.")
+        return 1
+    return 0
+
 def is_running(pid):
     try:
         os.kill(pid, 0)
diff --git a/lib/prserv/tests.py b/lib/prserv/tests.py
index f1e4f12c8..8b78e2496 100644
--- a/lib/prserv/tests.py
+++ b/lib/prserv/tests.py
@@ -403,8 +403,24 @@  class ScriptTests(unittest.TestCase):
         except subprocess.CalledProcessError as e:
             self.fail("Failed to start bitbake-prserv: %s" % e.returncode)
 
-    def test_2_stop_bitbake_prserv(self):
+    def test_2_status_bitbake_prserv(self):
+        result = subprocess.run([BIN_DIR / "bitbake-prserv", "--status"],
+                                capture_output=True, text=True)
+        self.assertEqual(result.returncode, 0,
+                         "Expected a running PRServer: %s" % result.stdout)
+        self.assertIn(":%s (pid " % self.port, result.stdout)
+
+    def test_3_stop_bitbake_prserv(self):
         try:
             subprocess.check_call([BIN_DIR / "bitbake-prserv", "--stop", "--port", self.port])
         except subprocess.CalledProcessError as e:
             self.fail("Failed to stop bitbake-prserv: %s" % e.returncode)
+
+    def test_4_status_stopped_bitbake_prserv(self):
+        result = subprocess.run([BIN_DIR / "bitbake-prserv", "--status"],
+                                capture_output=True, text=True)
+        self.assertNotIn(":%s (pid " % self.port, result.stdout)
+        # Servers unrelated to this test may be running on the machine
+        if "PRServer running at" not in result.stdout:
+            self.assertEqual(result.returncode, 1,
+                             "Expected no running PRServer: %s" % result.stdout)