fixing an issue with memoize on macOS services, switching to useing __context__ instead

This commit is contained in:
Wesley Whetstone 2018-08-10 15:06:05 -07:00 committed by Ch3LL
parent b412bff534
commit 3ab5d282be
No known key found for this signature in database
GPG key ID: 132B55A7C13EFA73
2 changed files with 75 additions and 20 deletions

View file

@ -51,19 +51,19 @@ def __virtual__():
return __virtualname__
def _get_service(name):
def _name_in_services(name, services):
'''
Get information about a service. If the service is not found, raise an
error
Checks to see if the given service is in the given services.
:param str name: Service label, file name, or full path
:return: The service information for the service, otherwise an Error
:param dict services: The currently available services.
:return: The service information for the service, otherwise
an empty dictionary
:rtype: dict
'''
services = __utils__['mac_utils.available_services']()
name = name.lower()
if name in services:
# Match on label
return services[name]
@ -77,8 +77,50 @@ def _get_service(name):
# Match on basename
return service
# Could not find service
raise CommandExecutionError('Service not found: {0}'.format(name))
return dict()
def _get_service(name):
'''
Get information about a service. If the service is not found, raise an
error
:param str name: Service label, file name, or full path
:return: The service information for the service, otherwise an Error
:rtype: dict
'''
services = __utils__['mac_utils.available_services']()
name = name.lower()
service = _name_in_services(name, services)
# if we would the service we can return it
if service:
return service
# if we got here our service is not available, now we can check to see if
# we received a cached batch of services, if not we did a fresh check
# so we need to raise that the service could not be found.
try:
if not __context__['using_cached_services']:
raise CommandExecutionError('Service not found: {0}'.format(name))
except KeyError:
pass
# we used a cached version to check, a service could have been made
# between now and then, we should refresh our available services.
services = __utils__['mac_utils.available_services'](refresh=True)
# check to see if we found the service we are looking for.
service = _name_in_services(name, services)
if not service:
# Could not find the service after refresh raise.
raise CommandExecutionError('Service not found: {0}'.format(name))
# found it :)
return service
def show(name):
@ -429,7 +471,7 @@ def disabled(name, runas=None, domain='system'):
salt '*' service.disabled org.cups.cupsd
'''
ret = False
disabled = launchctl('print-disabled',
domain,
return_stdout=True,

View file

@ -299,14 +299,18 @@ def launchctl(sub_cmd, *args, **kwargs):
return ret['stdout'] if return_stdout else True
def _available_services():
def _available_services(refresh=False):
'''
This is a helper function needed for testing. We are using the memoziation
decorator on the `available_services` function, which causes the function
to run once and then return the results of the first run on subsequent
calls. This causes problems when trying to test the functionality of the
`available_services` function.
This is a helper function for getting the available macOS services.
'''
try:
if __context__['available_services'] and not refresh:
log.debug('Found context for available services.')
__context__['available_services_cached'] = True
return __context__['available_services']
except KeyError:
pass
launchd_paths = [
'/Library/LaunchAgents',
'/Library/LaunchDaemons',
@ -359,14 +363,22 @@ def _available_services():
'file_path': true_path,
'plist': plist}
return _available_services
# put this in __context__ as this is a time consuming function.
# a fix for this issue. https://github.com/saltstack/salt/issues/48414
__context__['available_services'] = _available_services
# this is a fresh gathering of services, set cached to false
__context__['available_services_cached'] = False
return __context__['available_services']
@decorators.memoize
def available_services():
def available_services(refresh=False):
'''
Return a dictionary of all available services on the system
:param bool refresh: If you wish to refresh the available services
as this data is cached on the first run.
Returns:
dict: All available services
@ -377,4 +389,5 @@ def available_services():
import salt.utils.mac_service
salt.utils.mac_service.available_services()
'''
return _available_services()
log.debug('Loading available services')
return _available_services(refresh)