summaryrefslogtreecommitdiff
path: root/lib/ansible/modules/service.py
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ansible/modules/service.py')
-rw-r--r--lib/ansible/modules/service.py125
1 files changed, 98 insertions, 27 deletions
diff --git a/lib/ansible/modules/service.py b/lib/ansible/modules/service.py
index b562f53d..a84829c9 100644
--- a/lib/ansible/modules/service.py
+++ b/lib/ansible/modules/service.py
@@ -21,8 +21,8 @@ description:
- This module is a proxy for multiple more specific service manager modules
(such as M(ansible.builtin.systemd) and M(ansible.builtin.sysvinit)).
This allows management of a heterogeneous environment of machines without creating a specific task for
- each service manager. The module to be executed is determined by the O(use) option, which defaults to the
- service manager discovered by M(ansible.builtin.setup). If M(ansible.builtin.setup) was not yet run, this module may run it.
+ each service manager. The module to be executed is determined by the I(use) option, which defaults to the
+ service manager discovered by M(ansible.builtin.setup). If C(setup) was not yet run, this module may run it.
- For Windows targets, use the M(ansible.windows.win_service) module instead.
options:
name:
@@ -32,10 +32,10 @@ options:
required: true
state:
description:
- - V(started)/V(stopped) are idempotent actions that will not run
+ - C(started)/C(stopped) are idempotent actions that will not run
commands unless necessary.
- - V(restarted) will always bounce the service.
- - V(reloaded) will always reload.
+ - C(restarted) will always bounce the service.
+ - C(reloaded) will always reload.
- B(At least one of state and enabled are required.)
- Note that reloaded will start the service if it is not already started,
even if your chosen init system wouldn't normally.
@@ -43,7 +43,7 @@ options:
choices: [ reloaded, restarted, started, stopped ]
sleep:
description:
- - If the service is being V(restarted) then sleep this many seconds
+ - If the service is being C(restarted) then sleep this many seconds
between the stop and start command.
- This helps to work around badly-behaving init scripts that exit immediately
after signaling a process to stop.
@@ -76,13 +76,11 @@ options:
- Additional arguments provided on the command line.
- While using remote hosts with systemd this setting will be ignored.
type: str
- default: ''
aliases: [ args ]
use:
description:
- The service module actually uses system specific modules, normally through auto detection, this setting can force a specific module.
- Normally it uses the value of the 'ansible_service_mgr' fact and falls back to the old 'service' module when none matching is found.
- - The 'old service module' still uses autodetection and in no way does it correspond to the C(service) command.
type: str
default: auto
version_added: 2.2
@@ -107,9 +105,6 @@ attributes:
platforms: all
notes:
- For AIX, group subsystem names can be used.
- - The C(service) command line utility is not part of any service manager system but a convenience.
- It does not have a standard implementation across systems, and this action cannot use it directly.
- Though it might be used if found in certain circumstances, the detected system service manager is normally preferred.
seealso:
- module: ansible.windows.win_service
author:
@@ -176,7 +171,7 @@ import time
if platform.system() != 'SunOS':
from ansible.module_utils.compat.version import LooseVersion
-from ansible.module_utils.common.text.converters import to_bytes, to_text
+from ansible.module_utils._text import to_bytes, to_text
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.common.locale import get_best_parsable_locale
from ansible.module_utils.common.sys_info import get_platform_subclass
@@ -1195,31 +1190,107 @@ class OpenBsdService(Service):
return self.execute_command("%s -f %s" % (self.svc_cmd, self.action))
def service_enable(self):
-
if not self.enable_cmd:
return super(OpenBsdService, self).service_enable()
+ rc, stdout, stderr = self.execute_command("%s %s %s %s" % (self.enable_cmd, 'getdef', self.name, 'flags'))
+
+ if stderr:
+ self.module.fail_json(msg=stderr)
+
+ getdef_string = stdout.rstrip()
+
+ # Depending on the service the string returned from 'getdef' may be
+ # either a set of flags or the boolean YES/NO
+ if getdef_string == "YES" or getdef_string == "NO":
+ default_flags = ''
+ else:
+ default_flags = getdef_string
+
+ rc, stdout, stderr = self.execute_command("%s %s %s %s" % (self.enable_cmd, 'get', self.name, 'flags'))
+
+ if stderr:
+ self.module.fail_json(msg=stderr)
+
+ get_string = stdout.rstrip()
+
+ # Depending on the service the string returned from 'get' may be
+ # either a set of flags or the boolean YES/NO
+ if get_string == "YES" or get_string == "NO":
+ current_flags = ''
+ else:
+ current_flags = get_string
+
+ # If there are arguments from the user we use these as flags unless
+ # they are already set.
+ if self.arguments and self.arguments != current_flags:
+ changed_flags = self.arguments
+ # If the user has not supplied any arguments and the current flags
+ # differ from the default we reset them.
+ elif not self.arguments and current_flags != default_flags:
+ changed_flags = ' '
+ # Otherwise there is no need to modify flags.
+ else:
+ changed_flags = ''
+
rc, stdout, stderr = self.execute_command("%s %s %s %s" % (self.enable_cmd, 'get', self.name, 'status'))
- status_action = None
if self.enable:
+ if rc == 0 and not changed_flags:
+ return
+
if rc != 0:
- status_action = "on"
- elif self.enable is not None:
- # should be explicit False at this point
- if rc != 1:
- status_action = "off"
+ status_action = "set %s status on" % (self.name)
+ else:
+ status_action = ''
+ if changed_flags:
+ flags_action = "set %s flags %s" % (self.name, changed_flags)
+ else:
+ flags_action = ''
+ else:
+ if rc == 1:
+ return
- if status_action is not None:
- self.changed = True
- if not self.module.check_mode:
- rc, stdout, stderr = self.execute_command("%s set %s status %s" % (self.enable_cmd, self.name, status_action))
+ status_action = "set %s status off" % self.name
+ flags_action = ''
- if rc != 0:
- if stderr:
- self.module.fail_json(msg=stderr)
+ # Verify state assumption
+ if not status_action and not flags_action:
+ self.module.fail_json(msg="neither status_action or status_flags is set, this should never happen")
+
+ if self.module.check_mode:
+ self.module.exit_json(changed=True, msg="changing service enablement")
+
+ status_modified = 0
+ if status_action:
+ rc, stdout, stderr = self.execute_command("%s %s" % (self.enable_cmd, status_action))
+
+ if rc != 0:
+ if stderr:
+ self.module.fail_json(msg=stderr)
+ else:
+ self.module.fail_json(msg="rcctl failed to modify service status")
+
+ status_modified = 1
+
+ if flags_action:
+ rc, stdout, stderr = self.execute_command("%s %s" % (self.enable_cmd, flags_action))
+
+ if rc != 0:
+ if stderr:
+ if status_modified:
+ error_message = "rcctl modified service status but failed to set flags: " + stderr
else:
- self.module.fail_json(msg="rcctl failed to modify service status")
+ error_message = stderr
+ else:
+ if status_modified:
+ error_message = "rcctl modified service status but failed to set flags"
+ else:
+ error_message = "rcctl failed to modify service flags"
+
+ self.module.fail_json(msg=error_message)
+
+ self.changed = True
class NetBsdService(Service):