Exemplo n.º 1
0
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
Exemplo n.º 2
0
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
Exemplo n.º 3
0
 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)
Exemplo n.º 4
0
 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)
Exemplo n.º 5
0
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}
Exemplo n.º 6
0
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
Exemplo n.º 7
0
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
Exemplo n.º 8
0
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