Consolidate systemd detection logic (#81809)

* Add logic to consider the canary location for systemd files

Fixes: #80975

Signed-off-by: Abhijeet Kasurde <akasurde@redhat.com>
pull/82078/head
Abhijeet Kasurde 2 years ago committed by GitHub
parent bf29458726
commit e8ef6b7d7c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -0,0 +1,3 @@
---
bugfixes:
- Consolidate systemd detection logic into one place (https://github.com/ansible/ansible/issues/80975).

@ -110,8 +110,8 @@ def fail_if_missing(module, found, service, msg=''):
This function will return an error or exit gracefully depending on check mode status This function will return an error or exit gracefully depending on check mode status
and if the service is missing or not. and if the service is missing or not.
:arg module: is an AnsibleModule object, used for it's utility methods :arg module: is an AnsibleModule object, used for it's utility methods
:arg found: boolean indicating if services was found or not :arg found: boolean indicating if services were found or not
:arg service: name of service :arg service: name of service
:kw msg: extra info to append to error/success msg when missing :kw msg: extra info to append to error/success msg when missing
''' '''
@ -165,7 +165,7 @@ def daemonize(module, cmd):
''' '''
Execute a command while detaching as a daemon, returns rc, stdout, and stderr. Execute a command while detaching as a daemon, returns rc, stdout, and stderr.
:arg module: is an AnsibleModule object, used for it's utility methods :arg module: is an AnsibleModule object, used for it's utility methods
:arg cmd: is a list or string representing the command and options to run :arg cmd: is a list or string representing the command and options to run
This is complex because daemonization is hard for people. This is complex because daemonization is hard for people.
@ -274,3 +274,30 @@ def check_ps(module, pattern):
if pattern in line: if pattern in line:
return True return True
return False return False
def is_systemd_managed(module):
"""
Find out if the machine supports systemd or not
:arg module: is an AnsibleModule object, used for it's utility methods
Returns True if the system supports systemd, False if not.
"""
# tools must be installed
if module.get_bin_path('systemctl'):
# This should show if systemd is the boot init system, if checking init failed to mark as systemd
# these mirror systemd's own sd_boot test http://www.freedesktop.org/software/systemd/man/sd_booted.html
for canary in ["/run/systemd/system/", "/dev/.run/systemd/", "/dev/.systemd/"]:
if os.path.exists(canary):
return True
# If all else fails, check if init is the systemd command, using comm as cmdline could be symlink
try:
with open('/proc/1/comm', 'r') as init_proc:
init = init_proc.readline().strip()
return init == 'systemd'
except IOError:
# If comm doesn't exist, old kernel, no systemd
return False
return False

@ -179,7 +179,7 @@ from ansible.module_utils.common.text.converters import to_bytes, to_text
from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.common.locale import get_best_parsable_locale from ansible.module_utils.common.locale import get_best_parsable_locale
from ansible.module_utils.common.sys_info import get_platform_subclass from ansible.module_utils.common.sys_info import get_platform_subclass
from ansible.module_utils.service import fail_if_missing from ansible.module_utils.service import fail_if_missing, is_systemd_managed
from ansible.module_utils.six import PY2, b from ansible.module_utils.six import PY2, b
@ -484,24 +484,7 @@ class LinuxService(Service):
# tools must be installed # tools must be installed
if location.get('systemctl', False): if location.get('systemctl', False):
return is_systemd_managed(self.module)
# this should show if systemd is the boot init system
# these mirror systemd's own sd_boot test http://www.freedesktop.org/software/systemd/man/sd_booted.html
for canary in ["/run/systemd/system/", "/dev/.run/systemd/", "/dev/.systemd/"]:
if os.path.exists(canary):
return True
# If all else fails, check if init is the systemd command, using comm as cmdline could be symlink
try:
f = open('/proc/1/comm', 'r')
except IOError:
# If comm doesn't exist, old kernel, no systemd
return False
for line in f:
if 'systemd' in line:
return True
return False return False
# Locate a tool to enable/disable a service # Locate a tool to enable/disable a service

@ -94,6 +94,7 @@ import platform
import re import re
from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.common.locale import get_best_parsable_locale from ansible.module_utils.common.locale import get_best_parsable_locale
from ansible.module_utils.service import is_systemd_managed
class BaseService(object): class BaseService(object):
@ -244,16 +245,7 @@ class SystemctlScanService(BaseService):
BAD_STATES = frozenset(['not-found', 'masked', 'failed']) BAD_STATES = frozenset(['not-found', 'masked', 'failed'])
def systemd_enabled(self): def systemd_enabled(self):
# Check if init is the systemd command, using comm as cmdline could be symlink return is_systemd_managed(self.module)
try:
f = open('/proc/1/comm', 'r')
except IOError:
# If comm doesn't exist, old kernel, no systemd
return False
for line in f:
if 'systemd' in line:
return True
return False
def _list_from_units(self, systemctl_path, services): def _list_from_units(self, systemctl_path, services):

Loading…
Cancel
Save