Add tool to query state of system service next-update
authorChristian Herdtweck <christian.herdtweck@intra2net.com>
Thu, 25 Apr 2024 10:40:41 +0000 (12:40 +0200)
committerChristian Herdtweck <christian.herdtweck@intra2net.com>
Thu, 25 Apr 2024 10:40:41 +0000 (12:40 +0200)
I have written this or very similar code a few times, time to centralize
it.

src/sysmisc.py

index 79b8f85..3a2b0cd 100644 (file)
@@ -73,7 +73,6 @@ The library exports the symbols below and some custom logging functions.
 The logging functions either use the format capability or play
 the simple role of providing shorter names.
 """
-
 import re
 import subprocess
 import hashlib
@@ -83,6 +82,7 @@ import time
 import types
 import uuid
 from contextlib import contextmanager
+import enum
 import logging
 llog = logging.getLogger('pyi2ncommon.sysmisc')
 
@@ -239,6 +239,41 @@ def hash_file(fname, new=hashlib.sha512, bs=4096):
         return hsh.hexdigest()
 
 
+class ServiceState(enum.Enum):
+    """State of a system service, see `get_service_state`."""
+    RUNNING = 0
+    DEAD_WITH_PIDFILE = 1
+    DEAD_WITH_LOCKFILE = 2
+    STOPPED = 3
+    SERVICE_UNKNOWN = 4
+    OTHER = -1
+
+
+def get_service_state(service_name: str) -> ServiceState:
+    """
+    Get state of a system service.
+
+    Calls "service {service_name} status", since that works on older and newer systemd-based
+    installs, and tries to interpret return code as defined by the
+    "Linux Standard Base PDA Specification 3.0RC1", Chapter 8.2 ("Init Script Actions",
+    https://refspecs.linuxbase.org/LSB_3.0.0/LSB-PDA/LSB-PDA/iniscrptact.html ).
+    """
+    code = subprocess.run(["service", service_name, "status"],
+                          capture_output=True).returncode
+    if code == 0:
+        return ServiceState.RUNNING
+    elif code == 1:
+        return ServiceState.DEAD_WITH_PIDFILE
+    elif code == 2:
+        return ServiceState.DEAD_WITH_LOCKFILE
+    elif code == 3:
+        return ServiceState.STOPPED
+    elif code == 4:
+        return ServiceState.SERVICE_UNKNOWN
+    else:
+        return ServiceState.OTHER
+
+
 cheat_tpl = """\
 #!/bin/sh
 set -u