예제 #1
0
파일: dark_reaper.py 프로젝트: kbg/rucio
def run(total_workers=1, chunk_size=100, once=False, rses=[], scheme=None,
        exclude_rses=None, include_rses=None, delay_seconds=0, all_rses=False):
    """
    Starts up the reaper threads.

    :param total_workers: The total number of workers.
    :param chunk_size: the size of chunk for deletion.
    :param threads_per_worker: Total number of threads created by each worker.
    :param once: If True, only runs one iteration of the main loop.
    :param greedy: If True, delete right away replicas with tombstone.
    :param rses: List of RSEs the reaper should work against. If empty, it considers all RSEs.
    :param scheme: Force the reaper to use a particular protocol/scheme, e.g., mock.
    :param exclude_rses: RSE expression to exclude RSEs from the Reaper.
    :param include_rses: RSE expression to include RSEs.
    """
    logging.info('main: starting processes')

    if all_rses:
        rses = list_rses()
    elif not rses:
        rses = [rse['id'] for rse in rse_core.list_rses()]

    threads = []
    for worker in range(total_workers):
        kwargs = {'worker_number': worker,
                  'total_workers': total_workers,
                  'rses': rses,
                  'once': once,
                  'chunk_size': chunk_size,
                  'scheme': scheme}
        threads.append(threading.Thread(target=reaper, kwargs=kwargs, name='Worker: %s, Total_Workers: %s' % (worker, total_workers)))
    [t.start() for t in threads]
    while threads[0].is_alive():
        [t.join(timeout=3.14) for t in threads]
예제 #2
0
    def __init__(self, path=''):
        try:
            self.model = json.load(open(path, 'r'))
        except IOError:
            self.model = {
                "STANDARD_LINK": {
                    "r2": 0.0,
                    "rmse": 0.0,
                    "rate": 23399639.38262837,
                    "datalen": 0.0,
                    "overhead": 12.025538382153206,
                    "diskrw": 12046990.897099394
                }
            }

        # Create RSE to site name dictionary
        self._rse2site = {}
        self._rseid2site = {}
        self._site2rses = {}
        self._site2rseids = {}

        for rse in list_rses():
            if rse['deleted'] is False:
                attribs = list_rse_attributes(rse['rse'])
                try:
                    self._rse2site[rse['rse']] = attribs['site']
                    self._rseid2site[rse['id']] = attribs['site']
                except KeyError:
                    continue
                if attribs['site'] not in list(self._site2rses.keys()):
                    self._site2rses[attribs['site']] = []
                    self._site2rseids[attribs['site']] = []
                self._site2rses[attribs['site']].append(rse['rse'])
                self._site2rseids[attribs['site']].append(rse['id'])
예제 #3
0
파일: reaper.py 프로젝트: rcarpa/rucio
def get_rses_to_hostname_mapping():
    """
    Return a dictionaries mapping the RSEs to the hostname of the SE

    :returns:      Dictionary with RSE_id as key and (hostname, rse_info) as value
    """

    result = REGION.get('rse_hostname_mapping')
    if result is NO_VALUE:
        result = {}
        all_rses = list_rses()
        for rse in all_rses:
            try:
                rse_protocol = get_rse_protocols(rse_id=rse['id'])
            except RSENotFound:
                logging.log(
                    logging.WARNING,
                    'RSE deleted while constructing rse-to-hostname mapping. Skipping %s',
                    rse['rse'])
                continue

            for prot in rse_protocol['protocols']:
                if prot['domains']['wan']['delete'] == 1:
                    result[rse['id']] = (prot['hostname'], rse_protocol)
            if rse['id'] not in result:
                logging.log(logging.WARNING,
                            'No default delete protocol for %s', rse['rse'])

        REGION.set('rse_hostname_mapping', result)
        return result

    return result
예제 #4
0
 def test_all_rse(self):
     """ RSE_EXPRESSION_PARSER (CORE) Test reference on all RSE """
     all_rses = rse.list_rses()
     assert_equal(
         sorted(rse_expression_parser.parse_expression("*"),
                key=lambda rse: rse['rse']),
         sorted(all_rses, key=lambda rse: rse['rse']))
