nosh system module: fixes and improvements (#32014)
* nosh system module: fixes and improvements documentation: * fleshed out and fixed to better follow the official guidelines consistency: * the following facts will now always be returned on success: name, service_path, enabled, preset, user, status * state is only returned when the state option is used * state and status will be null if the service is not loaded by the end of the task * [nosh]: PEP8 fix
This commit is contained in:
parent
465fe5802b
commit
4ffd60a406
1 changed files with 76 additions and 39 deletions
|
@ -18,9 +18,10 @@ module: nosh
|
||||||
author:
|
author:
|
||||||
- "Thomas Caravia"
|
- "Thomas Caravia"
|
||||||
version_added: "2.5"
|
version_added: "2.5"
|
||||||
short_description: Manage services with nosh.
|
short_description: Manage services with nosh
|
||||||
description:
|
description:
|
||||||
- Controls services on remote hosts using the nosh toolset.
|
- Control running and enabled state for system-wide or user services.
|
||||||
|
- BSD and Linux systems are supported.
|
||||||
options:
|
options:
|
||||||
name:
|
name:
|
||||||
required: true
|
required: true
|
||||||
|
@ -30,7 +31,7 @@ options:
|
||||||
required: false
|
required: false
|
||||||
choices: [ started, stopped, reset, restarted, reloaded ]
|
choices: [ started, stopped, reset, restarted, reloaded ]
|
||||||
description:
|
description:
|
||||||
- C(Started)/C(stopped) are idempotent actions that will not run
|
- C(started)/C(stopped) are idempotent actions that will not run
|
||||||
commands unless necessary.
|
commands unless necessary.
|
||||||
C(restarted) will always bounce the service.
|
C(restarted) will always bounce the service.
|
||||||
C(reloaded) will send a SIGHUP or start the service.
|
C(reloaded) will send a SIGHUP or start the service.
|
||||||
|
@ -40,24 +41,27 @@ options:
|
||||||
required: false
|
required: false
|
||||||
choices: [ "yes", "no" ]
|
choices: [ "yes", "no" ]
|
||||||
description:
|
description:
|
||||||
- Whether the service is enabled or not, independently of *.preset file
|
- Enable or disable the service, independently of C(*.preset) file
|
||||||
preference or running state. Mutually exclusive with C(preset). Will take
|
preference or running state. Mutually exclusive with I(preset). Will take
|
||||||
effect prior to the C(reset) state.
|
effect prior to I(state=reset).
|
||||||
preset:
|
preset:
|
||||||
required: false
|
required: false
|
||||||
choices: [ "yes", "no" ]
|
choices: [ "yes", "no" ]
|
||||||
default: no
|
|
||||||
description:
|
description:
|
||||||
- Enable or disable the service according to local preferences in *.preset files.
|
- Enable or disable the service according to local preferences in *.preset files.
|
||||||
Mutually exclusive with C(enabled). Only has an effect if set to true. Will take
|
Mutually exclusive with I(enabled). Only has an effect if set to true. Will take
|
||||||
effect prior to the C(reset) state.
|
effect prior to I(state=reset).
|
||||||
user:
|
user:
|
||||||
required: false
|
required: false
|
||||||
default: no
|
default: 'no'
|
||||||
choices: [ "yes", "no" ]
|
choices: [ "yes", "no" ]
|
||||||
description:
|
description:
|
||||||
- Run system-control talking to the service manager of the calling user, rather than
|
- Run system-control talking to the calling user's service manager, rather than
|
||||||
the service manager of the system.
|
the system-wide service manager.
|
||||||
|
requirements:
|
||||||
|
- A system with an active nosh service manager, see Notes for further information.
|
||||||
|
notes:
|
||||||
|
- Information on the nosh utilities suite may be found at U(https://jdebp.eu/Softwares/nosh/).
|
||||||
'''
|
'''
|
||||||
|
|
||||||
EXAMPLES = '''
|
EXAMPLES = '''
|
||||||
|
@ -83,8 +87,22 @@ EXAMPLES = '''
|
||||||
- name: for package installers, set nginx running state according to local enable settings, preset and reset
|
- name: for package installers, set nginx running state according to local enable settings, preset and reset
|
||||||
nosh: name=nginx preset=True state=reset
|
nosh: name=nginx preset=True state=reset
|
||||||
|
|
||||||
- name: reboot the host if nosh is the system manager, would need a "wait_for*" step at least, not recommended as-is
|
- name: reboot the host if nosh is the system manager, would need a "wait_for*" task at least, not recommended as-is
|
||||||
nosh: name=reboot state=started
|
nosh: name=reboot state=started
|
||||||
|
|
||||||
|
- name: using conditionals with the module facts
|
||||||
|
tasks:
|
||||||
|
- name: obtain information on tinydns service
|
||||||
|
nosh: name=tinydns
|
||||||
|
register: result
|
||||||
|
|
||||||
|
- name: fail if service not loaded
|
||||||
|
fail: msg="The {{ result.name }} service is not loaded"
|
||||||
|
when: not result.status
|
||||||
|
|
||||||
|
- name: fail if service is running
|
||||||
|
fail: msg="The {{ result.name }} service is running"
|
||||||
|
when: result.status and result.status['DaemontoolsEncoreState'] == "running"
|
||||||
'''
|
'''
|
||||||
|
|
||||||
RETURN = '''
|
RETURN = '''
|
||||||
|
@ -98,8 +116,23 @@ service_path:
|
||||||
returned: success
|
returned: success
|
||||||
type: string
|
type: string
|
||||||
sample: "/var/sv/sshd"
|
sample: "/var/sv/sshd"
|
||||||
|
enabled:
|
||||||
|
description: whether the service is enabled at system bootstrap
|
||||||
|
returned: success
|
||||||
|
type: boolean
|
||||||
|
sample: True
|
||||||
|
preset:
|
||||||
|
description: whether the enabled status reflects the one set in the relevant C(*.preset) file
|
||||||
|
returned: success
|
||||||
|
type: boolean
|
||||||
|
sample: False
|
||||||
|
state:
|
||||||
|
description: service process run state, C(None) if the service is not loaded and will not be started
|
||||||
|
returned: if state option is used
|
||||||
|
type: string
|
||||||
|
sample: "reloaded"
|
||||||
status:
|
status:
|
||||||
description: a dictionary with the key=value pairs returned by `system-control show-json SERVICE` or Loaded=False if the service is not loaded
|
description: a dictionary with the key=value pairs returned by `system-control show-json` or C(None) if the service is not loaded
|
||||||
returned: success
|
returned: success
|
||||||
type: complex
|
type: complex
|
||||||
contains: {
|
contains: {
|
||||||
|
@ -152,6 +185,11 @@ status:
|
||||||
"../sshdgenkeys"
|
"../sshdgenkeys"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
user:
|
||||||
|
description: whether the user-level service manager is called
|
||||||
|
returned: success
|
||||||
|
type: boolean
|
||||||
|
sample: False
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
|
@ -217,14 +255,14 @@ def handle_enabled(module, result, service_path):
|
||||||
These options are set to "mutually exclusive" but the explicit 'enabled' option will
|
These options are set to "mutually exclusive" but the explicit 'enabled' option will
|
||||||
have priority if the check is bypassed.
|
have priority if the check is bypassed.
|
||||||
"""
|
"""
|
||||||
enabled = service_is_enabled(module, service_path)
|
|
||||||
|
# computed prior in control flow
|
||||||
|
preset = result['preset']
|
||||||
|
enabled = result['enabled']
|
||||||
|
|
||||||
# preset, effect only if option set to true (no reverse preset)
|
# preset, effect only if option set to true (no reverse preset)
|
||||||
if module.params['preset']:
|
if module.params['preset']:
|
||||||
action = 'preset'
|
action = 'preset'
|
||||||
preset = enabled is service_is_preset_enabled(module, service_path)
|
|
||||||
result['preset'] = preset
|
|
||||||
result['enabled'] = enabled
|
|
||||||
|
|
||||||
# run preset if needed
|
# run preset if needed
|
||||||
if preset != module.params['preset']:
|
if preset != module.params['preset']:
|
||||||
|
@ -243,8 +281,6 @@ def handle_enabled(module, result, service_path):
|
||||||
else:
|
else:
|
||||||
action = 'disable'
|
action = 'disable'
|
||||||
|
|
||||||
result['enabled'] = enabled
|
|
||||||
|
|
||||||
# change enable/disable if needed
|
# change enable/disable if needed
|
||||||
if enabled != module.params['enabled']:
|
if enabled != module.params['enabled']:
|
||||||
result['changed'] = True
|
result['changed'] = True
|
||||||
|
@ -253,6 +289,7 @@ def handle_enabled(module, result, service_path):
|
||||||
if rc != 0:
|
if rc != 0:
|
||||||
module.fail_json(msg="Unable to %s service %s: %s" % (action, service_path, out + err))
|
module.fail_json(msg="Unable to %s service %s: %s" % (action, service_path, out + err))
|
||||||
result['enabled'] = not enabled
|
result['enabled'] = not enabled
|
||||||
|
result['preset'] = not preset
|
||||||
|
|
||||||
|
|
||||||
def handle_state(module, result, service_path):
|
def handle_state(module, result, service_path):
|
||||||
|
@ -264,28 +301,25 @@ def handle_state(module, result, service_path):
|
||||||
"""
|
"""
|
||||||
# default to desired state, no action
|
# default to desired state, no action
|
||||||
result['state'] = module.params['state']
|
result['state'] = module.params['state']
|
||||||
|
state = module.params['state']
|
||||||
action = None
|
action = None
|
||||||
|
|
||||||
# case for enabled/preset + reset + check_mode: use anticipated enabled status
|
# computed prior in control flow, possibly modified by handle_enabled()
|
||||||
# otherwise test real enabled status
|
enabled = result['enabled']
|
||||||
if module.check_mode and (module.params['enabled'] is not None or module.params['preset']):
|
|
||||||
enabled = result['enabled']
|
|
||||||
else:
|
|
||||||
enabled = service_is_enabled(module, service_path)
|
|
||||||
|
|
||||||
# service not loaded -> not started by manager, no status information
|
# service not loaded -> not started by manager, no status information
|
||||||
if not service_is_loaded(module, service_path):
|
if not service_is_loaded(module, service_path):
|
||||||
if module.params['state'] in ['started', 'restarted', 'reloaded']:
|
if state in ['started', 'restarted', 'reloaded']:
|
||||||
action = 'start'
|
action = 'start'
|
||||||
result['state'] = 'started'
|
result['state'] = 'started'
|
||||||
elif module.params['state'] == 'reset':
|
elif state == 'reset':
|
||||||
if enabled:
|
if enabled:
|
||||||
action = 'start'
|
action = 'start'
|
||||||
result['state'] = 'started'
|
result['state'] = 'started'
|
||||||
else:
|
else:
|
||||||
result['state'] = 'stopped'
|
result['state'] = None
|
||||||
else:
|
else:
|
||||||
result['state'] = 'stopped'
|
result['state'] = None
|
||||||
|
|
||||||
# service is loaded
|
# service is loaded
|
||||||
else:
|
else:
|
||||||
|
@ -293,14 +327,14 @@ def handle_state(module, result, service_path):
|
||||||
result['status'] = get_service_status(module, service_path)
|
result['status'] = get_service_status(module, service_path)
|
||||||
running = service_is_running(result['status'])
|
running = service_is_running(result['status'])
|
||||||
|
|
||||||
if module.params['state'] == 'started':
|
if state == 'started':
|
||||||
if not running:
|
if not running:
|
||||||
action = 'start'
|
action = 'start'
|
||||||
elif module.params['state'] == 'stopped':
|
elif state == 'stopped':
|
||||||
if running:
|
if running:
|
||||||
action = 'stop'
|
action = 'stop'
|
||||||
# reset = start/stop according to enabled status
|
# reset = start/stop according to enabled status
|
||||||
elif module.params['state'] == 'reset':
|
elif state == 'reset':
|
||||||
if enabled is not running:
|
if enabled is not running:
|
||||||
if running:
|
if running:
|
||||||
action = 'stop'
|
action = 'stop'
|
||||||
|
@ -309,14 +343,14 @@ def handle_state(module, result, service_path):
|
||||||
action = 'start'
|
action = 'start'
|
||||||
result['state'] = 'started'
|
result['state'] = 'started'
|
||||||
# start if not running, 'service' module constraint
|
# start if not running, 'service' module constraint
|
||||||
elif module.params['state'] == 'restarted':
|
elif state == 'restarted':
|
||||||
if not running:
|
if not running:
|
||||||
action = 'start'
|
action = 'start'
|
||||||
result['state'] = 'started'
|
result['state'] = 'started'
|
||||||
else:
|
else:
|
||||||
action = 'condrestart'
|
action = 'condrestart'
|
||||||
# start if not running, 'service' module constraint
|
# start if not running, 'service' module constraint
|
||||||
elif module.params['state'] == 'reloaded':
|
elif state == 'reloaded':
|
||||||
if not running:
|
if not running:
|
||||||
action = 'start'
|
action = 'start'
|
||||||
result['state'] = 'started'
|
result['state'] = 'started'
|
||||||
|
@ -342,7 +376,7 @@ def main():
|
||||||
state=dict(choices=['started', 'stopped', 'reset', 'restarted', 'reloaded'], type='str'),
|
state=dict(choices=['started', 'stopped', 'reset', 'restarted', 'reloaded'], type='str'),
|
||||||
enabled=dict(type='bool'),
|
enabled=dict(type='bool'),
|
||||||
preset=dict(type='bool'),
|
preset=dict(type='bool'),
|
||||||
user=dict(type='bool'),
|
user=dict(type='bool', default=False),
|
||||||
),
|
),
|
||||||
supports_check_mode=True,
|
supports_check_mode=True,
|
||||||
mutually_exclusive=[['enabled', 'preset']],
|
mutually_exclusive=[['enabled', 'preset']],
|
||||||
|
@ -354,12 +388,17 @@ def main():
|
||||||
result = {
|
result = {
|
||||||
'name': service,
|
'name': service,
|
||||||
'changed': False,
|
'changed': False,
|
||||||
'status': {},
|
'status': None,
|
||||||
}
|
}
|
||||||
|
|
||||||
# check service can be found (or fail) and get path
|
# check service can be found (or fail) and get path
|
||||||
service_path = get_service_path(module, service)
|
service_path = get_service_path(module, service)
|
||||||
|
|
||||||
|
# get preliminary service facts
|
||||||
result['service_path'] = service_path
|
result['service_path'] = service_path
|
||||||
|
result['user'] = module.params['user']
|
||||||
|
result['enabled'] = service_is_enabled(module, service_path)
|
||||||
|
result['preset'] = result['enabled'] is service_is_preset_enabled(module, service_path)
|
||||||
|
|
||||||
# set enabled state, service need not be loaded
|
# set enabled state, service need not be loaded
|
||||||
if module.params['enabled'] is not None or module.params['preset']:
|
if module.params['enabled'] is not None or module.params['preset']:
|
||||||
|
@ -372,8 +411,6 @@ def main():
|
||||||
# get final service status if possible
|
# get final service status if possible
|
||||||
if service_is_loaded(module, service_path):
|
if service_is_loaded(module, service_path):
|
||||||
result['status'] = get_service_status(module, service_path)
|
result['status'] = get_service_status(module, service_path)
|
||||||
else:
|
|
||||||
result['status'] = {'Loaded': False}
|
|
||||||
|
|
||||||
module.exit_json(**result)
|
module.exit_json(**result)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue