def _get_systemd_only(func, kwargs): ret = {} warnings = [] valid_args = _argspec(func).args for systemd_arg in SYSTEMD_ONLY: if systemd_arg in kwargs: if systemd_arg in valid_args: ret[systemd_arg] = kwargs[systemd_arg] else: warnings.append( 'The \'{0}\' argument is not supported by this ' 'platform/action'.format(systemd_arg)) return ret, warnings
def _get_systemd_only(func, kwargs): if not hasattr(_get_systemd_only, "HAS_SYSTEMD"): setattr(_get_systemd_only, "HAS_SYSTEMD", booted()) ret = {} warnings = [] valid_args = _argspec(func).args for systemd_arg in SYSTEMD_ONLY: if systemd_arg in kwargs and systemd_arg in valid_args: if _get_systemd_only.HAS_SYSTEMD: ret[systemd_arg] = kwargs[systemd_arg] else: warnings.append("The '{}' argument is not supported by this " "platform".format(systemd_arg)) return ret, warnings
def envs(self, back=None, sources=False): ''' Return the environments for the named backend or all backends ''' back = self.backends(back) ret = set() if sources: ret = {} for fsb in back: fstr = '{0}.envs'.format(fsb) kwargs = {'ignore_cache': True} \ if 'ignore_cache' in _argspec(self.servers[fstr]).args \ and self.opts['__role'] == 'minion' \ else {} if sources: ret[fsb] = self.servers[fstr](**kwargs) else: ret.update(self.servers[fstr](**kwargs)) if sources: return ret return list(ret)
def envs(self, back=None, sources=False): """ Return the environments for the named backend or all backends """ back = self.backends(back) ret = set() if sources: ret = {} for fsb in back: fstr = "{0}.envs".format(fsb) kwargs = ({ "ignore_cache": True } if "ignore_cache" in _argspec(self.servers[fstr]).args and self.opts["__role"] == "minion" else {}) if sources: ret[fsb] = self.servers[fstr](**kwargs) else: ret.update(self.servers[fstr](**kwargs)) if sources: return ret return list(ret)
def get_client_args(): if not HAS_DOCKER_PY: raise CommandExecutionError('docker Python module not imported') try: create_args = _argspec(docker.APIClient.create_container).args except AttributeError: try: create_args = _argspec(docker.Client.create_container).args except AttributeError: raise CommandExecutionError( 'Coult not get create_container argspec' ) try: host_config_args = \ _argspec(docker.types.HostConfig.__init__).args except AttributeError: try: host_config_args = _argspec(docker.utils.create_host_config).args except AttributeError: raise CommandExecutionError( 'Could not get create_host_config argspec' ) try: endpoint_config_args = \ _argspec(docker.types.EndpointConfig.__init__).args except AttributeError: try: endpoint_config_args = \ _argspec(docker.utils.utils.create_endpoint_config).args except AttributeError: try: endpoint_config_args = \ _argspec(docker.utils.create_endpoint_config).args except AttributeError: raise CommandExecutionError( 'Could not get create_endpoint_config argspec' ) for arglist in (create_args, host_config_args, endpoint_config_args): try: # The API version is passed automagically by the API code that # imports these classes/functions and is not an arg that we will be # passing, so remove it if present. arglist.remove('version') except ValueError: pass # Remove any args in host or networking config from the main config dict. # This keeps us from accidentally allowing args that docker-py has moved # from the container config to the host config. for arglist in (host_config_args, endpoint_config_args): for item in arglist: try: create_args.remove(item) except ValueError: # Arg is not in create_args pass return {'create_container': create_args, 'host_config': host_config_args, 'networking_config': endpoint_config_args}
def get_client_args(limit=None): if not HAS_DOCKER_PY: raise CommandExecutionError('docker Python module not imported') limit = salt.utils.args.split_input(limit or []) ret = {} if not limit or any(x in limit for x in ('create_container', 'host_config', 'connect_container_to_network')): try: ret['create_container'] = \ _argspec(docker.APIClient.create_container).args except AttributeError: try: ret['create_container'] = \ _argspec(docker.Client.create_container).args except AttributeError: raise CommandExecutionError( 'Coult not get create_container argspec') try: ret['host_config'] = \ _argspec(docker.types.HostConfig.__init__).args except AttributeError: try: ret['host_config'] = \ _argspec(docker.utils.create_host_config).args except AttributeError: raise CommandExecutionError( 'Could not get create_host_config argspec') try: ret['connect_container_to_network'] = \ _argspec(docker.types.EndpointConfig.__init__).args except AttributeError: try: ret['connect_container_to_network'] = \ _argspec(docker.utils.utils.create_endpoint_config).args except AttributeError: try: ret['connect_container_to_network'] = \ _argspec(docker.utils.create_endpoint_config).args except AttributeError: raise CommandExecutionError( 'Could not get connect_container_to_network argspec') for key, wrapped_func in ( ('logs', docker.api.container.ContainerApiMixin.logs), ('create_network', docker.api.network.NetworkApiMixin.create_network)): if not limit or key in limit: try: func_ref = wrapped_func if six.PY2: try: # create_network is decorated, so we have to dig into the # closure created by functools.wraps ret[key] = \ _argspec(func_ref.__func__.__closure__[0].cell_contents).args except (AttributeError, IndexError): # functools.wraps changed (unlikely), bail out ret[key] = [] else: try: # functools.wraps makes things a little easier in Python 3 ret[key] = _argspec(func_ref.__wrapped__).args except AttributeError: # functools.wraps changed (unlikely), bail out ret[key] = [] except AttributeError: # Function moved, bail out ret[key] = [] if not limit or 'ipam_config' in limit: try: ret['ipam_config'] = _argspec(docker.types.IPAMPool.__init__).args except AttributeError: try: ret['ipam_config'] = _argspec( docker.utils.create_ipam_pool).args except AttributeError: raise CommandExecutionError('Could not get ipam args') for item in ret: # The API version is passed automagically by the API code that imports # these classes/functions and is not an arg that we will be passing, so # remove it if present. Similarly, don't include "self" if it shows up # in the arglist. for argname in ('version', 'self'): try: ret[item].remove(argname) except ValueError: pass # Remove any args in host or endpoint config from the create_container # arglist. This keeps us from accidentally allowing args that docker-py has # moved from the create_container function to the either the host or # endpoint config. for item in ('host_config', 'connect_container_to_network'): for val in ret.get(item, []): try: ret['create_container'].remove(val) except ValueError: # Arg is not in create_container arglist pass for item in ('create_container', 'host_config', 'connect_container_to_network'): if limit and item not in limit: ret.pop(item, None) try: ret['logs'].remove('container') except (KeyError, ValueError, TypeError): pass return ret
def dead(name, enable=None, sig=None, init_delay=None, no_block=False, **kwargs): ''' Ensure that the named service is dead by stopping the service if it is running name The name of the init or rc script used to manage the service enable Set the service to be enabled at boot time, ``True`` sets the service to be enabled, ``False`` sets the named service to be disabled. The default is ``None``, which does not enable or disable anything. sig The string to search for when looking for the service process with ps init_delay Add a sleep command (in seconds) before the check to make sure service is killed. .. versionadded:: Nitrogen no_block : False **For systemd minions only.** Stops the service using ``--no-block``. .. versionadded:: Nitrogen ''' ret = {'name': name, 'changes': {}, 'result': True, 'comment': ''} # Check for common error: using enabled option instead of enable if 'enabled' in kwargs: return _enabled_used_error(ret) # Convert enable to boolean in case user passed a string value if isinstance(enable, six.string_types): enable = salt.utils.is_true(enable) # Check if the service is available try: if not _available(name, ret): # A non-available service is OK here, don't let the state fail # because of it. ret['result'] = True return ret except CommandExecutionError as exc: ret['result'] = False ret['comment'] = exc.strerror return ret # lot of custom init script won't or mis implement the status # command, so it is just an indicator but can not be fully trusted before_toggle_status = __salt__['service.status'](name, sig) if 'service.enabled' in __salt__: before_toggle_enable_status = __salt__['service.enabled'](name) else: before_toggle_enable_status = True # See if the service is already dead if not before_toggle_status: ret['comment'] = 'The service {0} is already dead'.format(name) if enable is True and not before_toggle_enable_status: ret.update(_enable(name, None, **kwargs)) elif enable is False and before_toggle_enable_status: ret.update(_disable(name, None, **kwargs)) return ret # Run the tests if __opts__['test']: ret['result'] = None ret['comment'] = 'Service {0} is set to be killed'.format(name) return ret stop_kwargs = {} if no_block: if 'no_block' in _argspec(__salt__['service.stop']).args: stop_kwargs = {'no_block': no_block} else: ret.setdefault('warnings', []).append( 'The \'no_block\' argument is not supported on this platform.' ) func_ret = __salt__['service.stop'](name, **stop_kwargs) if not func_ret: ret['result'] = False ret['comment'] = 'Service {0} failed to die'.format(name) if enable is True: ret.update(_enable(name, True, result=False, **kwargs)) elif enable is False: ret.update(_disable(name, True, result=False, **kwargs)) return ret if init_delay: time.sleep(init_delay) # only force a change state if we have explicitly detected them after_toggle_status = __salt__['service.status'](name) if 'service.enabled' in __salt__: after_toggle_enable_status = __salt__['service.enabled'](name) else: after_toggle_enable_status = True if ( (before_toggle_enable_status != after_toggle_enable_status) or (before_toggle_status != after_toggle_status) ) and not ret.get('changes', {}): ret['changes'][name] = after_toggle_status # be sure to stop, in case we mis detected in the check if after_toggle_status: ret['result'] = False ret['comment'] = 'Service {0} failed to die'.format(name) else: ret['comment'] = 'Service {0} was killed'.format(name) if enable is True: ret.update(_enable(name, after_toggle_status, result=not after_toggle_status, **kwargs)) elif enable is False: ret.update(_disable(name, after_toggle_status, result=not after_toggle_status, **kwargs)) return ret
def running(name, enable=None, sig=None, init_delay=None, no_block=False, **kwargs): ''' Ensure that the service is running name The name of the init or rc script used to manage the service enable Set the service to be enabled at boot time, ``True`` sets the service to be enabled, ``False`` sets the named service to be disabled. The default is ``None``, which does not enable or disable anything. sig The string to search for when looking for the service process with ps init_delay Some services may not be truly available for a short period after their startup script indicates to the system that they are. Provide an 'init_delay' to specify that this state should wait an additional given number of seconds after a service has started before returning. Useful for requisite states wherein a dependent state might assume a service has started but is not yet fully initialized. no_block : False **For systemd minions only.** Starts the service using ``--no-block``. .. versionadded:: Nitrogen .. note:: ``watch`` can be used with service.running to restart a service when another state changes ( example: a file.managed state that creates the service's config file ). More details regarding ``watch`` can be found in the :ref:`Requisites <requisites>` documentation. ''' ret = {'name': name, 'changes': {}, 'result': True, 'comment': ''} # Check for common error: using enabled option instead of enable if 'enabled' in kwargs: return _enabled_used_error(ret) # Convert enable to boolean in case user passed a string value if isinstance(enable, six.string_types): enable = salt.utils.is_true(enable) # Check if the service is available try: if not _available(name, ret): return ret except CommandExecutionError as exc: ret['result'] = False ret['comment'] = exc.strerror return ret # lot of custom init script won't or mis implement the status # command, so it is just an indicator but can not be fully trusted before_toggle_status = __salt__['service.status'](name, sig) if 'service.enabled' in __salt__: before_toggle_enable_status = __salt__['service.enabled'](name) else: before_toggle_enable_status = True # See if the service is already running if before_toggle_status: ret['comment'] = 'The service {0} is already running'.format(name) if enable is True and not before_toggle_enable_status: ret.update(_enable(name, None, **kwargs)) elif enable is False and before_toggle_enable_status: ret.update(_disable(name, None, **kwargs)) return ret # Run the tests if __opts__['test']: ret['result'] = None ret['comment'] = 'Service {0} is set to start'.format(name) return ret if salt.utils.is_windows(): if enable is True: ret.update(_enable(name, False, result=False, **kwargs)) start_kwargs = {} if no_block: if 'no_block' in _argspec(__salt__['service.start']).args: start_kwargs = {'no_block': no_block} else: ret.setdefault('warnings', []).append( 'The \'no_block\' argument is not supported on this platform.' ) func_ret = __salt__['service.start'](name, **start_kwargs) if not func_ret: ret['result'] = False ret['comment'] = 'Service {0} failed to start'.format(name) if enable is True: ret.update(_enable(name, False, result=False, **kwargs)) elif enable is False: ret.update(_disable(name, False, result=False, **kwargs)) return ret if init_delay: time.sleep(init_delay) # only force a change state if we have explicitly detected them after_toggle_status = __salt__['service.status'](name, sig) if 'service.enabled' in __salt__: after_toggle_enable_status = __salt__['service.enabled'](name) else: after_toggle_enable_status = True if ( (before_toggle_enable_status != after_toggle_enable_status) or (before_toggle_status != after_toggle_status) ) and not ret.get('changes', {}): ret['changes'][name] = after_toggle_status if after_toggle_status: ret['comment'] = 'Started Service {0}'.format(name) else: ret['comment'] = 'Service {0} failed to start'.format(name) if enable is True: ret.update(_enable(name, after_toggle_status, result=after_toggle_status, **kwargs)) elif enable is False: ret.update(_disable(name, after_toggle_status, result=after_toggle_status, **kwargs)) if init_delay: ret['comment'] = ( '{0}\nDelayed return for {1} seconds' .format(ret['comment'], init_delay) ) return ret