예제 #5
0
    def test_export_rest(self):
        """ EXPORT (REST): Test the export of data."""
        mw = []
        headers1 = {
            'X-Rucio-Account': 'root',
            'X-Rucio-Username': '******',
            'X-Rucio-Password': '******'
        }
        r1 = TestApp(auth_app.wsgifunc(*mw)).get('/userpass',
                                                 headers=headers1,
                                                 expect_errors=True)
        token = str(r1.header('X-Rucio-Auth-Token'))
        headers2 = {
            'X-Rucio-Type': 'user',
            'X-Rucio-Account': 'root',
            'X-Rucio-Auth-Token': str(token)
        }

        r2 = TestApp(export_app.wsgifunc(*mw)).get('/',
                                                   headers=headers2,
                                                   expect_errors=True)
        rses = [export_rse(rse['rse']) for rse in list_rses()]
        assert_equal(r2.status, 200)
        assert_equal(
            r2.body,
            render_json(**{
                'rses': rses,
                'distances': export_distances()
            }))
예제 #6
0
파일: reaper2.py 프로젝트: openmsi/rucio
def get_rses_to_process(rses, include_rses, exclude_rses, vos):
    """
    Return the list of RSEs to process based on rses, include_rses and exclude_rses

    :param rses:               List of RSEs the reaper should work against. If empty, it considers all RSEs.
    :param exclude_rses:       RSE expression to exclude RSEs from the Reaper.
    :param include_rses:       RSE expression to include RSEs.
    :param vos:                VOs on which to look for RSEs. Only used in multi-VO mode.
                               If None, we either use all VOs if run from "def",

    :returns: A list of RSEs to process
    """
    multi_vo = config_get_bool('common', 'multi_vo', raise_exception=False, default=False)
    if not multi_vo:
        if vos:
            logging.log(logging.WARNING, 'Ignoring argument vos, this is only applicable in a multi-VO setup.')
        vos = ['def']
    else:
        if vos:
            invalid = set(vos) - set([v['vo'] for v in list_vos()])
            if invalid:
                msg = 'VO{} {} cannot be found'.format('s' if len(invalid) > 1 else '', ', '.join([repr(v) for v in invalid]))
                raise VONotFound(msg)
        else:
            vos = [v['vo'] for v in list_vos()]
        logging.log(logging.INFO, 'Reaper: This instance will work on VO%s: %s' % ('s' if len(vos) > 1 else '', ', '.join([v for v in vos])))

    cache_key = 'rses_to_process'
    if multi_vo:
        cache_key += '@%s' % '-'.join(vo for vo in vos)
    result = REGION.get(cache_key)
    if result is not NO_VALUE:
        return result

    all_rses = []
    for vo in vos:
        all_rses.extend(list_rses(filters={'vo': vo}))

    if rses:
        invalid = set(rses) - set([rse['rse'] for rse in all_rses])
        if invalid:
            msg = 'RSE{} {} cannot be found'.format('s' if len(invalid) > 1 else '',
                                                    ', '.join([repr(rse) for rse in invalid]))
            raise RSENotFound(msg)
        rses = [rse for rse in all_rses if rse['rse'] in rses]
    else:
        rses = all_rses

    if include_rses:
        included_rses = parse_expression(include_rses)
        rses = [rse for rse in rses if rse in included_rses]

    if exclude_rses:
        excluded_rses = parse_expression(exclude_rses)
        rses = [rse for rse in rses if rse not in excluded_rses]

    REGION.set(cache_key, rses)
    logging.log(logging.INFO, 'Reaper: This instance will work on RSEs: %s', ', '.join([rse['rse'] for rse in rses]))
    return rses
예제 #7
0
 def test_all_rse(self):
     """ RSE_EXPRESSION_PARSER (CORE) Test reference on all RSE """
     all_rses = rse.list_rses(filters=self.filter['filter_'])
     value = sorted(rse_expression_parser.parse_expression(
         "*", **self.filter),
                    key=lambda rse: rse['rse'])
     expected = sorted(all_rses, key=lambda rse: rse['rse'])
     assert value == expected
