Exemple #1
0
 def __init__(self,
              scan_dirs,
              service_dirs,
              policy_impl,
              down_action,
              event_hook=None):
     self._dirwatcher = None
     self._down_action = down_action
     self._down_reasons = collections.deque()
     self._event_hook = event_hook
     self._policy_impl = policy_impl
     self._services = list(utils.get_iterable(service_dirs))
     self._scan_dirs = set(utils.get_iterable(scan_dirs))
     self._service_policies = {}
Exemple #2
0
def control_svscan(scan_dir, actions):
    """Sends a control signal to a svscan instance."""
    action_str = '-'
    for action in utils.get_iterable(actions):
        action_str += action.value

    subproc.check_call([_get_cmd('svscanctl'), action_str, scan_dir])
Exemple #3
0
def control_service(service_dir, actions, wait=None, timeout=0):
    """Sends a control signal to the supervised process.

    :returns:
        ``True`` - Command was successuful.
        ``False`` - Command timedout (only if `wait` was provided).
    :raises ``subproc.CalledProcessError``:
        With `returncode` set to `ERR_NO_SUP` if the service is not supervised.
        With `returncode` set to `ERR_COMMAND` if there is a problem
        communicating with the supervisor.
    """
    cmd = [_get_cmd('svc')]

    if wait:
        cmd.append('-w' + _get_wait_action(wait).value)
        if timeout > 0:
            cmd.extend(['-T{}'.format(timeout)])

    action_str = '-'
    for action in utils.get_iterable(actions):
        action_str += action.value

    cmd.append(action_str)
    cmd.append(service_dir)

    try:
        subproc.check_call(cmd)

    except subproc.CalledProcessError as err:
        if err.returncode == ERR_TIMEOUT:
            return False
        else:
            raise

    return True
Exemple #4
0
    def _sync(self):
        """Initial sync of placement."""
        self._servers_watch.sync()
        self._synced = True

        dn_mapping = {}
        conn = None
        for server_info in self._servers_watch.get_all_server_info():
            dn_mapping[server_info[servers.DN_KEY]] = server_info

            if conn is None:
                conn = self._servers_watch.get_ldap_connection(server_info)

        if conn is None:
            _LOGGER.error('No ldap connection information available')
            return

        conn.search(
            search_base=self._config.group_ou,
            search_filter='(objectclass=group)',
            attributes=['samAccountName', 'member']
        )

        if not _check_ldap3_operation(conn):
            _LOGGER.error('Failed to get groups from AD')
            return

        all_proids = {}
        for entry in conn.response:
            match = self._config.parse_group_name(
                entry['attributes']['samAccountName'])

            if match is None:
                continue

            members = set()
            if 'member' in entry['attributes']:
                members = set(utils.get_iterable(
                    entry['attributes']['member']))

            all_proids[match] = members

        for proid in all_proids:
            server_dn_set = set(
                k for (k, v) in self._get_server_dn_set(proid).items()
            )
            actual_dn_set = all_proids[proid]
            _LOGGER.debug('Sync proid %s, expected %r - actual %r', proid,
                          server_dn_set, actual_dn_set)

            diff = server_dn_set.symmetric_difference(actual_dn_set)
            for dn in diff:
                if dn not in dn_mapping:
                    continue

                if dn in server_dn_set:
                    self._add_dn_to_proid_group(conn, dn, proid, force=True)
                else:
                    self._remove_dn_from_proid_group(conn, dn, proid,
                                                     force=True)
Exemple #5
0
def wait_service(service_dirs, action, all_services=True, timeout=0):
    """Performs a wait task on the given list of service directories.
    """
    cmd = [_get_cmd('svwait')]

    if timeout > 0:
        cmd.extend(['-t{}'.format(timeout)])

    if not all_services:
        cmd.append('-o')

    cmd.append('-' + _get_wait_action(action).value)
    cmd.extend(utils.get_iterable(service_dirs))

    subproc.check_call(cmd)
Exemple #6
0
def unmount(target, mnt_flags=()):
    """Umount ``target``.
    """
    target = target.encode()

    mnt_flags = utils.get_iterable(mnt_flags)
    mnt_flags = six.moves.reduce(operator.or_, mnt_flags, 0)

    _LOGGER.debug('umount(%r, %r)', target,
                  utils.parse_mask(mnt_flags, MNTFlags))

    if not mnt_flags:
        return _umount(target)

    else:
        return _umount2(target, mnt_flags)
Exemple #7
0
def mount(source,
          target,
          fs_type,
          *mnt_opts_args,
          mnt_flags=(),
          **mnt_opts_kwargs):
    """Mount ``source`` on ``target`` using filesystem type ``fs_type`` and
    mount flags ``mnt_flags``.

    NOTE: Mount data argument is not supported.

    :params `str` source:
        What to mount
    :params `str` target:
        Where to mount it
    """
    if source is not None:
        source = source.encode()
    if target is not None:
        target = target.encode()
    else:
        target = source
    if fs_type is not None:
        fs_type = fs_type.encode()

    # Fix up mount flags
    mnt_flags = utils.get_iterable(mnt_flags)
    flags = int(six.moves.reduce(operator.or_, mnt_flags, MS_MGC_VAL))
    # Fix up mount options
    options = ','.join(
        itertools.chain(mnt_opts_args,
                        ('%s=%s' % (key, value)
                         for (key, value) in six.iteritems(mnt_opts_kwargs))))
    if options:
        options = options.encode()
    else:
        options = None

    _LOGGER.debug('mount(%r, %r, %r, %r, %r)', source, target, fs_type,
                  utils.parse_mask(flags, MSFlags), options)

    return _mount(source, target, fs_type, flags, options)
