def get_service_path(module, service): (rc, out, err) = run_sys_ctl(module, ['find', service]) # fail if service not found if rc != 0: fail_if_missing(module, False, service, msg='host') else: return to_native(out).strip()
def main(): # initialize module = AnsibleModule( argument_spec=dict( name=dict(type='str', aliases=['service', 'unit']), state=dict(type='str', choices=['started', 'stopped']), timeout=dict(default=300, type='int') ), supports_check_mode=True, ) start = datetime.datetime.utcnow() unit = module.params['name'] if unit: end = start + datetime.timedelta(seconds=module.params['timeout']) service_state_ok = False # Loop while datetime.datetime.utcnow() < end: (found,result) = call_systemd(module, unit) # Check service state if module.params['state'] is not None: fail_if_missing(module, found, unit, msg="host") # What is current service state? if 'ActiveState' in result['status']: if module.params['state'] == 'stopped': # If service is stopped -> break if not is_running_service(result['status']): service_state_ok = True break elif module.params['state'] == 'started': # If service is started -> break if is_running_service(result['status']): service_state_ok = True break time.sleep(1) if service_state_ok == False: elapsed = datetime.datetime.now() - start module.fail_json(msg="Timeout when waiting for %s service status to be %s" % (unit, module.params['state']), elapsed=elapsed.seconds) module.exit_json(**result)
def main(): # initialize module = AnsibleModule( argument_spec=dict( name=dict(type='str', aliases=['service', 'unit']), state=dict(type='str', choices=['reloaded', 'restarted', 'started', 'stopped']), enabled=dict(type='bool'), force=dict(type='bool'), masked=dict(type='bool'), daemon_reload=dict(type='bool', default=False, aliases=['daemon-reload']), daemon_reexec=dict(type='bool', default=False, aliases=['daemon-reexec']), user=dict(type='bool'), scope=dict(type='str', choices=['system', 'user', 'global']), no_block=dict(type='bool', default=False), ), supports_check_mode=True, required_one_of=[[ 'state', 'enabled', 'masked', 'daemon_reload', 'daemon_reexec' ]], required_by=dict( state=('name', ), enabled=('name', ), masked=('name', ), ), mutually_exclusive=[['scope', 'user']], ) unit = module.params['name'] if unit is not None: for globpattern in (r"*", r"?", r"["): if globpattern in unit: module.fail_json( msg= "This module does not currently support using glob patterns, found '%s' in service name: %s" % (globpattern, unit)) systemctl = module.get_bin_path('systemctl', True) if os.getenv('XDG_RUNTIME_DIR') is None: os.environ['XDG_RUNTIME_DIR'] = '/run/user/%s' % os.geteuid() ''' Set CLI options depending on params ''' if module.params['user'] is not None: # handle user deprecation, mutually exclusive with scope module.deprecate("The 'user' option is being replaced by 'scope'", version='2.11') if module.params['user']: module.params['scope'] = 'user' else: module.params['scope'] = 'system' # if scope is 'system' or None, we can ignore as there is no extra switch. # The other choices match the corresponding switch if module.params['scope'] not in (None, 'system'): systemctl += " --%s" % module.params['scope'] if module.params['no_block']: systemctl += " --no-block" if module.params['force']: systemctl += " --force" rc = 0 out = err = '' result = dict( name=unit, changed=False, status=dict(), ) # Run daemon-reload first, if requested if module.params['daemon_reload'] and not module.check_mode: (rc, out, err) = module.run_command("%s daemon-reload" % (systemctl)) if rc != 0: module.fail_json(msg='failure %d during daemon-reload: %s' % (rc, err)) # Run daemon-reexec if module.params['daemon_reexec'] and not module.check_mode: (rc, out, err) = module.run_command("%s daemon-reexec" % (systemctl)) if rc != 0: module.fail_json(msg='failure %d during daemon-reexec: %s' % (rc, err)) 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)) 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 if out: result['status'] = parse_systemctl_show( to_native(out).split('\n')) is_systemd = 'LoadState' in result[ 'status'] and result['status']['LoadState'] != 'not-found' is_masked = 'LoadState' in result['status'] and result[ 'status']['LoadState'] == 'masked' # Check for loading error if is_systemd and not is_masked 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' 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 or global user service and both init script and unit file exist stdout should have enabled/disabled, otherwise use rc entries if module.params['scope'] in (None, 'system') and \ not module.params['user'] and \ is_initd and \ not out.strip().endswith('disabled') and \ 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']) or is_deactivating_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)) # check for chroot elif is_chroot(module): module.warn( "Target is a chroot. This can lead to false positives or prevent the init system tools from working." ) else: # this should not happen? module.fail_json(msg="Service is in unknown state", status=result['status']) module.exit_json(**result)
def main(): # initialize module = AnsibleModule( argument_spec = dict( name = dict(required=True, type='str', 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), ), supports_check_mode=True, required_one_of=[['state', 'enabled', 'masked', 'daemon_reload']], ) systemctl = module.get_bin_path('systemctl', True) if module.params['user']: systemctl = systemctl + " --user" if module.params['no_block']: systemctl = systemctl + " --no-block" unit = module.params['name'] rc = 0 out = err = '' result = { 'name': unit, 'changed': False, 'status': {}, } # Run daemon-reload first, if requested if module.params['daemon_reload']: (rc, out, err) = module.run_command("%s daemon-reload" % (systemctl)) 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 # 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 out.find('ignoring request') != -1: # 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 else: multival.append(line) 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'])) # 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' 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, 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)
def main(): # initialize module = AnsibleModule( argument_spec=dict( name=dict(type='str', aliases=['service', 'unit']), properties=dict(type='dict'), ), supports_check_mode=True, required_one_of=[['properties']], ) systemctl = module.get_bin_path('systemctl', True) unit = module.params['name'] rc = 0 out = err = '' result = dict( name=unit, changed=False, status=dict(), ) for requires in ('properties'): if module.params[requires] is not None and unit is None: module.fail_json(msg="name is also required when specifying %s" % requires) 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)) 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 if out: result['status'] = parse_systemctl_show(to_native(out).split('\n')) is_systemd = 'LoadState' in result['status'] and result['status']['LoadState'] != 'not-found' is_masked = 'LoadState' in result['status'] and result['status']['LoadState'] == 'masked' # Check for loading error if is_systemd and not is_masked 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) # set service properties if requested and this is not an initd service. Should be done before starting the service. if module.params['properties'] is not None and not is_initd: fail_if_missing(module, found, unit, msg="host") # loop through all of the properties we want to set prop_list = module.params['properties'] prop_action = "" for prop in prop_list.keys(): # convert the output to a str as that is what result['status'][prop] will be when we compare later prop_val = str(convert_property_suffix(prop_list[prop])) # the property name must already be in the output from `systemctl show` if prop in result['status'] and prop_val != result['status'][prop]: prop_action += (" %s=%s" % (prop, prop_val)) # Modify all items if prop_action and not module.check_mode: result['changed'] = True (rc, out, err) = module.run_command("%s set-property %s %s" % (systemctl, unit, prop_action)) if rc != 0: module.fail_json(msg="Unable to set-property service %s - %s: %s" % (unit, prop_action, err)) else: # In the case where we have updated properties we need to pull the full list again # so that the result[status] reflects the new values (rc, out, err) = module.run_command("%s show '%s'" % (systemctl, unit)) if rc == 0: # load return of systemctl show into dictionary for easy access and return if out: result['status'] = parse_systemctl_show(to_native(out).split('\n')) module.exit_json(**result)
def main(): # initialize module = AnsibleModule( argument_spec=dict( name=dict(type='str', aliases=['service', 'unit']), state=dict(type='str', choices=[ 'tried-restarting', 'reloaded-or-restarted', 'tried-reloading-or-restarting', 'reloaded', 'restarted', 'started', 'stopped', ]), enabled=dict(type='bool'), force=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']: systemctl = systemctl + " --user" if module.params['no_block']: systemctl = systemctl + " --no-block" if module.params['force']: systemctl = systemctl + " --force" unit = module.params['name'] rc = 0 out = err = '' 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: module.fail_json(msg="name is also required when specifying %s" % requires) # Run daemon-reload first, if requested if module.params['daemon_reload'] and not module.check_mode: (rc, out, err) = module.run_command("%s daemon-reload" % (systemctl)) if rc != 0: module.fail_json(msg='failure %d during daemon-reload: %s' % (rc, err)) 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)) 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 if out: result['status'] = parse_systemctl_show( to_native(out).split('\n')) 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' 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, 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']: is_service_running = is_running_service(result['status']) action = get_action_from_state( requested_state=module.params['state'], current_state=is_service_running, # Fall back to start if not running: fallback_action=DO_NOTHING if is_service_running else 'start', ) if module.params['state'] not in ('started', 'stopped'): result['state'] = 'started' supported_features = detect_systemd_features(module, systemctl) actor = convert_action_to_actor(action, supported_features) if actor is not DO_NOTHING: result['changed'] = True if action == 'reload' and not unit_supports_reload( module, systemctl, unit): module.warn( 'The service (%s) does not support ' '`reload` action and it is likely to fail. ' 'you may try `reloaded-or-restarted`, ' '`tried-reloading-or-restarting` or anything else ' 'which suits your needs better. ' 'If you maintain this unit, you might want to ' 'implement ExecReload there first.' % unit) if not module.check_mode: actor(module, systemctl, unit) else: # this should not happen? module.fail_json(msg="Service is in unknown state", status=result['status']) module.exit_json(**result)
def main(): module = AnsibleModule( argument_spec=dict( name=dict(required=True, type='str', aliases=['service']), state=dict(choices=['started', 'stopped', 'restarted', 'reloaded'], type='str'), enabled=dict(type='bool'), sleep=dict(type='int', default=1), pattern=dict(type='str'), arguments=dict(type='str', aliases=['args']), runlevels=dict(type='list'), daemonize=dict(type='bool', default=False), ), supports_check_mode=True, required_one_of=[['state', 'enabled']], ) name = module.params['name'] action = module.params['state'] enabled = module.params['enabled'] runlevels = module.params['runlevels'] pattern = module.params['pattern'] sleep_for = module.params['sleep'] rc = 0 out = err = '' result = {'name': name, 'changed': False, 'status': {}} # ensure service exists, get script name fail_if_missing(module, sysv_exists(name), name) script = get_sysv_script(name) # locate binaries for service management paths = ['/sbin', '/usr/sbin', '/bin', '/usr/bin'] binaries = ['chkconfig', 'update-rc.d', 'insserv', 'service'] # Keeps track of the service status for various runlevels because we can # operate on multiple runlevels at once runlevel_status = {} location = {} for binary in binaries: location[binary] = module.get_bin_path(binary, opt_dirs=paths) # figure out enable status if runlevels: for rl in runlevels: runlevel_status.setdefault(rl, {}) runlevel_status[rl]["enabled"] = sysv_is_enabled(name, runlevel=rl) else: runlevel_status["enabled"] = sysv_is_enabled(name) # figure out started status, everyone does it different! is_started = False # user knows other methods fail and supplied pattern if pattern: is_started = get_ps(module, pattern) else: worked = False if location.get('service'): # standard tool that has been 'destandarized' by reimplementation in other OS/distros cmd = '%s %s status' % (location['service'], name) elif script: # maybe script implements status (not LSB) cmd = '%s status' % script else: module.fail_json(msg="Unable to determine service status") (rc, out, err) = module.run_command(cmd) if not rc == -1: # special case if name == 'iptables' and "ACCEPT" in out: worked = True is_started = True # check output messages, messy but sadly more reliable than rc if not worked and out.count('\n') <= 1: cleanout = out.lower().replace(name.lower(), '') for stopped in [ 'stop', 'is dead ', 'dead but ', 'could not access pid file', 'inactive' ]: if stopped in cleanout: worked = True break if not worked: for started_status in ['run', 'start', 'active']: if started_status in cleanout and "not " not in cleanout: is_started = True worked = True break # hope rc is not lying to us, use often used 'bad' returns if not worked and rc in [1, 2, 3, 4, 69]: worked = True if not worked: # hail mary if rc == 0: worked = True # ps for luck, can only assure positive match elif get_ps(module, name): is_started = True worked = True module.warn( "Used ps output to match service name and determine it is up, this is very unreliable" ) if not worked: module.warn( "Unable to determine if service is up, assuming it is down") ########################################################################### # BEGIN: Enable/Disable result['status'].setdefault('enabled', {}) result['status']['enabled']['changed'] = False result['status']['enabled']['rc'] = None result['status']['enabled']['stdout'] = None result['status']['enabled']['stderr'] = None if runlevels: result['status']['enabled']['runlevels'] = runlevels for rl in runlevels: if enabled != runlevel_status[rl]["enabled"]: result['changed'] = True result['status']['enabled']['changed'] = True if not module.check_mode and result['changed']: # Perform enable/disable here if enabled: if location.get('update-rc.d'): (rc, out, err) = module.run_command( "%s %s enable %s" % (location['update-rc.d'], name, ' '.join(runlevels))) elif location.get('chkconfig'): (rc, out, err) = module.run_command( "%s --level %s %s on" % (location['chkconfig'], ''.join(runlevels), name)) else: if location.get('update-rc.d'): (rc, out, err) = module.run_command( "%s %s disable %s" % (location['update-rc.d'], name, ' '.join(runlevels))) elif location.get('chkconfig'): (rc, out, err) = module.run_command( "%s --level %s %s off" % (location['chkconfig'], ''.join(runlevels), name)) else: if enabled is not None and enabled != runlevel_status["enabled"]: result['changed'] = True result['status']['enabled']['changed'] = True if not module.check_mode and result['changed']: # Perform enable/disable here if enabled: if location.get('update-rc.d'): (rc, out, err) = module.run_command( "%s %s enable" % (location['update-rc.d'], name)) elif location.get('chkconfig'): (rc, out, err) = module.run_command( "%s %s on" % (location['chkconfig'], name)) else: if location.get('update-rc.d'): (rc, out, err) = module.run_command( "%s %s disable" % (location['update-rc.d'], name)) elif location.get('chkconfig'): (rc, out, err) = module.run_command( "%s %s off" % (location['chkconfig'], name)) # Assigned above, might be useful is something goes sideways if not module.check_mode and result['status']['enabled']['changed']: result['status']['enabled']['rc'] = rc result['status']['enabled']['stdout'] = out result['status']['enabled']['stderr'] = err rc, out, err = None, None, None if "illegal runlevel specified" in result['status']['enabled'][ 'stderr']: module.fail_json( msg= "Illegal runlevel specified for enable operation on service %s" % name, **result) # END: Enable/Disable ########################################################################### ########################################################################### # BEGIN: state result['status'].setdefault(module.params['state'], {}) result['status'][module.params['state']]['changed'] = False result['status'][module.params['state']]['rc'] = None result['status'][module.params['state']]['stdout'] = None result['status'][module.params['state']]['stderr'] = None if action: action = re.sub(r'p?ed$', '', action.lower()) def runme(doit): args = module.params['arguments'] cmd = "%s %s %s" % (script, doit, "" if args is None else args) # how to run if module.params['daemonize']: (rc, out, err) = daemonize(cmd) else: (rc, out, err) = module.run_command(cmd) # FIXME: ERRORS if rc != 0: module.fail_json(msg="Failed to %s service: %s" % (action, name)) return (rc, out, err) if action == 'restart': result['changed'] = True result['status'][module.params['state']]['changed'] = True if not module.check_mode: # cannot rely on existing 'restart' in init script for dothis in ['stop', 'start']: (rc, out, err) = runme(dothis) if sleep_for: sleep(sleep_for) elif is_started != (action == 'start'): result['changed'] = True result['status'][module.params['state']]['changed'] = True if not module.check_mode: rc, out, err = runme(action) elif is_started == (action == 'stop'): result['changed'] = True result['status'][module.params['state']]['changed'] = True if not module.check_mode: rc, out, err = runme(action) if not module.check_mode and result['status'][ module.params['state']]['changed']: result['status'][module.params['state']]['rc'] = rc result['status'][module.params['state']]['stdout'] = out result['status'][module.params['state']]['stderr'] = err rc, out, err = None, None, None # END: state ########################################################################### module.exit_json(**result)
def main(): # initialize module = AnsibleModule( argument_spec=dict( name=dict(type='str', aliases=['service', 'unit']), state=dict(type='str', choices=['reloaded', 'restarted', 'started', 'stopped']), enabled=dict(type='bool'), force=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']: systemctl = systemctl + " --user" if module.params['no_block']: systemctl = systemctl + " --no-block" if module.params['force']: systemctl = systemctl + " --force" unit = module.params['name'] rc = 0 out = err = '' 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: module.fail_json(msg="name is also required when specifying %s" % requires) # Run daemon-reload first, if requested if module.params['daemon_reload'] and not module.check_mode: (rc, out, err) = module.run_command("%s daemon-reload" % (systemctl)) if rc != 0: module.fail_json(msg='failure %d during daemon-reload: %s' % (rc, err)) 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)) 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 if out: result['status'] = parse_systemctl_show(to_native(out).split('\n')) 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' 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, 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)
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), detect_early_failure = dict(type='bool', default=False), early_failure_timeout = dict(type='float', default=1), ), supports_check_mode=True, required_one_of=[['state', 'enabled', 'masked', 'daemon_reload']], ) systemctl = module.get_bin_path('systemctl', True) if module.params['user']: systemctl = systemctl + " --user" if module.params['no_block']: if module.params['detect_early_failure']: module.fail_json(msg="no_block and detect_early_failure don't go together") systemctl = systemctl + " --no-block" unit = module.params['name'] rc = 0 out = err = '' result = { 'name': unit, 'changed': False, 'status': {}, } for requires in ('state', 'enabled', 'masked'): 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 if module.params['daemon_reload']: (rc, out, err) = module.run_command("%s daemon-reload" % (systemctl)) if rc != 0: module.fail_json(msg='failure %d during daemon-reload: %s' % (rc, err)) if unit: is_systemd, is_initd, properties = get_unit_properties(unit, systemctl, module) # 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) if is_systemd and properties: result['status'] = properties # 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' 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, 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)) unit_type = re.compile("[^.]*$").search(result['status']['Id']).group(0).lower() if unit_type == 'service' and action in ('start', 'stop', 'restart') and module.params['detect_early_failure']: time.sleep(module.params['early_failure_timeout']) is_systemd, is_initd, properties = get_unit_properties(unit, systemctl, module) if not (is_systemd and properties): # this should not happen? module.fail_json(msg="Systemd service no longer found after early_failure_timeout", is_initd=is_initd, is_systemd=is_systemd, status=properties, previous_status=result['status']) result['status'] = properties if 'ActiveState' in result['status'] and result['status']['ActiveState'] == 'failed': module.fail_json(msg="Failed to %s service %s: Service went into failed state early" % (action, unit)) else: # this should not happen? module.fail_json(msg="Service is in unknown state", status=result['status']) module.exit_json(**result)
def main(): # initialize module = AnsibleModule( argument_spec=dict( name=dict(required=True, type="str", 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), ), supports_check_mode=True, required_one_of=[["state", "enabled", "masked", "daemon_reload"]], ) systemctl = module.get_bin_path("systemctl") if module.params["user"]: systemctl = systemctl + " --user" unit = module.params["name"] rc = 0 out = err = "" result = {"name": unit, "changed": False, "status": {}, "warnings": []} # Run daemon-reload first, if requested if module.params["daemon_reload"]: (rc, out, err) = module.run_command("%s daemon-reload" % (systemctl)) 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 # 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 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 else: multival.append(line) 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"])) # Does service exist? found = is_systemd or is_initd if is_initd and not is_systemd: result["warnings"].append( "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" 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 both init script and unit file exist stdout should have enabled/disabled, otherwise use rc entries if is_initd and (not out.startswith("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 result["status"]["ActiveState"] != "active": action = "start" elif module.params["state"] == "stopped": if result["status"]["ActiveState"] == "active": action = "stop" else: if result["status"]["ActiveState"] != "active": 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)