예제 #8
0
def get_conveyor_rses(rses=None, include_rses=None, exclude_rses=None, vos=None, logger=logging.log):
    """
    Get a list of rses for conveyor

    :param rses:          List of rses (Single-VO only)
    :param include_rses:  RSEs to include
    :param exclude_rses:  RSEs to exclude
    :param vos:           VOs on which to look for RSEs. Only used in multi-VO mode.
                          If None, we either use all VOs if run from "def", or the current VO otherwise.
    :param logger:        Optional decorated logger that can be passed from the calling daemons or servers.
    :return:              List of working rses
    """
    multi_vo = config_get_bool('common', 'multi_vo', raise_exception=False, default=False)
    if not multi_vo:
        if vos:
            logger(logging.WARNING, 'Ignoring argument vos, this is only applicable in a multi-VO setup.')
        vos = ['def']
    else:
        if vos:
            invalid = set(vos) - set([v['vo'] for v in list_vos()])
            if invalid:
                msg = 'VO{} {} cannot be found'.format('s' if len(invalid) > 1 else '', ', '.join([repr(v) for v in invalid]))
                raise VONotFound(msg)
        else:
            vos = [v['vo'] for v in list_vos()]
        logger(logging.INFO, 'This instance will work on VO%s: %s' % ('s' if len(vos) > 1 else '', ', '.join([v for v in vos])))

    working_rses = []
    rses_list = []
    for vo in vos:
        rses_list.extend(list_rses(filters={'vo': vo}))
    if rses:
        working_rses = [rse for rse in rses_list if rse['rse'] in rses]

    if include_rses:
        for vo in vos:
            try:
                parsed_rses = parse_expression(include_rses, filter={'vo': vo}, session=None)
            except InvalidRSEExpression:
                logger(logging.ERROR, "Invalid RSE exception %s to include RSEs", include_rses)
            else:
                for rse in parsed_rses:
                    if rse not in working_rses:
                        working_rses.append(rse)

    if not (rses or include_rses):
        working_rses = rses_list

    if exclude_rses:
        try:
            parsed_rses = parse_expression(exclude_rses, session=None)
        except InvalidRSEExpression as error:
            logger(logging.ERROR, "Invalid RSE exception %s to exclude RSEs: %s", exclude_rses, error)
        else:
            working_rses = [rse for rse in working_rses if rse not in parsed_rses]

    working_rses = [rsemgr.get_rse_info(rse_id=rse['id']) for rse in working_rses]
    return working_rses
예제 #9
0
def list_rses(filters=None):
    """
    Lists all RSEs.

    :param filters: dictionary of attributes by which the results should be filtered.

    :returns: List of all RSEs.
    """

    return rse_module.list_rses(filters=filters)
예제 #10
0
 def test_export_client(self):
     """ EXPORT (CLIENT): Test the export of data."""
     export_client = ExportClient()
     data = export_client.export_data()
     rses = {}
     for rse in list_rses():
         rse_name = rse['rse']
         rses[rse_name] = export_rse(rse_name)
     assert_equal(data['rses'], parse_response(render_json(**rses)))
     assert_equal(data['distances'], parse_response(render_json(**export_distances())))
예제 #11
0
파일: rse.py 프로젝트: pombredanne/rucio
def list_rses(filters=None):
    """
    Lists all RSEs.

    :param filters: dictionary of attributes by which the results should be filtered.

    :returns: List of all RSEs.
    """

    return rse_module.list_rses(filters=filters)
예제 #12
0
파일: rse.py 프로젝트: ijjorama/rucio
def list_rses(filters={}, vo='def'):
    """
    Lists all RSEs.

    :param filters: dictionary of attributes by which the results should be filtered.
    :param vo: The VO to act on.

    :returns: List of all RSEs.
    """
    filters['vo'] = vo
    return rse_module.list_rses(filters=filters)
예제 #13
0
파일: common.py 프로젝트: zzaiin/Rucio
def get_undeterministic_rses():
    key = 'undeterministic_rses'
    result = region.get(key)
    if type(result) is NoValue:
        rses_list = rse_core.list_rses(filters={'deterministic': 0})
        result = [rse['id'] for rse in rses_list]
        try:
            region.set(key, result)
        except:
            logging.warning("Failed to set dogpile cache, error: %s" % (traceback.format_exc()))
    return result
예제 #14
0
 def resolve_elements(self, session):
     """
     Inherited from :py:func:`BaseExpressionElement.resolve_elements`
     """
     output = list_rses({self.key: self.value}, session=session)
     if not output:
         return (set(), {})
     rse_dict = {}
     for rse in output:
         rse_dict[rse['id']] = rse
     return (set([rse['id'] for rse in output]), rse_dict)
예제 #15
0
 def resolve_elements(self, session):
     """
     Inherited from :py:func:`BaseExpressionElement.resolve_elements`
     """
     output = list_rses({self.key: self.value}, session=session)
     if not output:
         return (set(), {})
     rse_dict = {}
     for rse in output:
         rse_dict[rse['id']] = rse
     return (set([rse['id'] for rse in output]), rse_dict)
예제 #16
0
def export_rses(session=None):
    """
    Export RSE data.

    :param session: database session in use.
    """
    data = {}
    for rse in rse_module.list_rses(session=session):
        rse_name = rse['rse']
        data[rse_name] = rse_module.export_rse(rse_name, session=session)

    return data
