diff --git a/testinfra/modules/service.py b/testinfra/modules/service.py index 830d066d..592558b5 100644 --- a/testinfra/modules/service.py +++ b/testinfra/modules/service.py @@ -143,6 +143,32 @@ def is_enabled(self): class SystemdService(SysvService): + suffix_list = [ + "service", + "socket", + "device", + "mount", + "automount", + "swap", + "target", + "path", + "timer", + "slice", + "scope", + ] + """ + List of valid suffixes for systemd unit files + + See systemd.unit(5) for more details + """ + + def _has_systemd_suffix(self): + """ + Check if service name has a known systemd unit suffix + """ + unit_suffix = self.name.split(".")[-1] + return unit_suffix in self.suffix_list + @property def is_running(self): out = self.run_expect([0, 1, 3], "systemctl is-active %s", self.name) @@ -158,14 +184,20 @@ def is_enabled(self): return True if cmd.stdout.strip() == "disabled": return False - # Fallback on SysV + # Fallback on SysV - only for non-systemd units # https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=760616 - return super().is_enabled + if not self._has_systemd_suffix(): + return super().is_enabled + raise RuntimeError( + "Unable to determine state of {0}. Does this service exist?".format( + self.name + ) + ) @property def is_valid(self): - # systemd-analyze requires a full path. - if self.name.endswith(".service"): + # systemd-analyze requires a full unit name. + if self._has_systemd_suffix(): name = self.name else: name = self.name + ".service" @@ -264,9 +296,7 @@ def is_enabled(self): if self.name in self.check_output("rcctl ls off").splitlines(): return False raise RuntimeError( - "Unable to determine state of {0}. Does this service exist?".format( - self.name - ) + f"Unable to determine state of {self.name}. Does this service exist?" )