From 6834a79fd9bd2626f3ff1cd0581d4a58faba860e Mon Sep 17 00:00:00 2001 From: Michal Sekletar Date: Thu, 12 Jan 2017 10:47:36 +0100 Subject: [PATCH] service: introduce xinetd support This commit effectively implements a fallback on systemd based systems. xinetd based service can be enabled via chkconfig. On RHEL6 all is fine and enabled=yes should work for xinetd based services. However on RHEL7 service module detects systemd and uses systemctl as a management tool. systemctl enable would fail for xinetd based service even though chkconfig supports xinetd. Hence we check for this scenario (no native service present, no initscript of the same name present and xinetd service is available) beforehand and revert to service/chkconfig even when systemd is used as a init system. --- system/service.py | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/system/service.py b/system/service.py index af97e7d..2c79bbe 100644 --- a/system/service.py +++ b/system/service.py @@ -131,6 +131,7 @@ import select import time import string import glob +import dbus from ansible.module_utils.service import fail_if_missing # The distutils module is not shipped with SUNWPython on Solaris. @@ -449,6 +450,63 @@ class LinuxService(Service): return False + def systemd_get_manager(bus): + try: + systemd = bus.get_object('org.freedesktop.systemd1', '/org/freedesktop/systemd1') + systemd_manager = dbus.Interface(systemd, 'org.freedesktop.systemd1.Manager') + + return systemd_manager + except: + return None + + def get_systemd_unit_file_name(): + unit_name_max = 256 + unit_suffixes = [ "service", "socket", "busname", "target", "device", "mount", "automount", "swap", "timer", "path", "slice", "scope" ] + + unit_file = "" + suffix = "" + + if not _self.__systemd_unit: + return (unit_file, suffix) + + if len(_self.__systemd_unit) >= unit_name_max: + return (unit_file, suffix) + + suffix = self.__systemd_unit.rpartition(".")[2] + if suffix == self.__systemd_unit: + suffix = "service" + + try: + unit_suffixes.index(suffix) + if not self.__systemd_unit.endswith(suffix): + unit_file = self.__systemd_unit + "." + suffix + else: + unit_file = self.__systemd_unit + except: + suffix = "" + + return (unit_file, suffix) + + # If we can get unit file state we assume it exists + def systemd_unit_file_exists(): + unit_file, type = get_systemd_unit_file_name() + + if not type: + return False + + bus = dbus.SystemBus() + manager = systemd_get_manager(bus) + + if not manager: + return False + + try: + state = manager.GetUnitFileState(unit_file) + except: + state = "not-found" + + return state == "enabled" or state == "disabled" or state == "static" + # Locate a tool to enable/disable a service if check_systemd(): # service is managed by systemd @@ -456,6 +514,20 @@ class LinuxService(Service): self.svc_cmd = location['systemctl'] self.enable_cmd = location['systemctl'] + # If systemd unit file corresponding to service name doesn't exist and neither initscript exists + # then this is most likely xinetd service or it doesn't exist at all + if (not systemd_unit_file_exists() and + not sysv_exists(self.name) and + os.path.exists("/etc/xinetd.d/%s.conf" % self.name)): + + distribution = platform.linux_distribution()[0] + + if ((distribution.startswith("Red Hat Enterprise Linux") or + distribution.startswith("Fedora") or + distribution.startswith("CentOS")) and + (location.get('service', False) and location.get('chkconfig', False))): + self.svc_cmd = location['service'] + self.enable_cmd = location['chkconfig'] elif location.get('initctl', False) and os.path.exists("/etc/init/%s.conf" % self.name): # service is managed by upstart self.enable_cmd = location['initctl'] -- 2.9.3