예제 #17
0
파일: exporter.py 프로젝트: wdconinc/rucio
def export_rses(vo='def', session=None):
    """
    Export RSE data.

    :param vo: The VO to export.
    :param session: database session in use.
    """
    data = {}
    for rse in rse_module.list_rses(filters={'vo': vo}, session=session):
        rse_id = rse['id']
        data[rse_id] = rse_module.export_rse(rse_id, session=session)

    return data
예제 #18
0
파일: reaper.py 프로젝트: pombredanne/rucio
def run(total_workers=1, chunk_size=100, threads_per_worker=None, once=False, greedy=False, rses=[], scheme=None, exclude_rses=None, include_rses=None, delay_seconds=0):
    """
    Starts up the reaper threads.

    :param total_workers: The total number of workers.
    :param chunk_size: the size of chunk for deletion.
    :param threads_per_worker: Total number of threads created by each worker.
    :param once: If True, only runs one iteration of the main loop.
    :param greedy: If True, delete right away replicas with tombstone.
    :param rses: List of RSEs the reaper should work against. If empty, it considers all RSEs.
    :param scheme: Force the reaper to use a particular protocol/scheme, e.g., mock.
    :param exclude_rses: RSE expression to exclude RSEs from the Reaper.
    :param include_rses: RSE expression to include RSEs.
    """
    logging.info('main: starting processes')

    rses_list = rse_core.list_rses()
    if rses:
        rses = [rse for rse in rses_list if rse['rse'] in rses]
    else:
        rses = rses_list

    if exclude_rses:
        excluded_rses = parse_expression(exclude_rses)
        rses = [rse for rse in rses if rse not in excluded_rses]

    if include_rses:
        included_rses = parse_expression(include_rses)
        rses = [rse for rse in rses if rse in included_rses]

    logging.info('Reaper: This instance will work on RSEs: ' + ', '.join([rse['rse'] for rse in rses]))

    threads = []
    nb_rses_per_worker = int(math.ceil(len(rses) / float(total_workers))) or 1.0
    for worker in xrange(total_workers):
        for child in xrange(threads_per_worker or 1):
            kwargs = {'worker_number': worker,
                      'child_number': child + 1,
                      'total_children': threads_per_worker or 1,
                      'once': once,
                      'chunk_size': chunk_size,
                      'greedy': greedy,
                      'rses': rses[worker * nb_rses_per_worker: worker * nb_rses_per_worker + nb_rses_per_worker],
                      'delay_seconds': delay_seconds,
                      'scheme': scheme}
            threads.append(threading.Thread(target=reaper, kwargs=kwargs))
    [t.start() for t in threads]
    while threads[0].is_alive():
        [t.join(timeout=3.14) for t in threads]
예제 #19
0
def export_data(session=None):
    """
    Export data.

    :param session: database session in use.
    """
    data = {
        'rses': [
            rse_module.export_rse(rse['rse'], session=session)
            for rse in rse_module.list_rses(session=session)
        ],
        'distances':
        distance_module.export_distances(session=session)
    }
    return data
예제 #20
0
def get_rses(rses=None, include_rses=None, exclude_rses=None):
    working_rses = []
    rses_list = rse_core.list_rses()
    if rses:
        working_rses = [rse for rse in rses_list if rse['rse'] in rses]

    if include_rses:
        try:
            parsed_rses = parse_expression(include_rses, session=None)
        except InvalidRSEExpression, e:
            logging.error("Invalid RSE exception %s to include RSEs" % (include_rses))
        else:
            for rse in parsed_rses:
                if rse not in working_rses:
                    working_rses.append(rse)
예제 #21
0
def get_rses_to_process(rses, include_rses, exclude_rses):
    """
    Return the list of RSEs to process based on rses, include_rses and exclude_rses

    :param rses:               List of RSEs the reaper should work against. If empty, it considers all RSEs.
    :param exclude_rses:       RSE expression to exclude RSEs from the Reaper.
    :param include_rses:       RSE expression to include RSEs.

    :returns: A list of RSEs to process
    """
    result = REGION.get('rses_to_process')
    if result is not NO_VALUE:
        return result

    all_rses = list_rses()

    if rses:
        if config_get_bool('common',
                           'multi_vo',
                           raise_exception=False,
                           default=False):
            logging.warning(
                'Ignoring argument rses, this is only available in a single-VO setup. Please try an RSE Expression with include_rses if it is required.'
            )
            rses = all_rses
        else:
            invalid = set(rses) - set([rse['rse'] for rse in all_rses])
            if invalid:
                msg = 'RSE{} {} cannot be found'.format(
                    's' if len(invalid) > 1 else '',
                    ', '.join([repr(rse) for rse in invalid]))
                raise RSENotFound(msg)
            rses = [rse for rse in all_rses if rse['rse'] in rses]
    else:
        rses = all_rses

    if include_rses:
        included_rses = parse_expression(include_rses)
        rses = [rse for rse in rses if rse in included_rses]

    if exclude_rses:
        excluded_rses = parse_expression(exclude_rses)
        rses = [rse for rse in rses if rse not in excluded_rses]

    REGION.set('rses_to_process', rses)
    logging.info('Reaper: This instance will work on RSEs: %s',
                 ', '.join([rse['rse'] for rse in rses]))
    return rses
