diff --git a/lib/ansible/modules/system/systemd.py b/lib/ansible/modules/system/systemd.py index 6b4bd780f8..aada2c3412 100644 --- a/lib/ansible/modules/system/systemd.py +++ b/lib/ansible/modules/system/systemd.py @@ -1,77 +1,66 @@ #!/usr/bin/python # -*- coding: utf-8 -*- -# (c) 2016, Brian Coca + +# Copyright: (c) 2016, Brian Coca # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) from __future__ import absolute_import, division, print_function __metaclass__ = type - ANSIBLE_METADATA = {'metadata_version': '1.1', 'status': ['stableinterface'], 'supported_by': 'core'} - DOCUMENTATION = ''' module: systemd author: - - "Ansible Core Team" + - Ansible Core Team version_added: "2.2" -short_description: Manage services. +short_description: Manage services description: - Controls systemd services on remote hosts. options: name: - required: false description: - Name of the service. When using in a chroot environment you always need to specify the full name i.e. (crond.service). - aliases: ['unit', 'service'] + aliases: [ service, unit ] state: - required: false - default: null - choices: [ 'started', 'stopped', 'restarted', 'reloaded' ] description: - C(started)/C(stopped) are idempotent actions that will not run commands unless necessary. C(restarted) will always bounce the service. C(reloaded) will always reload. + choices: [ reloaded, restarted, started, stopped ] enabled: - required: false - choices: [ "yes", "no" ] - default: null description: - Whether the service should start on boot. B(At least one of state and enabled are required.) + type: bool masked: - required: false - choices: [ "yes", "no" ] - default: null description: - Whether the unit should be masked or not, a masked unit is impossible to start. + type: bool daemon_reload: - required: false - default: no - choices: [ "yes", "no" ] description: - run daemon-reload before doing any other operations, to make sure systemd has read any changes. - aliases: ['daemon-reload'] + type: bool + default: 'no' + aliases: [ daemon-reload ] user: - required: false - default: no - choices: [ "yes", "no" ] description: - run systemctl talking to the service manager of the calling user, rather than the service manager of the system. + type: bool + default: 'no' no_block: - required: false - default: no - choices: [ "yes", "no" ] description: - Do not synchronously wait for the requested operation to finish. Enqueued job will continue without Ansible blocking on its completion. + type: bool + default: 'no' version_added: "2.3" notes: - Since 2.4, one of the following options is required 'state', 'enabled', 'masked', 'daemon_reload', and all except 'daemon_reload' also require 'name'. - Before 2.4 you always required 'name'. requirements: - - A system managed by systemd + - A system managed by systemd. ''' EXAMPLES = ''' @@ -246,9 +235,11 @@ from ansible.module_utils._text import to_native def is_running_service(service_status): return service_status['ActiveState'] in set(['active', 'activating']) + def request_was_ignored(out): return '=' not in out and 'ignoring request' in out + def parse_systemctl_show(lines): # The output of 'systemctl show' can contain values that span multiple lines. At first glance it # appears that such values are always surrounded by {}, so the previous version of this code @@ -290,18 +281,18 @@ def parse_systemctl_show(lines): def main(): # initialize module = AnsibleModule( - argument_spec = dict( - name = dict(aliases=['unit', 'service']), - state = dict(choices=[ 'started', 'stopped', 'restarted', 'reloaded'], type='str'), - enabled = dict(type='bool'), - masked = dict(type='bool'), - daemon_reload = dict(type='bool', default=False, aliases=['daemon-reload']), - user = dict(type='bool', default=False), - no_block = dict(type='bool', default=False), + argument_spec=dict( + name=dict(type='str', aliases=['service', 'unit']), + state=dict(type='str', choices=['reloaded,' 'restarted', 'started', 'stopped']), + enabled=dict(type='bool'), + masked=dict(type='bool'), + daemon_reload=dict(type='bool', default=False, aliases=['daemon-reload']), + user=dict(type='bool', default=False), + no_block=dict(type='bool', default=False), ), supports_check_mode=True, required_one_of=[['state', 'enabled', 'masked', 'daemon_reload']], - ) + ) systemctl = module.get_bin_path('systemctl', True) if module.params['user']: @@ -311,11 +302,11 @@ def main(): unit = module.params['name'] rc = 0 out = err = '' - result = { - 'name': unit, - 'changed': False, - 'status': {}, - } + result = dict( + name=unit, + changed=False, + status=dict(), + ) for requires in ('state', 'enabled', 'masked'): if module.params[requires] is not None and unit is None: @@ -379,7 +370,6 @@ def main(): # some versions of system CAN mask/unmask non existing services, we only fail on missing if they don't fail_if_missing(module, found, unit, msg='host') - # Enable/disable service startup at boot if requested if module.params['enabled'] is not None: @@ -438,7 +428,7 @@ def main(): if not is_running_service(result['status']): action = 'start' else: - action = module.params['state'][:-2] # remove 'ed' from restarted/reloaded + action = module.params['state'][:-2] # remove 'ed' from restarted/reloaded result['state'] = 'started' if action: @@ -451,8 +441,8 @@ def main(): # this should not happen? module.fail_json(msg="Service is in unknown state", status=result['status']) - module.exit_json(**result) + if __name__ == '__main__': main() diff --git a/test/sanity/pep8/legacy-files.txt b/test/sanity/pep8/legacy-files.txt index ae2fc08cee..5ea08683b4 100644 --- a/test/sanity/pep8/legacy-files.txt +++ b/test/sanity/pep8/legacy-files.txt @@ -360,7 +360,6 @@ lib/ansible/modules/system/runit.py lib/ansible/modules/system/seport.py lib/ansible/modules/system/solaris_zone.py lib/ansible/modules/system/svc.py -lib/ansible/modules/system/systemd.py lib/ansible/modules/system/timezone.py lib/ansible/modules/system/ufw.py lib/ansible/modules/system/user.py