diff --git a/lib/ansible/modules/system/systemd.py b/lib/ansible/modules/system/systemd.py index ccd35508a9..ea93384f90 100644 --- a/lib/ansible/modules/system/systemd.py +++ b/lib/ansible/modules/system/systemd.py @@ -294,7 +294,7 @@ def main(): } for requires in ('state', 'enabled', 'masked'): - if requires is not None and unit is None: + if module.params[requires] is not None and unit is None: module.fail_json(msg="name is also required when specifying %s" % requires) # Run daemon-reload first, if requested @@ -303,147 +303,148 @@ def main(): if rc != 0: module.fail_json(msg='failure %d during daemon-reload: %s' % (rc, err)) - found = False - is_initd = sysv_exists(unit) - is_systemd = False + if unit: + found = False + is_initd = sysv_exists(unit) + is_systemd = False - # check service data, cannot error out on rc as it changes across versions, assume not found - (rc, out, err) = module.run_command("%s show '%s'" % (systemctl, unit)) + # check service data, cannot error out on rc as it changes across versions, assume not found + (rc, out, err) = module.run_command("%s show '%s'" % (systemctl, unit)) - if request_was_ignored(out) or request_was_ignored(err): - # fallback list-unit-files as show does not work on some systems (chroot) - # not used as primary as it skips some services (like those using init.d) and requires .service/etc notation - (rc, out, err) = module.run_command("%s list-unit-files '%s'" % (systemctl, unit)) - if rc == 0: - is_systemd = True + if request_was_ignored(out) or request_was_ignored(err): + # fallback list-unit-files as show does not work on some systems (chroot) + # not used as primary as it skips some services (like those using init.d) and requires .service/etc notation + (rc, out, err) = module.run_command("%s list-unit-files '%s'" % (systemctl, unit)) + if rc == 0: + is_systemd = True - elif rc == 0: - # load return of systemctl show into dictionary for easy access and return - multival = [] - if out: - k = None - for line in to_native(out).split('\n'): # systemd can have multiline values delimited with {} - if line.strip(): - if k is None: - if '=' in line: - k,v = line.split('=', 1) - if v.lstrip().startswith('{'): - if not v.rstrip().endswith('}'): - multival.append(line) - continue - result['status'][k] = v.strip() - k = None - else: - if line.rstrip().endswith('}'): - result['status'][k] = '\n'.join(multival).strip() - multival = [] - k = None + elif rc == 0: + # load return of systemctl show into dictionary for easy access and return + multival = [] + if out: + k = None + for line in to_native(out).split('\n'): # systemd can have multiline values delimited with {} + if line.strip(): + if k is None: + if '=' in line: + k,v = line.split('=', 1) + if v.lstrip().startswith('{'): + if not v.rstrip().endswith('}'): + multival.append(line) + continue + result['status'][k] = v.strip() + k = None else: - multival.append(line) + if line.rstrip().endswith('}'): + result['status'][k] = '\n'.join(multival).strip() + multival = [] + k = None + else: + multival.append(line) - is_systemd = 'LoadState' in result['status'] and result['status']['LoadState'] != 'not-found' + is_systemd = 'LoadState' in result['status'] and result['status']['LoadState'] != 'not-found' - # Check for loading error - if is_systemd and 'LoadError' in result['status']: - module.fail_json(msg="Error loading unit file '%s': %s" % (unit, result['status']['LoadError'])) - else: - # Check for systemctl command - module.run_command(systemctl, check_rc=True) - - # Does service exist? - found = is_systemd or is_initd - if is_initd and not is_systemd: - module.warn('The service (%s) is actually an init script but the system is managed by systemd' % unit) - - # mask/unmask the service, if requested, can operate on services before they are installed - if module.params['masked'] is not None: - # state is not masked unless systemd affirms otherwise - masked = ('LoadState' in result['status'] and result['status']['LoadState'] == 'masked') - - if masked != module.params['masked']: - result['changed'] = True - if module.params['masked']: - action = 'mask' - else: - action = 'unmask' - - if not module.check_mode: - (rc, out, err) = module.run_command("%s %s '%s'" % (systemctl, action, unit)) - if rc != 0: - # 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: - - if module.params['enabled']: - action = 'enable' + # Check for loading error + if is_systemd and 'LoadError' in result['status']: + module.fail_json(msg="Error loading unit file '%s': %s" % (unit, result['status']['LoadError'])) else: - action = 'disable' + # Check for systemctl command + module.run_command(systemctl, check_rc=True) - fail_if_missing(module, found, unit, msg='host') + # Does service exist? + found = is_systemd or is_initd + if is_initd and not is_systemd: + module.warn('The service (%s) is actually an init script but the system is managed by systemd' % unit) - # do we need to enable the service? - enabled = False - (rc, out, err) = module.run_command("%s is-enabled '%s'" % (systemctl, unit)) + # mask/unmask the service, if requested, can operate on services before they are installed + if module.params['masked'] is not None: + # state is not masked unless systemd affirms otherwise + masked = ('LoadState' in result['status'] and result['status']['LoadState'] == 'masked') - # check systemctl result or if it is a init script - if rc == 0: - enabled = True - elif rc == 1: - # if not a user service and both init script and unit file exist stdout should have enabled/disabled, otherwise use rc entries - if not module.params['user'] and \ - is_initd and \ - (not out.strip().endswith('disabled') or sysv_is_enabled(unit)): - - enabled = True - - # default to current state - result['enabled'] = enabled - - # Change enable/disable if needed - if enabled != module.params['enabled']: - result['changed'] = True - if not module.check_mode: - (rc, out, err) = module.run_command("%s %s '%s'" % (systemctl, action, unit)) - if rc != 0: - module.fail_json(msg="Unable to %s service %s: %s" % (action, unit, out + err)) - - result['enabled'] = not enabled - - # set service state if requested - if module.params['state'] is not None: - fail_if_missing(module, found, unit, msg="host") - - # default to desired state - result['state'] = module.params['state'] - - # What is current service state? - if 'ActiveState' in result['status']: - action = None - if module.params['state'] == 'started': - if not is_running_service(result['status']): - action = 'start' - elif module.params['state'] == 'stopped': - if is_running_service(result['status']): - action = 'stop' - else: - if not is_running_service(result['status']): - action = 'start' + if masked != module.params['masked']: + result['changed'] = True + if module.params['masked']: + action = 'mask' else: - action = module.params['state'][:-2] # remove 'ed' from restarted/reloaded - result['state'] = 'started' + action = 'unmask' - if action: + if not module.check_mode: + (rc, out, err) = module.run_command("%s %s '%s'" % (systemctl, action, unit)) + if rc != 0: + # 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: + + if module.params['enabled']: + action = 'enable' + else: + action = 'disable' + + fail_if_missing(module, found, unit, msg='host') + + # do we need to enable the service? + enabled = False + (rc, out, err) = module.run_command("%s is-enabled '%s'" % (systemctl, unit)) + + # check systemctl result or if it is a init script + if rc == 0: + enabled = True + elif rc == 1: + # if not a user service and both init script and unit file exist stdout should have enabled/disabled, otherwise use rc entries + if not module.params['user'] and \ + is_initd and \ + (not out.strip().endswith('disabled') or sysv_is_enabled(unit)): + + enabled = True + + # default to current state + result['enabled'] = enabled + + # Change enable/disable if needed + if enabled != module.params['enabled']: result['changed'] = True if not module.check_mode: (rc, out, err) = module.run_command("%s %s '%s'" % (systemctl, action, unit)) if rc != 0: - module.fail_json(msg="Unable to %s service %s: %s" % (action, unit, err)) - else: - # this should not happen? - module.fail_json(msg="Service is in unknown state", status=result['status']) + module.fail_json(msg="Unable to %s service %s: %s" % (action, unit, out + err)) + + result['enabled'] = not enabled + + # set service state if requested + if module.params['state'] is not None: + fail_if_missing(module, found, unit, msg="host") + + # default to desired state + result['state'] = module.params['state'] + + # What is current service state? + if 'ActiveState' in result['status']: + action = None + if module.params['state'] == 'started': + if not is_running_service(result['status']): + action = 'start' + elif module.params['state'] == 'stopped': + if is_running_service(result['status']): + action = 'stop' + else: + if not is_running_service(result['status']): + action = 'start' + else: + action = module.params['state'][:-2] # remove 'ed' from restarted/reloaded + result['state'] = 'started' + + if action: + result['changed'] = True + if not module.check_mode: + (rc, out, err) = module.run_command("%s %s '%s'" % (systemctl, action, unit)) + if rc != 0: + module.fail_json(msg="Unable to %s service %s: %s" % (action, unit, err)) + else: + # this should not happen? + module.fail_json(msg="Service is in unknown state", status=result['status']) module.exit_json(**result)