예제 #22
0
def list_rses(filters={}, vo='def', session=None):
    """
    Lists all RSEs.

    :param filters: dictionary of attributes by which the results should be filtered.
    :param vo: The VO to act on.
    :param session: The database session in use.

    :returns: List of all RSEs.
    """
    if not filters:
        filters = {}

    filters['vo'] = vo

    return rse_module.list_rses(filters=filters, session=session)
예제 #23
0
def __get_undeterministic_rses():
    """
    Get the undeterministic rses from the database

    :returns:  List of undeterministc rses
    """
    key = 'undeterministic_rses'
    result = region.get(key)
    if isinstance(result, NoValue):
        rses_list = list_rses(filters={'deterministic': False})
        result = [rse['id'] for rse in rses_list]
        try:
            region.set(key, result)
        except Exception as error:
            logging.warning("Failed to set dogpile cache, error: %s", str(error))
    return result
    def sync_accounts(self, iam_users):

        for user in iam_users:

            username = user['userName']
            email = user['emails'][0]['value']

            if not user['active']:
                logging.debug(
                    'Skipped account creation for User {} [not active]'.format(
                        username))
                continue

            # Rucio DB schema restriction
            if len(username) > 25:
                logging.debug(
                    'Skipped account creation for User {} [len(username) > 25]'
                    .format(username))
                continue

            if not account.account_exists(InternalAccount(username)):
                account.add_account(InternalAccount(username),
                                    AccountType.SERVICE, email)
                logging.debug(
                    'Created account for User {} ***'.format(username))

                # Give account quota for all RSEs
                for rse_obj in rse.list_rses():
                    set_local_account_limit(InternalAccount(username),
                                            rse_obj['id'], 1000000000000)

                # Make the user an admin & able to sign URLs
                try:
                    add_account_attribute(InternalAccount(username), 'admin',
                                          'True')
                    add_account_attribute(InternalAccount(username),
                                          'sign-gcs', 'True')
                except Exception as e:
                    logging.debug(e)

            if "groups" in user:
                for group in user['groups']:
                    group_name = group['display']
                    if not account.has_account_attribute(
                            InternalAccount(username), group_name):
                        add_account_attribute(InternalAccount(username),
                                              group_name, 'True')
예제 #25
0
def __get_undeterministic_rses():
    """
    Get the undeterministic rses from the database

    :returns:  List of undeterministc rses
    """
    key = 'undeterministic_rses'
    result = region.get(key)
    if type(result) is NoValue:
        rses_list = list_rses(filters={'deterministic': False})
        result = [rse['id'] for rse in rses_list]
        try:
            region.set(key, result)
        except:
            logging.warning("Failed to set dogpile cache, error: %s" %
                            (traceback.format_exc()))
    return result
    def get_authfile_prefixes(self):
        session = get_session()
        session.connection()

        prefixes = set()
        for rse in list_rses():
            rse_id = rse['id']
            protocols = get_rse_protocols(rse_id)
            if 'protocols' in protocols:
                for protocol in protocols['protocols']:
                    scheme = protocol['scheme']
                    hostname = protocol['hostname']
                    port = protocol['port']
                    prefix = self.clean_prefix_path(protocol['prefix'])
                    authfile_prefix = f"/{scheme}:/{hostname}:{port}/{prefix}"
                    prefixes.add(authfile_prefix)
        return list(prefixes)
예제 #27
0
def __get_unavailable_read_rse_ids(session=None):
    """
    Get unavailable read rse ids
    """

    key = 'unavailable_read_rse_ids'
    result = REGION_SHORT.get(key)
    if type(result) is NoValue:
        try:
            logging.debug("Refresh unavailable read rses")
            unavailable_read_rses = list_rses(filters={'availability_read': False}, session=session)
            unavailable_read_rse_ids = [r['id'] for r in unavailable_read_rses]
            REGION_SHORT.set(key, unavailable_read_rse_ids)
            return unavailable_read_rse_ids
        except Exception:
            logging.warning("Failed to refresh unavailable read rses, error: %s" % (traceback.format_exc()))
            return []
    return result
