%PDF- %PDF-
Direktori : /lib/python2.7/site-packages/salt/states/ |
Current File : //lib/python2.7/site-packages/salt/states/supervisord.py |
# -*- coding: utf-8 -*- ''' Interaction with the Supervisor daemon ====================================== .. code-block:: yaml wsgi_server: supervisord.running: - require: - pkg: supervisor - watch: - file: /etc/nginx/sites-enabled/wsgi_server.conf ''' from __future__ import absolute_import, unicode_literals, print_function # Import python libs import logging from salt.ext import six log = logging.getLogger(__name__) def _check_error(result, success_message): ret = {} if 'ERROR' in result: if any(substring in result for substring in [ 'already started', 'not running', 'process group already active' ]): ret['comment'] = success_message else: ret['comment'] = result ret['result'] = False else: ret['comment'] = success_message return ret def _is_stopped_state(state): if state in ('STOPPED', 'STOPPING', 'EXITED', 'FATAL', 'BACKOFF'): return True if state in ('STARTING', 'RUNNING'): return False return False def running(name, restart=False, update=False, user=None, conf_file=None, bin_env=None, **kwargs): ''' Ensure the named service is running. name Service name as defined in the supervisor configuration file restart Whether to force a restart update Whether to update the supervisor configuration. user Name of the user to run the supervisorctl command .. versionadded:: 0.17.0 conf_file path to supervisorctl config file bin_env path to supervisorctl bin or path to virtualenv with supervisor installed ''' if name.endswith(':*'): name = name[:-1] ret = {'name': name, 'result': True, 'comment': '', 'changes': {}} if 'supervisord.status' not in __salt__: ret['result'] = False ret['comment'] = 'Supervisord module not activated. Do you need to install supervisord?' return ret all_processes = __salt__['supervisord.status']( user=user, conf_file=conf_file, bin_env=bin_env ) # parse process groups process_groups = set() for proc in all_processes: if ':' in proc: process_groups.add(proc[:proc.index(':') + 1]) process_groups = sorted(process_groups) matches = {} if name in all_processes: matches[name] = (all_processes[name]['state'].lower() == 'running') elif name in process_groups: for process in (x for x in all_processes if x.startswith(name)): matches[process] = ( all_processes[process]['state'].lower() == 'running' ) to_add = not bool(matches) if __opts__['test']: if not to_add: # Process/group already present, check if any need to be started to_start = [x for x, y in six.iteritems(matches) if y is False] if to_start: ret['result'] = None if name.endswith(':'): # Process group if len(to_start) == len(matches): ret['comment'] = ( 'All services in group \'{0}\' will be started' .format(name) ) else: ret['comment'] = ( 'The following services will be started: {0}' .format(' '.join(to_start)) ) else: # Single program ret['comment'] = 'Service {0} will be started'.format(name) else: if name.endswith(':'): # Process group ret['comment'] = ( 'All services in group \'{0}\' are already running' .format(name) ) else: ret['comment'] = ('Service {0} is already running' .format(name)) else: ret['result'] = None # Process/group needs to be added if name.endswith(':'): _type = 'Group \'{0}\''.format(name) else: _type = 'Service {0}'.format(name) ret['comment'] = '{0} will be added and started'.format(_type) return ret changes = [] just_updated = False if update: # If the state explicitly asks to update, we don't care if the process # is being added or not, since it'll take care of this for us, # so give this condition priority in order # # That is, unless `to_add` somehow manages to contain processes # we don't want running, in which case adding them may be a mistake comment = 'Updating supervisor' result = __salt__['supervisord.update']( user=user, conf_file=conf_file, bin_env=bin_env ) ret.update(_check_error(result, comment)) log.debug(comment) if '{0}: updated'.format(name) in result: just_updated = True elif to_add: # Not sure if this condition is precise enough. comment = 'Adding service: {0}'.format(name) __salt__['supervisord.reread']( user=user, conf_file=conf_file, bin_env=bin_env ) # Causes supervisorctl to throw `ERROR: process group already active` # if process group exists. At this moment, I'm not sure how to handle # this outside of grepping out the expected string in `_check_error`. result = __salt__['supervisord.add']( name, user=user, conf_file=conf_file, bin_env=bin_env ) ret.update(_check_error(result, comment)) changes.append(comment) log.debug(comment) is_stopped = None process_type = None if name in process_groups: process_type = 'group' # check if any processes in this group are stopped is_stopped = False for proc in all_processes: if proc.startswith(name) \ and _is_stopped_state(all_processes[proc]['state']): is_stopped = True break elif name in all_processes: process_type = 'service' if _is_stopped_state(all_processes[name]['state']): is_stopped = True else: is_stopped = False if is_stopped is False: if restart and not just_updated: comment = 'Restarting{0}: {1}'.format( process_type is not None and ' {0}'.format(process_type) or '', name ) log.debug(comment) result = __salt__['supervisord.restart']( name, user=user, conf_file=conf_file, bin_env=bin_env ) ret.update(_check_error(result, comment)) changes.append(comment) elif just_updated: comment = 'Not starting updated{0}: {1}'.format( process_type is not None and ' {0}'.format(process_type) or '', name ) result = comment ret.update({'comment': comment}) else: comment = 'Not starting already running{0}: {1}'.format( process_type is not None and ' {0}'.format(process_type) or '', name ) result = comment ret.update({'comment': comment}) elif not just_updated: comment = 'Starting{0}: {1}'.format( process_type is not None and ' {0}'.format(process_type) or '', name ) changes.append(comment) log.debug(comment) result = __salt__['supervisord.start']( name, user=user, conf_file=conf_file, bin_env=bin_env ) ret.update(_check_error(result, comment)) log.debug(six.text_type(result)) if ret['result'] and len(changes): ret['changes'][name] = ' '.join(changes) return ret def dead(name, user=None, conf_file=None, bin_env=None, **kwargs): ''' Ensure the named service is dead (not running). name Service name as defined in the supervisor configuration file user Name of the user to run the supervisorctl command .. versionadded:: 0.17.0 conf_file path to supervisorctl config file bin_env path to supervisorctl bin or path to virtualenv with supervisor installed ''' ret = {'name': name, 'result': True, 'comment': '', 'changes': {}} if __opts__['test']: ret['result'] = None ret['comment'] = ( 'Service {0} is set to be stopped'.format(name)) else: comment = 'Stopping service: {0}'.format(name) log.debug(comment) all_processes = __salt__['supervisord.status']( user=user, conf_file=conf_file, bin_env=bin_env ) # parse process groups process_groups = [] for proc in all_processes: if ':' in proc: process_groups.append(proc[:proc.index(':') + 1]) process_groups = list(set(process_groups)) is_stopped = None if name in process_groups: # check if any processes in this group are stopped is_stopped = False for proc in all_processes: if proc.startswith(name) \ and _is_stopped_state(all_processes[proc]['state']): is_stopped = True break elif name in all_processes: if _is_stopped_state(all_processes[name]['state']): is_stopped = True else: is_stopped = False else: # process name doesn't exist ret['comment'] = "Service {0} doesn't exist".format(name) return ret if is_stopped is True: ret['comment'] = "Service {0} is not running".format(name) else: result = {name: __salt__['supervisord.stop']( name, user=user, conf_file=conf_file, bin_env=bin_env )} ret.update(_check_error(result, comment)) ret['changes'][name] = comment log.debug(six.text_type(result)) return ret def mod_watch(name, restart=True, update=False, user=None, conf_file=None, bin_env=None, **kwargs): ''' The supervisord watcher, called to invoke the watch command. Always restart on watch .. note:: This state exists to support special handling of the ``watch`` :ref:`requisite <requisites>`. It should not be called directly. Parameters for this function should be set by the state being triggered. ''' return running( name, restart=restart, update=update, user=user, conf_file=conf_file, bin_env=bin_env )