diff options
Diffstat (limited to 'lib/ansible/modules/service.py')
-rw-r--r-- | lib/ansible/modules/service.py | 125 |
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): |