예제 #28
0
def get_conveyor_rses(rses=None, include_rses=None, exclude_rses=None):
    """
    Get a list of rses for conveyor

    :param rses:          List of rses
    :param include_rses:  RSEs to include
    :param exclude_rses:  RSEs to exclude
    :return:              List of working rses
    """
    working_rses = []
    rses_list = list_rses()
    if rses:
        working_rses = [rse for rse in rses_list if rse['rse'] in rses]

    if include_rses:
        try:
            parsed_rses = parse_expression(include_rses, session=None)
        except InvalidRSEExpression as error:
            logging.error("Invalid RSE exception %s to include RSEs" %
                          (include_rses))
        else:
            for rse in parsed_rses:
                if rse not in working_rses:
                    working_rses.append(rse)

    if not (rses or include_rses):
        working_rses = rses_list

    if exclude_rses:
        try:
            parsed_rses = parse_expression(exclude_rses, session=None)
        except InvalidRSEExpression as error:
            logging.error("Invalid RSE exception %s to exclude RSEs: %s" %
                          (exclude_rses, error))
        else:
            working_rses = [
                rse for rse in working_rses if rse not in parsed_rses
            ]

    working_rses = [rsemgr.get_rse_info(rse['rse']) for rse in working_rses]
    return working_rses
예제 #29
0
파일: common.py 프로젝트: pic-es/rucio
def get_conveyor_rses(rses=None, include_rses=None, exclude_rses=None):
    """
    Get a list of rses for conveyor

    :param rses:          List of rses (Single-VO only)
    :param include_rses:  RSEs to include
    :param exclude_rses:  RSEs to exclude
    :return:              List of working rses
    """
    working_rses = []
    rses_list = list_rses()
    if rses:
        if config_get_bool('common', 'multi_vo', raise_exception=False, default=False):
            logging.warning('Ignoring argument rses, this is only available in a single-vo setup. Please try an RSE Expression with include_rses if it is required.')
        else:
            working_rses = [rse for rse in rses_list if rse['rse'] in rses]

    if include_rses:
        try:
            parsed_rses = parse_expression(include_rses, session=None)
        except InvalidRSEExpression as error:
            logging.error("Invalid RSE exception %s to include RSEs", include_rses)
        else:
            for rse in parsed_rses:
                if rse not in working_rses:
                    working_rses.append(rse)

    if not (rses or include_rses):
        working_rses = rses_list

    if exclude_rses:
        try:
            parsed_rses = parse_expression(exclude_rses, session=None)
        except InvalidRSEExpression as error:
            logging.error("Invalid RSE exception %s to exclude RSEs: %s", exclude_rses, error)
        else:
            working_rses = [rse for rse in working_rses if rse not in parsed_rses]

    working_rses = [rsemgr.get_rse_info(rse['id']) for rse in working_rses]
    return working_rses
예제 #30
0
def __get_unavailable_rse_ids(operation, session=None):
    """
    Get unavailable rse ids for a given operation : read, write, delete
    """

    if operation not in ['read', 'write', 'delete']:
        logging.error("Wrong operation specified : %s" % (operation))
        return []
    key = 'unavailable_%s_rse_ids' % operation
    result = REGION_SHORT.get(key)
    if isinstance(result, NoValue):
        try:
            logging.debug("Refresh unavailable %s rses" % operation)
            availability_key = 'availability_%s' % operation
            unavailable_rses = list_rses(filters={availability_key: False}, session=session)
            unavailable_rse_ids = [rse['id'] for rse in unavailable_rses]
            REGION_SHORT.set(key, unavailable_rse_ids)
            return unavailable_rse_ids
        except Exception:
            logging.warning("Failed to refresh unavailable %s rses, error: %s" % (operation, traceback.format_exc()))
            return []
    return result