Exemple #8
0
    def query_spn(self, proid):
        """ Return list of spn registered for a GMSA
        On success return a dict:
            {
                'dn': dn,
                'spn': [spn]
            }
        On failure throw exception
        """
        gmsa_obj = self._get_gmsa_obj(proid)
        if gmsa_obj:
            result = {'dn': gmsa_obj['dn'], 'spn': []}
            if 'servicePrincipalName' in gmsa_obj['attributes']:
                result['spn'].extend(
                    utils.get_iterable(
                        gmsa_obj['attributes']['servicePrincipalName']))

            return result
        else:
            raise RuntimeError('GMSA \'{}\' not found'.format(proid))
Exemple #9
0
def control_service(service_dir, actions, wait=None, timeout=0):
    """Sends a control signal to the supervised process.

    :returns:
        ``True`` - Command was successuful.
        ``False`` - Command timedout (only if `wait` was provided).
    :raises ``subproc.CalledProcessError``:
        With `returncode` set to `ERR_NO_SUP` if the service is not supervised.
        With `returncode` set to `ERR_COMMAND` if there is a problem
        communicating with the supervisor.
    """
    cmd = [_get_cmd('svc')]

    # XXX: A bug in s6 2.6.0.0 causes svc command to hang if the service is not
    #      supervised. Disable for now.
    #      This does not happen in winss but we are keeping consitent.
    # if wait:
    #     cmd.append('-w' + _get_wait_action(wait).value)
    #     if timeout > 0:
    #         cmd.extend(['-T{}'.format(timeout)])

    action_str = '-'
    for action in utils.get_iterable(actions):
        action_str += action.value

    cmd.append(action_str)
    cmd.append(service_dir)

    try:
        subproc.check_call(cmd)
        # XXX: Remove below when above bug is fixed.
        if wait is not None:
            wait_service(service_dir, wait, timeout=timeout)

    except subproc.CalledProcessError as err:
        if err.returncode == ERR_TIMEOUT:
            return False
        else:
            raise

    return True
Exemple #10
0
    def host_in_proid_group(self, proid):
        """Checks that the current host is a member of the proid group.
        """
        conn = servers.create_ldap_connection(self._dc)

        conn.search(search_base=self._config.group_ou,
                    search_filter='(cn={})'.format(
                        self._config.get_group_name(proid)),
                    attributes=['member'])

        if not _check_ldap3_operation(conn):
            _LOGGER.error('Failed to get groups from AD')
            return False

        entry = conn.response[0]

        if 'member' in entry['attributes']:
            for member in utils.get_iterable(entry['attributes']['member']):
                if member.lower() == self._dn:
                    return True

        return False
Exemple #11
0
def _interpolate_service_conf(resource_path, service_conf, name, params):
    """Interpolates the service config.
    """
    params['name'] = name
    new_service_conf = {'name': name}

    if 'command' not in service_conf:
        raise Exception('Service def did not include command: %s' %
                        resource_path)

    new_service_conf['command'] = _interpolate_scalar(
        service_conf.get('command'), params)

    monitor_policy = service_conf.get('monitor_policy', None)
    if monitor_policy is not None:
        monitor_policy = _interpolate_dict(monitor_policy, params)
        if 'tombstone' not in monitor_policy or \
                'path' not in monitor_policy['tombstone']:
            raise Exception('Service def ombstone path missing: %s' %
                            resource_path)

        tombstone_path = monitor_policy['tombstone']['path']
        tombstone_path = _interpolate_scalar(tombstone_path, params)

        tombstone_id = monitor_policy['tombstone'].get('id', name)
        tombstone_id = _interpolate_scalar(tombstone_id, params)

        new_policy = {
            'limit': int(monitor_policy.get('limit', 0)),
            'interval': int(monitor_policy.get('interval', 60)),
            'tombstone': {
                'uds':
                False,
                'path':
                tombstone_path,
                'id':
                tombstone_id,
                'no_exit_info':
                monitor_policy['tombstone'].get('no_exit_info', False)
            }
        }

        monitor_policy = new_policy

    new_service_conf['monitor_policy'] = monitor_policy
    new_service_conf['userid'] = _interpolate_scalar(
        service_conf.get('user', 'root'), params)
    new_service_conf['downed'] = service_conf.get('downed', False)
    new_service_conf['environ_dir'] = _interpolate_scalar(
        service_conf.get('environ_dir', None), params)
    new_service_conf['environ'] = _interpolate(
        service_conf.get('environ', None), params)
    new_service_conf['notification_fd'] = service_conf.get(
        'notification_fd', None)
    new_service_conf['call_before_run'] = _interpolate(
        service_conf.get('call_before_run', None), params)
    new_service_conf['call_before_finish'] = _interpolate(
        service_conf.get('call_before_finish', None), params)
    new_service_conf['logger_args'] = service_conf.get('logger_args', None)

    files = []
    data_dir = service_conf.get('data_dir', None)
    if data_dir is not None:
        for item in utils.get_iterable(data_dir):
            if 'path' not in item:
                continue

            file = {'path': item['path']}

            content = ''
            if 'content' in item:
                content = _interpolate_scalar(item['content'], params)

            file['content'] = content
            file['executable'] = item.get('executable', False)

            files.append(file)

    new_service_conf['data_dir'] = files

    del params['name']

    _LOGGER.debug('Service config for %s: %r', name, new_service_conf)
    return new_service_conf