예제 #31
0
def get_rses_to_process(rses, include_rses, exclude_rses):
    """
    Return the list of RSEs to process based on rses, include_rses and exclude_rses

    :param rses:               List of RSEs the reaper should work against. If empty, it considers all RSEs.
    :param exclude_rses:       RSE expression to exclude RSEs from the Reaper.
    :param include_rses:       RSE expression to include RSEs.

    :returns: A list of RSEs to process
    """
    result = REGION.get('rses_to_process')
    if result is not NO_VALUE:
        return result

    all_rses = list_rses()
    if rses:
        invalid = set(rses) - set([rse['rse'] for rse in all_rses])
        if invalid:
            msg = 'RSE{} {} cannot be found'.format(
                's' if len(invalid) > 1 else '',
                ', '.join([repr(rse) for rse in invalid]))
            raise RSENotFound(msg)
        rses = [rse for rse in all_rses if rse['rse'] in rses]
    else:
        rses = all_rses

    if include_rses:
        included_rses = parse_expression(include_rses)
        rses = [rse for rse in rses if rse in included_rses]

    if exclude_rses:
        excluded_rses = parse_expression(exclude_rses)
        rses = [rse for rse in rses if rse not in excluded_rses]

    REGION.set('rses_to_process', rses)
    logging.info('Reaper: This instance will work on RSEs: %s',
                 ', '.join([rse['rse'] for rse in rses]))
    return rses
예제 #32
0
def get_sources(dest_rse, scheme, req):
    allowed_rses = []
    if req['request_type'] == RequestType.STAGEIN:
        rses = rse_core.list_rses(filters={'staging_buffer': dest_rse['rse']})
        allowed_rses = [x['rse'] for x in rses]

    allowed_source_rses = []
    if req['attributes']:
        if type(req['attributes']) is dict:
            req_attributes = json.loads(json.dumps(req['attributes']))
        else:
            req_attributes = json.loads(str(req['attributes']))
        source_replica_expression = req_attributes["source_replica_expression"]
        if source_replica_expression:
            try:
                parsed_rses = parse_expression(source_replica_expression, session=None)
            except InvalidRSEExpression, e:
                logging.error("Invalid RSE exception %s for request %s: %s" % (source_replica_expression,
                                                                               req['request_id'],
                                                                               e))
                allowed_source_rses = []
            else:
                allowed_source_rses = [x['rse'] for x in parsed_rses]
예제 #33
0
def get_rses_to_hostname_mapping():
    """
    Return a dictionaries mapping the RSEs to the hostname of the SE

    :returns: Dictionary with RSE_id as key and (hostname, rse_info) as value
    """

    result = REGION.get('rse_hostname_mapping')
    if result is NO_VALUE:
        result = {}
        all_rses = list_rses()
        for rse in all_rses:
            rse_protocol = get_rse_protocols(rse_id=rse['id'])
            for prot in rse_protocol['protocols']:
                if prot['domains']['wan']['delete'] == 1:
                    result[rse['id']] = (prot['hostname'], rse_protocol)
            if rse['id'] not in result:
                logging.warn('No default delete protocol for %s', rse['rse'])

        REGION.set('rse_hostname_mapping', result)
        return result

    return result
예제 #34
0
def run(one_worker_per_rse=False, once=False, rses=[], scheme=None, all_os_rses=False, older_than=30, sleep_time=1):
    """
    Starts up the injector threads.

    :param one_worker_per_rse: If True, one worker per RSE; Otherwise, one worker for all RSEs.
    :param once: If True, only runs one iteration of the main loop.
    :param rses: List of RSEs the reaper should work against. If empty, it considers all RSEs.
    :param scheme: Force the reaper to use a particular protocol/scheme, e.g., mock.
    :param all_os_rses: All Objectstore RSEs.
    :param older_than: List control: older objects more than this value of days to list.
    :param sleep_time: Days to sleep.
    """

    logging.info('main: starting processes')

    if all_os_rses:
        rses = []
        for rse in rse_core.list_rses():
            if rse['rse'].endswith('_ES'):
                rses.append(rse['rse'])

    threads = []
    if one_worker_per_rse:
        worker = 0
        for rse in rses:
            kwargs = {'once': once, 'rses': [rse], 'scheme': scheme, 'worker_number': worker, 'total_workers': len(rses),
                      'older_than': older_than, 'sleep_time': sleep_time}
            threads.append(threading.Thread(target=injector, kwargs=kwargs, name='Worker: %s, Total_Workers: %s' % (worker, len(rses))))
            worker += 1
    else:
        kwargs = {'once': once, 'rses': rses, 'scheme': scheme, 'older_than': older_than, 'sleep_time': sleep_time}
        threads.append(threading.Thread(target=injector, kwargs=kwargs, name='Worker: %s, Total_Workers: %s' % (0, 1)))

    [t.start() for t in threads]
    while threads[0].is_alive():
        [t.join(timeout=3.14) for t in threads]
예제 #35
0
from dogpile.cache import make_region

from rucio.core.rse import list_rses, get_rse_protocols

rse_region = make_region().configure(
    'dogpile.cache.memcached',  # 'dogpile.cache.memory'
    expiration_time=1,
    arguments={'url': "127.0.0.1:11211", 'distributed_lock': True},
)


if __name__ == '__main__':

    for rse in list_rses():
        rse_info = get_rse_protocols(rse['rse'])
        print rse['rse'], rse_info
        rse_region.set(str(rse['rse']), rse_info)
        # rse_region.delete(str(rse['rse']))

예제 #36
0
def run(total_workers=1, chunk_size=100, threads_per_worker=None, once=False, greedy=False, rses=[], scheme=None, exclude_rses=None, include_rses=None, vos=None, delay_seconds=0):
    """
    Starts up the reaper threads.

    :param total_workers: The total number of workers.
    :param chunk_size: the size of chunk for deletion.
    :param threads_per_worker: Total number of threads created by each worker.
    :param once: If True, only runs one iteration of the main loop.
    :param greedy: If True, delete right away replicas with tombstone.
    :param rses: List of RSEs the reaper should work against. If empty, it considers all RSEs.
    :param scheme: Force the reaper to use a particular protocol/scheme, e.g., mock.
    :param exclude_rses: RSE expression to exclude RSEs from the Reaper.
    :param include_rses: RSE expression to include RSEs.
    :param vos: VOs on which to look for RSEs. Only used in multi-VO mode.
                If None, we either use all VOs if run from "def", or the current VO otherwise.
    """
    if rucio.db.sqla.util.is_old_db():
        raise DatabaseException('Database was not updated, daemon won\'t start')

    logging.info('Reaper1 daemon will be deprecated and replaced by reaper2 with Rucio release 1.25 (~March 2021)!')
    logging.info('main: starting processes')

    multi_vo = config_get_bool('common', 'multi_vo', raise_exception=False, default=False)
    if not multi_vo:
        if vos:
            logging.warning('Ignoring argument vos, this is only applicable in a multi-VO setup.')
        vos = ['def']
    else:
        if vos:
            invalid = set(vos) - set([v['vo'] for v in list_vos()])
            if invalid:
                msg = 'VO{} {} cannot be found'.format('s' if len(invalid) > 1 else '', ', '.join([repr(v) for v in invalid]))
                raise VONotFound(msg)
        else:
            vos = [v['vo'] for v in list_vos()]
        logging.info('Reaper: This instance will work on VO%s: %s' % ('s' if len(vos) > 1 else '', ', '.join([v for v in vos])))

    all_rses = []
    for vo in vos:
        all_rses.extend(rse_core.list_rses(filters={'vo': vo}))

    if rses:
        invalid = set(rses) - set([rse['rse'] for rse in all_rses])
        if invalid:
            msg = 'RSE{} {} cannot be found'.format('s' if len(invalid) > 1 else '',
                                                    ', '.join([repr(rse) for rse in invalid]))
            raise RSENotFound(msg)
        rses = [rse for rse in all_rses if rse['rse'] in rses]
    else:
        rses = all_rses

    if exclude_rses:
        excluded_rses = parse_expression(exclude_rses)
        rses = [rse for rse in rses if rse not in excluded_rses]

    if include_rses:
        included_rses = parse_expression(include_rses)
        rses = [rse for rse in rses if rse in included_rses]

    if not rses:
        logging.error('Reaper: No RSEs found. Exiting.')
        return

    logging.info('Reaper: This instance will work on RSEs: ' + ', '.join([rse['rse'] for rse in rses]))

    threads = []
    nb_rses_per_worker = int(math.ceil(len(rses) / float(total_workers))) or 1
    rses = random.sample(rses, len(rses))
    for worker in range(total_workers):
        for child in range(threads_per_worker or 1):
            rses_list = rses[worker * nb_rses_per_worker: worker * nb_rses_per_worker + nb_rses_per_worker]
            if not rses_list:
                logging.warning('Reaper: Empty RSEs list for worker %(worker)s' % locals())
                continue
            kwargs = {'worker_number': worker,
                      'child_number': child,
                      'total_children': threads_per_worker or 1,
                      'once': once,
                      'chunk_size': chunk_size,
                      'greedy': greedy,
                      'rses': rses_list,
                      'delay_seconds': delay_seconds,
                      'scheme': scheme}
            threads.append(threading.Thread(target=reaper, kwargs=kwargs, name='Worker: %s, child: %s' % (worker, child)))
    [t.start() for t in threads]
    while threads[0].is_alive():
        [t.join(timeout=3.14) for t in threads]