rucio 35.7.0__py3-none-any.whl → 37.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of rucio might be problematic. Click here for more details.
- rucio/alembicrevision.py +1 -1
- rucio/{daemons/c3po/collectors → cli}/__init__.py +1 -0
- rucio/cli/account.py +216 -0
- rucio-35.7.0.data/scripts/rucio → rucio/cli/bin_legacy/rucio.py +769 -486
- rucio-35.7.0.data/scripts/rucio-admin → rucio/cli/bin_legacy/rucio_admin.py +476 -423
- rucio/cli/command.py +272 -0
- rucio/cli/config.py +72 -0
- rucio/cli/did.py +191 -0
- rucio/cli/download.py +128 -0
- rucio/cli/lifetime_exception.py +33 -0
- rucio/cli/replica.py +162 -0
- rucio/cli/rse.py +293 -0
- rucio/cli/rule.py +158 -0
- rucio/cli/scope.py +40 -0
- rucio/cli/subscription.py +73 -0
- rucio/cli/upload.py +60 -0
- rucio/cli/utils.py +226 -0
- rucio/client/accountclient.py +0 -1
- rucio/client/baseclient.py +33 -24
- rucio/client/client.py +45 -1
- rucio/client/didclient.py +5 -3
- rucio/client/downloadclient.py +6 -8
- rucio/client/replicaclient.py +0 -2
- rucio/client/richclient.py +317 -0
- rucio/client/rseclient.py +4 -4
- rucio/client/uploadclient.py +26 -12
- rucio/common/bittorrent.py +234 -0
- rucio/common/cache.py +66 -29
- rucio/common/checksum.py +168 -0
- rucio/common/client.py +122 -0
- rucio/common/config.py +22 -35
- rucio/common/constants.py +61 -3
- rucio/common/didtype.py +72 -24
- rucio/common/dumper/__init__.py +45 -38
- rucio/common/dumper/consistency.py +75 -30
- rucio/common/dumper/data_models.py +63 -19
- rucio/common/dumper/path_parsing.py +19 -8
- rucio/common/exception.py +65 -8
- rucio/common/extra.py +5 -10
- rucio/common/logging.py +13 -13
- rucio/common/pcache.py +8 -7
- rucio/common/plugins.py +59 -27
- rucio/common/policy.py +12 -3
- rucio/common/schema/__init__.py +84 -34
- rucio/common/schema/generic.py +0 -17
- rucio/common/schema/generic_multi_vo.py +0 -17
- rucio/common/test_rucio_server.py +12 -6
- rucio/common/types.py +132 -52
- rucio/common/utils.py +93 -643
- rucio/core/account_limit.py +14 -12
- rucio/core/authentication.py +2 -2
- rucio/core/config.py +23 -42
- rucio/core/credential.py +14 -15
- rucio/core/did.py +5 -1
- rucio/core/did_meta_plugins/elasticsearch_meta.py +407 -0
- rucio/core/did_meta_plugins/filter_engine.py +62 -3
- rucio/core/did_meta_plugins/json_meta.py +2 -2
- rucio/core/did_meta_plugins/mongo_meta.py +43 -30
- rucio/core/did_meta_plugins/postgres_meta.py +75 -39
- rucio/core/identity.py +6 -5
- rucio/core/importer.py +4 -3
- rucio/core/lifetime_exception.py +2 -2
- rucio/core/lock.py +8 -7
- rucio/core/message.py +6 -0
- rucio/core/monitor.py +30 -29
- rucio/core/naming_convention.py +2 -2
- rucio/core/nongrid_trace.py +2 -2
- rucio/core/oidc.py +11 -9
- rucio/core/permission/__init__.py +79 -37
- rucio/core/permission/generic.py +1 -7
- rucio/core/permission/generic_multi_vo.py +1 -7
- rucio/core/quarantined_replica.py +4 -3
- rucio/core/replica.py +464 -139
- rucio/core/replica_sorter.py +55 -59
- rucio/core/request.py +34 -32
- rucio/core/rse.py +301 -97
- rucio/core/rse_counter.py +1 -2
- rucio/core/rse_expression_parser.py +7 -7
- rucio/core/rse_selector.py +9 -7
- rucio/core/rule.py +41 -40
- rucio/core/rule_grouping.py +42 -40
- rucio/core/scope.py +5 -4
- rucio/core/subscription.py +26 -28
- rucio/core/topology.py +11 -11
- rucio/core/trace.py +2 -2
- rucio/core/transfer.py +29 -15
- rucio/core/volatile_replica.py +4 -3
- rucio/daemons/atropos/atropos.py +1 -1
- rucio/daemons/auditor/__init__.py +2 -2
- rucio/daemons/auditor/srmdumps.py +6 -6
- rucio/daemons/automatix/automatix.py +32 -21
- rucio/daemons/badreplicas/necromancer.py +2 -2
- rucio/daemons/bb8/nuclei_background_rebalance.py +1 -1
- rucio/daemons/bb8/t2_background_rebalance.py +1 -1
- rucio/daemons/common.py +15 -25
- rucio/daemons/conveyor/finisher.py +2 -2
- rucio/daemons/conveyor/poller.py +18 -28
- rucio/daemons/conveyor/receiver.py +2 -2
- rucio/daemons/conveyor/stager.py +1 -0
- rucio/daemons/conveyor/submitter.py +3 -3
- rucio/daemons/hermes/hermes.py +91 -30
- rucio/daemons/judge/evaluator.py +2 -2
- rucio/daemons/oauthmanager/oauthmanager.py +3 -3
- rucio/daemons/reaper/dark_reaper.py +7 -3
- rucio/daemons/reaper/reaper.py +12 -16
- rucio/daemons/rsedecommissioner/config.py +1 -1
- rucio/daemons/rsedecommissioner/profiles/generic.py +5 -4
- rucio/daemons/rsedecommissioner/profiles/types.py +7 -6
- rucio/daemons/rsedecommissioner/rse_decommissioner.py +1 -1
- rucio/daemons/storage/consistency/actions.py +8 -6
- rucio/daemons/tracer/kronos.py +4 -4
- rucio/db/sqla/constants.py +5 -0
- rucio/db/sqla/migrate_repo/versions/1677d4d803c8_split_rse_availability_into_multiple.py +4 -4
- rucio/db/sqla/migrate_repo/versions/30d5206e9cad_increase_oauthrequest_redirect_msg_.py +37 -0
- rucio/db/sqla/models.py +157 -154
- rucio/db/sqla/session.py +58 -27
- rucio/db/sqla/types.py +2 -2
- rucio/db/sqla/util.py +2 -2
- rucio/gateway/account.py +18 -12
- rucio/gateway/account_limit.py +137 -60
- rucio/gateway/authentication.py +18 -12
- rucio/gateway/config.py +30 -20
- rucio/gateway/credential.py +9 -10
- rucio/gateway/did.py +70 -53
- rucio/gateway/dirac.py +6 -4
- rucio/gateway/exporter.py +3 -2
- rucio/gateway/heartbeat.py +6 -4
- rucio/gateway/identity.py +36 -51
- rucio/gateway/importer.py +3 -2
- rucio/gateway/lifetime_exception.py +3 -2
- rucio/gateway/meta_conventions.py +17 -6
- rucio/gateway/permission.py +4 -1
- rucio/gateway/quarantined_replica.py +3 -2
- rucio/gateway/replica.py +31 -22
- rucio/gateway/request.py +27 -18
- rucio/gateway/rse.py +69 -37
- rucio/gateway/rule.py +46 -26
- rucio/gateway/scope.py +3 -2
- rucio/gateway/subscription.py +14 -11
- rucio/gateway/vo.py +12 -8
- rucio/rse/__init__.py +3 -3
- rucio/rse/protocols/bittorrent.py +11 -1
- rucio/rse/protocols/cache.py +0 -11
- rucio/rse/protocols/dummy.py +0 -11
- rucio/rse/protocols/gfal.py +14 -9
- rucio/rse/protocols/globus.py +1 -1
- rucio/rse/protocols/http_cache.py +1 -1
- rucio/rse/protocols/posix.py +2 -2
- rucio/rse/protocols/protocol.py +84 -317
- rucio/rse/protocols/rclone.py +2 -1
- rucio/rse/protocols/rfio.py +10 -1
- rucio/rse/protocols/ssh.py +2 -1
- rucio/rse/protocols/storm.py +2 -13
- rucio/rse/protocols/webdav.py +74 -30
- rucio/rse/protocols/xrootd.py +2 -1
- rucio/rse/rsemanager.py +170 -53
- rucio/rse/translation.py +260 -0
- rucio/tests/common.py +23 -13
- rucio/tests/common_server.py +26 -9
- rucio/transfertool/bittorrent.py +15 -14
- rucio/transfertool/bittorrent_driver.py +5 -7
- rucio/transfertool/bittorrent_driver_qbittorrent.py +9 -8
- rucio/transfertool/fts3.py +20 -16
- rucio/transfertool/mock.py +2 -3
- rucio/vcsversion.py +4 -4
- rucio/version.py +7 -0
- rucio/web/rest/flaskapi/v1/accounts.py +17 -3
- rucio/web/rest/flaskapi/v1/auth.py +5 -5
- rucio/web/rest/flaskapi/v1/credentials.py +3 -2
- rucio/web/rest/flaskapi/v1/dids.py +21 -15
- rucio/web/rest/flaskapi/v1/identities.py +33 -9
- rucio/web/rest/flaskapi/v1/redirect.py +5 -4
- rucio/web/rest/flaskapi/v1/replicas.py +12 -8
- rucio/web/rest/flaskapi/v1/rses.py +15 -4
- rucio/web/rest/flaskapi/v1/traces.py +56 -19
- {rucio-35.7.0.data → rucio-37.0.0.data}/data/rucio/etc/alembic.ini.template +1 -1
- {rucio-35.7.0.data → rucio-37.0.0.data}/data/rucio/etc/alembic_offline.ini.template +1 -1
- {rucio-35.7.0.data → rucio-37.0.0.data}/data/rucio/etc/rucio.cfg.atlas.client.template +3 -2
- {rucio-35.7.0.data → rucio-37.0.0.data}/data/rucio/etc/rucio.cfg.template +3 -19
- {rucio-35.7.0.data → rucio-37.0.0.data}/data/rucio/etc/rucio_multi_vo.cfg.template +1 -18
- {rucio-35.7.0.data → rucio-37.0.0.data}/data/rucio/requirements.server.txt +97 -68
- rucio-37.0.0.data/scripts/rucio +133 -0
- rucio-37.0.0.data/scripts/rucio-admin +97 -0
- {rucio-35.7.0.data → rucio-37.0.0.data}/scripts/rucio-atropos +2 -2
- {rucio-35.7.0.data → rucio-37.0.0.data}/scripts/rucio-auditor +2 -1
- {rucio-35.7.0.data → rucio-37.0.0.data}/scripts/rucio-automatix +2 -2
- {rucio-35.7.0.data → rucio-37.0.0.data}/scripts/rucio-cache-client +17 -10
- {rucio-35.7.0.data → rucio-37.0.0.data}/scripts/rucio-conveyor-receiver +1 -0
- {rucio-35.7.0.data → rucio-37.0.0.data}/scripts/rucio-kronos +1 -0
- {rucio-35.7.0.data → rucio-37.0.0.data}/scripts/rucio-minos +2 -2
- {rucio-35.7.0.data → rucio-37.0.0.data}/scripts/rucio-minos-temporary-expiration +2 -2
- {rucio-35.7.0.data → rucio-37.0.0.data}/scripts/rucio-necromancer +2 -2
- {rucio-35.7.0.data → rucio-37.0.0.data}/scripts/rucio-reaper +6 -6
- {rucio-35.7.0.data → rucio-37.0.0.data}/scripts/rucio-transmogrifier +2 -2
- rucio-37.0.0.dist-info/METADATA +92 -0
- {rucio-35.7.0.dist-info → rucio-37.0.0.dist-info}/RECORD +237 -243
- {rucio-35.7.0.dist-info → rucio-37.0.0.dist-info}/licenses/AUTHORS.rst +3 -0
- rucio/common/schema/atlas.py +0 -413
- rucio/common/schema/belleii.py +0 -408
- rucio/common/schema/domatpc.py +0 -401
- rucio/common/schema/escape.py +0 -426
- rucio/common/schema/icecube.py +0 -406
- rucio/core/permission/atlas.py +0 -1348
- rucio/core/permission/belleii.py +0 -1077
- rucio/core/permission/escape.py +0 -1078
- rucio/daemons/c3po/algorithms/__init__.py +0 -13
- rucio/daemons/c3po/algorithms/simple.py +0 -134
- rucio/daemons/c3po/algorithms/t2_free_space.py +0 -128
- rucio/daemons/c3po/algorithms/t2_free_space_only_pop.py +0 -130
- rucio/daemons/c3po/algorithms/t2_free_space_only_pop_with_network.py +0 -294
- rucio/daemons/c3po/c3po.py +0 -371
- rucio/daemons/c3po/collectors/agis.py +0 -108
- rucio/daemons/c3po/collectors/free_space.py +0 -81
- rucio/daemons/c3po/collectors/jedi_did.py +0 -57
- rucio/daemons/c3po/collectors/mock_did.py +0 -51
- rucio/daemons/c3po/collectors/network_metrics.py +0 -71
- rucio/daemons/c3po/collectors/workload.py +0 -112
- rucio/daemons/c3po/utils/__init__.py +0 -13
- rucio/daemons/c3po/utils/dataset_cache.py +0 -50
- rucio/daemons/c3po/utils/expiring_dataset_cache.py +0 -56
- rucio/daemons/c3po/utils/expiring_list.py +0 -62
- rucio/daemons/c3po/utils/popularity.py +0 -85
- rucio/daemons/c3po/utils/timeseries.py +0 -89
- rucio/rse/protocols/gsiftp.py +0 -92
- rucio-35.7.0.data/scripts/rucio-c3po +0 -85
- rucio-35.7.0.dist-info/METADATA +0 -72
- /rucio/{daemons/c3po → cli/bin_legacy}/__init__.py +0 -0
- {rucio-35.7.0.data → rucio-37.0.0.data}/data/rucio/etc/globus-config.yml.template +0 -0
- {rucio-35.7.0.data → rucio-37.0.0.data}/data/rucio/etc/ldap.cfg.template +0 -0
- {rucio-35.7.0.data → rucio-37.0.0.data}/data/rucio/etc/mail_templates/rule_approval_request.tmpl +0 -0
- {rucio-35.7.0.data → rucio-37.0.0.data}/data/rucio/etc/mail_templates/rule_approved_admin.tmpl +0 -0
- {rucio-35.7.0.data → rucio-37.0.0.data}/data/rucio/etc/mail_templates/rule_approved_user.tmpl +0 -0
- {rucio-35.7.0.data → rucio-37.0.0.data}/data/rucio/etc/mail_templates/rule_denied_admin.tmpl +0 -0
- {rucio-35.7.0.data → rucio-37.0.0.data}/data/rucio/etc/mail_templates/rule_denied_user.tmpl +0 -0
- {rucio-35.7.0.data → rucio-37.0.0.data}/data/rucio/etc/mail_templates/rule_ok_notification.tmpl +0 -0
- {rucio-35.7.0.data → rucio-37.0.0.data}/data/rucio/etc/rse-accounts.cfg.template +0 -0
- {rucio-35.7.0.data → rucio-37.0.0.data}/data/rucio/tools/bootstrap.py +0 -0
- {rucio-35.7.0.data → rucio-37.0.0.data}/data/rucio/tools/merge_rucio_configs.py +0 -0
- {rucio-35.7.0.data → rucio-37.0.0.data}/data/rucio/tools/reset_database.py +0 -0
- {rucio-35.7.0.data → rucio-37.0.0.data}/scripts/rucio-abacus-account +0 -0
- {rucio-35.7.0.data → rucio-37.0.0.data}/scripts/rucio-abacus-collection-replica +0 -0
- {rucio-35.7.0.data → rucio-37.0.0.data}/scripts/rucio-abacus-rse +0 -0
- {rucio-35.7.0.data → rucio-37.0.0.data}/scripts/rucio-bb8 +0 -0
- {rucio-35.7.0.data → rucio-37.0.0.data}/scripts/rucio-cache-consumer +0 -0
- {rucio-35.7.0.data → rucio-37.0.0.data}/scripts/rucio-conveyor-finisher +0 -0
- {rucio-35.7.0.data → rucio-37.0.0.data}/scripts/rucio-conveyor-poller +0 -0
- {rucio-35.7.0.data → rucio-37.0.0.data}/scripts/rucio-conveyor-preparer +0 -0
- {rucio-35.7.0.data → rucio-37.0.0.data}/scripts/rucio-conveyor-stager +0 -0
- {rucio-35.7.0.data → rucio-37.0.0.data}/scripts/rucio-conveyor-submitter +0 -0
- {rucio-35.7.0.data → rucio-37.0.0.data}/scripts/rucio-conveyor-throttler +0 -0
- {rucio-35.7.0.data → rucio-37.0.0.data}/scripts/rucio-dark-reaper +0 -0
- {rucio-35.7.0.data → rucio-37.0.0.data}/scripts/rucio-dumper +0 -0
- {rucio-35.7.0.data → rucio-37.0.0.data}/scripts/rucio-follower +0 -0
- {rucio-35.7.0.data → rucio-37.0.0.data}/scripts/rucio-hermes +0 -0
- {rucio-35.7.0.data → rucio-37.0.0.data}/scripts/rucio-judge-cleaner +0 -0
- {rucio-35.7.0.data → rucio-37.0.0.data}/scripts/rucio-judge-evaluator +0 -0
- {rucio-35.7.0.data → rucio-37.0.0.data}/scripts/rucio-judge-injector +0 -0
- {rucio-35.7.0.data → rucio-37.0.0.data}/scripts/rucio-judge-repairer +0 -0
- {rucio-35.7.0.data → rucio-37.0.0.data}/scripts/rucio-oauth-manager +0 -0
- {rucio-35.7.0.data → rucio-37.0.0.data}/scripts/rucio-replica-recoverer +0 -0
- {rucio-35.7.0.data → rucio-37.0.0.data}/scripts/rucio-rse-decommissioner +0 -0
- {rucio-35.7.0.data → rucio-37.0.0.data}/scripts/rucio-storage-consistency-actions +0 -0
- {rucio-35.7.0.data → rucio-37.0.0.data}/scripts/rucio-undertaker +0 -0
- {rucio-35.7.0.dist-info → rucio-37.0.0.dist-info}/WHEEL +0 -0
- {rucio-35.7.0.dist-info → rucio-37.0.0.dist-info}/licenses/LICENSE +0 -0
- {rucio-35.7.0.dist-info → rucio-37.0.0.dist-info}/top_level.txt +0 -0
rucio/daemons/conveyor/poller.py
CHANGED
|
@@ -23,7 +23,6 @@ import logging
|
|
|
23
23
|
import re
|
|
24
24
|
import threading
|
|
25
25
|
import time
|
|
26
|
-
from collections.abc import Mapping, Sequence
|
|
27
26
|
from itertools import groupby
|
|
28
27
|
from typing import TYPE_CHECKING, Any, Optional
|
|
29
28
|
|
|
@@ -31,11 +30,10 @@ from requests.exceptions import RequestException
|
|
|
31
30
|
from sqlalchemy.exc import DatabaseError
|
|
32
31
|
|
|
33
32
|
import rucio.db.sqla.util
|
|
34
|
-
from rucio.common.config import config_get, config_get_bool
|
|
33
|
+
from rucio.common.config import config_get, config_get_bool, config_get_float
|
|
35
34
|
from rucio.common.exception import DatabaseException, TransferToolTimeout, TransferToolWrongAnswer
|
|
36
35
|
from rucio.common.logging import setup_logging
|
|
37
36
|
from rucio.common.stopwatch import Stopwatch
|
|
38
|
-
from rucio.common.types import InternalAccount, LoggerFunction
|
|
39
37
|
from rucio.common.utils import dict_chunks
|
|
40
38
|
from rucio.core import request as request_core
|
|
41
39
|
from rucio.core import transfer as transfer_core
|
|
@@ -44,12 +42,14 @@ from rucio.core.topology import ExpiringObjectCache, Topology
|
|
|
44
42
|
from rucio.daemons.common import ProducerConsumerDaemon, db_workqueue
|
|
45
43
|
from rucio.db.sqla.constants import MYSQL_LOCK_WAIT_TIMEOUT_EXCEEDED, ORACLE_DEADLOCK_DETECTED_REGEX, ORACLE_RESOURCE_BUSY_REGEX, RequestState, RequestType
|
|
46
44
|
from rucio.transfertool.fts3 import FTS3Transfertool
|
|
47
|
-
from rucio.transfertool.transfertool import Transfertool
|
|
48
45
|
|
|
49
46
|
if TYPE_CHECKING:
|
|
47
|
+
from collections.abc import Mapping, Sequence
|
|
50
48
|
from types import FrameType
|
|
51
49
|
|
|
50
|
+
from rucio.common.types import LoggerFunction
|
|
52
51
|
from rucio.daemons.common import HeartbeatHandler
|
|
52
|
+
from rucio.transfertool.transfertool import Transfertool
|
|
53
53
|
|
|
54
54
|
GRACEFUL_STOP = threading.Event()
|
|
55
55
|
METRICS = MetricManager(module=__name__)
|
|
@@ -62,7 +62,7 @@ FILTER_TRANSFERTOOL = config_get('conveyor', 'filter_transfertool', False, None)
|
|
|
62
62
|
def _fetch_requests(
|
|
63
63
|
db_bulk: int,
|
|
64
64
|
older_than: int,
|
|
65
|
-
activity_shares: Optional[Mapping[str, float]],
|
|
65
|
+
activity_shares: Optional['Mapping[str, float]'],
|
|
66
66
|
transfertool: Optional[str],
|
|
67
67
|
filter_transfertool: Optional[str],
|
|
68
68
|
cached_topology: Optional[ExpiringObjectCache],
|
|
@@ -116,9 +116,9 @@ def _handle_requests(
|
|
|
116
116
|
timeout: Optional[int],
|
|
117
117
|
transfertool: str,
|
|
118
118
|
transfer_stats_manager: request_core.TransferStatsManager,
|
|
119
|
-
|
|
119
|
+
oidc_support: bool,
|
|
120
120
|
*,
|
|
121
|
-
logger: LoggerFunction = logging.log,
|
|
121
|
+
logger: "LoggerFunction" = logging.log,
|
|
122
122
|
) -> None:
|
|
123
123
|
transfs.sort(key=lambda t: (t['external_host'] or '',
|
|
124
124
|
t['scope'].vo if multi_vo else '',
|
|
@@ -136,15 +136,9 @@ def _handle_requests(
|
|
|
136
136
|
|
|
137
137
|
transfertool_kwargs = {}
|
|
138
138
|
if transfertool_cls.external_name == FTS3Transfertool.external_name:
|
|
139
|
-
account = None
|
|
140
|
-
if oidc_account:
|
|
141
|
-
if vo:
|
|
142
|
-
account = InternalAccount(oidc_account, vo=vo)
|
|
143
|
-
else:
|
|
144
|
-
account = InternalAccount(oidc_account)
|
|
145
139
|
transfertool_kwargs.update({
|
|
146
140
|
'vo': vo,
|
|
147
|
-
'
|
|
141
|
+
'oidc_support': oidc_support,
|
|
148
142
|
})
|
|
149
143
|
|
|
150
144
|
transfertool_obj = transfertool_cls(external_host=external_host, **transfertool_kwargs)
|
|
@@ -161,12 +155,12 @@ def _handle_requests(
|
|
|
161
155
|
|
|
162
156
|
def poller(
|
|
163
157
|
once: bool = False,
|
|
164
|
-
activities: Optional[Sequence[str]] = None,
|
|
158
|
+
activities: Optional['Sequence[str]'] = None,
|
|
165
159
|
sleep_time: int = 60,
|
|
166
160
|
fts_bulk: int = 100,
|
|
167
161
|
db_bulk: int = 1000,
|
|
168
162
|
older_than: int = 60,
|
|
169
|
-
activity_shares: Optional[Mapping[str, float]] = None,
|
|
163
|
+
activity_shares: Optional['Mapping[str, float]'] = None,
|
|
170
164
|
partition_wait_time: int = 10,
|
|
171
165
|
transfertool: Optional[str] = TRANSFER_TOOL,
|
|
172
166
|
filter_transfertool: Optional[str] = FILTER_TRANSFERTOOL,
|
|
@@ -176,13 +170,9 @@ def poller(
|
|
|
176
170
|
"""
|
|
177
171
|
Main loop to check the status of a transfer primitive with a transfertool.
|
|
178
172
|
"""
|
|
179
|
-
|
|
180
|
-
timeout = config_get('conveyor', 'poll_timeout', default=None, raise_exception=False)
|
|
181
|
-
if timeout:
|
|
182
|
-
timeout = float(timeout)
|
|
183
|
-
|
|
173
|
+
timeout = config_get_float('conveyor', 'poll_timeout', default=None, raise_exception=False)
|
|
184
174
|
multi_vo = config_get_bool('common', 'multi_vo', False, None)
|
|
185
|
-
|
|
175
|
+
oidc_support = config_get_bool('conveyor', 'poller_oidc_support', default=False, raise_exception=False)
|
|
186
176
|
|
|
187
177
|
executable = DAEMON_NAME
|
|
188
178
|
|
|
@@ -227,7 +217,7 @@ def poller(
|
|
|
227
217
|
fts_bulk=fts_bulk,
|
|
228
218
|
multi_vo=multi_vo,
|
|
229
219
|
timeout=timeout, # type: ignore (unclear if timeout is meant to be int or float)
|
|
230
|
-
|
|
220
|
+
oidc_support=oidc_support,
|
|
231
221
|
transfertool=transfertool, # type: ignore (transfertool is not None)
|
|
232
222
|
transfer_stats_manager=transfer_stats_manager,
|
|
233
223
|
)
|
|
@@ -251,7 +241,7 @@ def stop(signum: Optional[int] = None, frame: Optional["FrameType"] = None) -> N
|
|
|
251
241
|
def run(
|
|
252
242
|
once: bool = False,
|
|
253
243
|
sleep_time: int = 60,
|
|
254
|
-
activities: Optional[Sequence[str]] = None,
|
|
244
|
+
activities: Optional['Sequence[str]'] = None,
|
|
255
245
|
fts_bulk: int = 100,
|
|
256
246
|
db_bulk: int = 1000,
|
|
257
247
|
older_than: int = 60,
|
|
@@ -301,8 +291,8 @@ def run(
|
|
|
301
291
|
|
|
302
292
|
|
|
303
293
|
def poll_transfers(
|
|
304
|
-
transfertool_obj: Transfertool,
|
|
305
|
-
transfers_by_eid: Mapping[str, Mapping[str, Any]],
|
|
294
|
+
transfertool_obj: 'Transfertool',
|
|
295
|
+
transfers_by_eid: 'Mapping[str, Mapping[str, Any]]',
|
|
306
296
|
transfer_stats_manager: request_core.TransferStatsManager,
|
|
307
297
|
timeout: "Optional[int]" = None,
|
|
308
298
|
logger: "LoggerFunction" = logging.log
|
|
@@ -328,8 +318,8 @@ def poll_transfers(
|
|
|
328
318
|
|
|
329
319
|
|
|
330
320
|
def _poll_transfers(
|
|
331
|
-
transfertool_obj: Transfertool,
|
|
332
|
-
transfers_by_eid: Mapping[str, Mapping[str, Any]],
|
|
321
|
+
transfertool_obj: 'Transfertool',
|
|
322
|
+
transfers_by_eid: 'Mapping[str, Mapping[str, Any]]',
|
|
333
323
|
transfer_stats_manager: request_core.TransferStatsManager,
|
|
334
324
|
timeout: "Optional[int]" = None,
|
|
335
325
|
logger: "LoggerFunction" = logging.log
|
|
@@ -28,7 +28,7 @@ import stomp
|
|
|
28
28
|
|
|
29
29
|
import rucio.db.sqla.util
|
|
30
30
|
from rucio.common import exception
|
|
31
|
-
from rucio.common.config import config_get, config_get_bool, config_get_int
|
|
31
|
+
from rucio.common.config import config_get, config_get_bool, config_get_int, config_get_list
|
|
32
32
|
from rucio.common.logging import setup_logging
|
|
33
33
|
from rucio.common.policy import get_policy
|
|
34
34
|
from rucio.core import request as request_core
|
|
@@ -134,7 +134,7 @@ def receiver(
|
|
|
134
134
|
brokers_alias = []
|
|
135
135
|
brokers_resolved = []
|
|
136
136
|
try:
|
|
137
|
-
brokers_alias =
|
|
137
|
+
brokers_alias = config_get_list('messaging-fts3', 'brokers')
|
|
138
138
|
except Exception:
|
|
139
139
|
raise Exception('Could not load brokers from configuration')
|
|
140
140
|
|
rucio/daemons/conveyor/stager.py
CHANGED
|
@@ -17,7 +17,6 @@ Conveyor transfer submitter is a daemon to manage non-tape file transfers.
|
|
|
17
17
|
"""
|
|
18
18
|
import logging
|
|
19
19
|
import threading
|
|
20
|
-
from collections.abc import Mapping
|
|
21
20
|
from typing import TYPE_CHECKING, Optional
|
|
22
21
|
|
|
23
22
|
import rucio.db.sqla.util
|
|
@@ -37,6 +36,7 @@ from rucio.transfertool.fts3 import FTS3Transfertool
|
|
|
37
36
|
from rucio.transfertool.globus import GlobusTransferTool
|
|
38
37
|
|
|
39
38
|
if TYPE_CHECKING:
|
|
39
|
+
from collections.abc import Mapping
|
|
40
40
|
from types import FrameType
|
|
41
41
|
|
|
42
42
|
from rucio.common.types import LoggerFunction, RSESettingsDict
|
|
@@ -114,7 +114,7 @@ def _fetch_requests(
|
|
|
114
114
|
|
|
115
115
|
|
|
116
116
|
def _handle_requests(
|
|
117
|
-
batch: tuple[Topology, Mapping[str, RequestWithSources]],
|
|
117
|
+
batch: tuple[Topology, 'Mapping[str, RequestWithSources]'],
|
|
118
118
|
*,
|
|
119
119
|
transfertools: list[str],
|
|
120
120
|
schemes: Optional[list[str]],
|
|
@@ -301,7 +301,7 @@ def submitter(
|
|
|
301
301
|
heartbeat_handler=heartbeat_handler,
|
|
302
302
|
)
|
|
303
303
|
|
|
304
|
-
def _consumer(batch: tuple[Topology, Mapping[str, RequestWithSources]]) -> None:
|
|
304
|
+
def _consumer(batch: tuple[Topology, 'Mapping[str, RequestWithSources]']) -> None:
|
|
305
305
|
return _handle_requests(
|
|
306
306
|
batch,
|
|
307
307
|
transfertools=transfertools,
|
rucio/daemons/hermes/hermes.py
CHANGED
|
@@ -114,10 +114,7 @@ def setup_activemq(
|
|
|
114
114
|
brokers_alias = []
|
|
115
115
|
brokers_resolved = []
|
|
116
116
|
try:
|
|
117
|
-
brokers_alias =
|
|
118
|
-
broker.strip()
|
|
119
|
-
for broker in config_get("messaging-hermes", "brokers").split(",")
|
|
120
|
-
]
|
|
117
|
+
brokers_alias = config_get_list("messaging-hermes", "brokers")
|
|
121
118
|
except:
|
|
122
119
|
raise Exception("Could not load brokers from configuration")
|
|
123
120
|
|
|
@@ -408,7 +405,7 @@ def submit_to_elastic(
|
|
|
408
405
|
|
|
409
406
|
def aggregate_to_influx(
|
|
410
407
|
messages: "Iterable[dict[str, Any]]",
|
|
411
|
-
bin_size:
|
|
408
|
+
bin_size: str,
|
|
412
409
|
endpoint: str,
|
|
413
410
|
logger: "LoggerFunction"
|
|
414
411
|
) -> int:
|
|
@@ -517,6 +514,69 @@ def aggregate_to_influx(
|
|
|
517
514
|
return 204
|
|
518
515
|
|
|
519
516
|
|
|
517
|
+
def build_message_dict(
|
|
518
|
+
bulk: int,
|
|
519
|
+
thread: int,
|
|
520
|
+
total_threads: int,
|
|
521
|
+
message_dict: dict[str, list[dict[str, Any]]],
|
|
522
|
+
logger: "LoggerFunction",
|
|
523
|
+
service: Optional[str] = None,
|
|
524
|
+
) -> None:
|
|
525
|
+
"""
|
|
526
|
+
Retrieves messages from the database and builds a dictionary with the keys being the services, and the values a list of the messages (built up of dictionary / json information)
|
|
527
|
+
|
|
528
|
+
:param bulk: Integer for number of messages to retrieve.
|
|
529
|
+
:param thread: Passed to thread in retrieve_messages for Identifier of the caller thread as an integer.
|
|
530
|
+
:param total_threads: Passed to total_threads for Maximum number of threads as an integer.
|
|
531
|
+
:param message_dict: Either empty dictionary to be built, or build upon when using query_by_service.
|
|
532
|
+
:param logger: The logger object.
|
|
533
|
+
:param service: When passed, only returns messages table for this specific service.
|
|
534
|
+
|
|
535
|
+
:returns: None, but builds on the dictionary message_dict passed to this fuction (for when querying multiple services).
|
|
536
|
+
"""
|
|
537
|
+
start_time = time.time()
|
|
538
|
+
messages = retrieve_messages(
|
|
539
|
+
bulk=bulk,
|
|
540
|
+
old_mode=False,
|
|
541
|
+
thread=thread,
|
|
542
|
+
total_threads=total_threads,
|
|
543
|
+
service_filter=service,
|
|
544
|
+
)
|
|
545
|
+
|
|
546
|
+
if messages:
|
|
547
|
+
if service is not None:
|
|
548
|
+
# query_by_service dictionary build behaviour
|
|
549
|
+
message_dict[service] = messages.copy()
|
|
550
|
+
logger(
|
|
551
|
+
logging.DEBUG,
|
|
552
|
+
"Retrieved %i messages retrieved in %s seconds for %s service.",
|
|
553
|
+
len(messages),
|
|
554
|
+
time.time() - start_time,
|
|
555
|
+
service,
|
|
556
|
+
)
|
|
557
|
+
|
|
558
|
+
else:
|
|
559
|
+
# default dictionary build behaviour
|
|
560
|
+
for message in messages:
|
|
561
|
+
service = message["services"]
|
|
562
|
+
if service is not None:
|
|
563
|
+
if service not in message_dict:
|
|
564
|
+
message_dict[service] = []
|
|
565
|
+
message_dict[service].append(message)
|
|
566
|
+
logger(
|
|
567
|
+
logging.DEBUG,
|
|
568
|
+
"Retrieved %i messages retrieved in %s seconds",
|
|
569
|
+
len(messages),
|
|
570
|
+
time.time() - start_time,
|
|
571
|
+
)
|
|
572
|
+
else:
|
|
573
|
+
logger(
|
|
574
|
+
logging.INFO,
|
|
575
|
+
"No messages retrieved in %s seconds",
|
|
576
|
+
time.time() - start_time,
|
|
577
|
+
)
|
|
578
|
+
|
|
579
|
+
|
|
520
580
|
def hermes(once: bool = False, bulk: int = 1000, sleep_time: int = 10) -> None:
|
|
521
581
|
"""
|
|
522
582
|
Creates a Hermes Worker that can submit messages to different services (InfluXDB, ElasticSearch, ActiveMQ)
|
|
@@ -571,7 +631,6 @@ def run_once(heartbeat_handler: "HeartbeatHandler", bulk: int, **_kwargs) -> boo
|
|
|
571
631
|
)
|
|
572
632
|
except Exception as err:
|
|
573
633
|
logger(logging.ERROR, str(err))
|
|
574
|
-
conns = None
|
|
575
634
|
if "activemq" in services_list:
|
|
576
635
|
try:
|
|
577
636
|
conns, destination, username, password, use_ssl = setup_activemq(logger)
|
|
@@ -585,30 +644,31 @@ def run_once(heartbeat_handler: "HeartbeatHandler", bulk: int, **_kwargs) -> boo
|
|
|
585
644
|
|
|
586
645
|
worker_number, total_workers, logger = heartbeat_handler.live()
|
|
587
646
|
message_dict = {}
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
messages
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
len(messages),
|
|
609
|
-
time.time() - start_time,
|
|
647
|
+
query_by_service = config_get_bool("hermes", "query_by_service", default=False)
|
|
648
|
+
|
|
649
|
+
# query_by_service is a toggleable behaviour switch between collecting bulk number of messages across all services when false, to collecting bulk messages from each service when true.
|
|
650
|
+
if query_by_service:
|
|
651
|
+
for service in services_list:
|
|
652
|
+
build_message_dict(
|
|
653
|
+
bulk=bulk,
|
|
654
|
+
thread=worker_number,
|
|
655
|
+
total_threads=total_workers,
|
|
656
|
+
message_dict=message_dict,
|
|
657
|
+
logger=logger,
|
|
658
|
+
service=service,
|
|
659
|
+
)
|
|
660
|
+
else:
|
|
661
|
+
build_message_dict(
|
|
662
|
+
bulk=bulk,
|
|
663
|
+
thread=worker_number,
|
|
664
|
+
total_threads=total_workers,
|
|
665
|
+
message_dict=message_dict,
|
|
666
|
+
logger=logger
|
|
610
667
|
)
|
|
611
668
|
|
|
669
|
+
if message_dict:
|
|
670
|
+
to_delete = []
|
|
671
|
+
|
|
612
672
|
if "influx" in message_dict and influx_endpoint:
|
|
613
673
|
# For influxDB, bulk submission, either everything succeeds or fails
|
|
614
674
|
t_time = time.time()
|
|
@@ -685,12 +745,12 @@ def run_once(heartbeat_handler: "HeartbeatHandler", bulk: int, **_kwargs) -> boo
|
|
|
685
745
|
except Exception as error:
|
|
686
746
|
logger(logging.ERROR, "Error sending email : %s", str(error))
|
|
687
747
|
|
|
688
|
-
if "activemq" in message_dict
|
|
748
|
+
if "activemq" in message_dict:
|
|
689
749
|
t_time = time.time()
|
|
690
750
|
try:
|
|
691
751
|
messages_sent = deliver_to_activemq(
|
|
692
752
|
messages=message_dict["activemq"],
|
|
693
|
-
conns=conns,
|
|
753
|
+
conns=conns, # type: ignore (argument could be None)
|
|
694
754
|
destination=destination, # type: ignore (argument could be None)
|
|
695
755
|
username=username, # type: ignore (argument could be None)
|
|
696
756
|
password=password, # type: ignore (argument could be None)
|
|
@@ -717,6 +777,7 @@ def run_once(heartbeat_handler: "HeartbeatHandler", bulk: int, **_kwargs) -> boo
|
|
|
717
777
|
"updated_at": message["created_at"],
|
|
718
778
|
"payload": str(message["payload"]),
|
|
719
779
|
"event_type": message["event_type"],
|
|
780
|
+
"services": message["services"]
|
|
720
781
|
}
|
|
721
782
|
for message in to_delete
|
|
722
783
|
]
|
rucio/daemons/judge/evaluator.py
CHANGED
|
@@ -91,9 +91,9 @@ def run_once(
|
|
|
91
91
|
dids = get_updated_dids(total_workers=total_workers,
|
|
92
92
|
worker_number=worker_number,
|
|
93
93
|
limit=did_limit,
|
|
94
|
-
blocked_dids=[(InternalScope(key[0],
|
|
94
|
+
blocked_dids=[(InternalScope(key[0], from_external=False), key[1]) for key in paused_dids])
|
|
95
95
|
logger(logging.DEBUG, 'index query time %f fetch size is %d (%d blocked)', time.time() - start, len(dids),
|
|
96
|
-
len([(InternalScope(key[0],
|
|
96
|
+
len([(InternalScope(key[0], from_external=False), key[1]) for key in paused_dids]))
|
|
97
97
|
|
|
98
98
|
# If the list is empty, sent the worker to sleep
|
|
99
99
|
if not dids:
|
|
@@ -53,7 +53,7 @@ graceful_stop = threading.Event()
|
|
|
53
53
|
DAEMON_NAME = 'oauth-manager'
|
|
54
54
|
|
|
55
55
|
|
|
56
|
-
def
|
|
56
|
+
def oauth_manager(once: bool = False, max_rows: int = 100, sleep_time: int = 300) -> None:
|
|
57
57
|
"""
|
|
58
58
|
Main loop to delete all expired tokens, refresh tokens eligible
|
|
59
59
|
for refresh and delete all expired OAuth session parameters.
|
|
@@ -178,10 +178,10 @@ def run(once: bool = False, threads: int = 1, max_rows: int = 100, sleep_time: i
|
|
|
178
178
|
raise DatabaseException('Database was not updated, daemon won\'t start')
|
|
179
179
|
|
|
180
180
|
if once:
|
|
181
|
-
|
|
181
|
+
oauth_manager(once, max_rows, sleep_time)
|
|
182
182
|
else:
|
|
183
183
|
logging.info('OAuth Manager starting %s threads', str(threads))
|
|
184
|
-
threads = [threading.Thread(target=
|
|
184
|
+
threads = [threading.Thread(target=oauth_manager,
|
|
185
185
|
kwargs={'once': once,
|
|
186
186
|
'max_rows': max_rows,
|
|
187
187
|
'sleep_time': sleep_time}) for i in range(0, threads)]
|
|
@@ -44,6 +44,7 @@ if TYPE_CHECKING:
|
|
|
44
44
|
from types import FrameType
|
|
45
45
|
from typing import Optional
|
|
46
46
|
|
|
47
|
+
from rucio.common.types import LFNDict
|
|
47
48
|
from rucio.daemons.common import HeartbeatHandler
|
|
48
49
|
|
|
49
50
|
logging.getLogger("requests").setLevel(logging.CRITICAL)
|
|
@@ -120,10 +121,13 @@ def run_once(
|
|
|
120
121
|
if replica['scope']:
|
|
121
122
|
scope = replica['scope'].external
|
|
122
123
|
try:
|
|
124
|
+
lfn: "LFNDict" = {
|
|
125
|
+
'scope': scope,
|
|
126
|
+
'name': replica['name'],
|
|
127
|
+
'path': replica['path']
|
|
128
|
+
}
|
|
123
129
|
pfn = str(list(rsemgr.lfns2pfns(rse_settings=rse_info,
|
|
124
|
-
lfns=[
|
|
125
|
-
'name': replica['name'],
|
|
126
|
-
'path': replica['path']}],
|
|
130
|
+
lfns=[lfn],
|
|
127
131
|
operation='delete',
|
|
128
132
|
scheme=scheme).values())[0])
|
|
129
133
|
logger(logging.INFO, 'Deletion ATTEMPT of %s:%s as %s on %s', scope, replica['name'], pfn, rse)
|
rucio/daemons/reaper/reaper.py
CHANGED
|
@@ -12,9 +12,9 @@
|
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
"""
|
|
16
16
|
Reaper is a daemon to manage file deletion.
|
|
17
|
-
|
|
17
|
+
"""
|
|
18
18
|
|
|
19
19
|
import concurrent.futures.thread # noqa (https://github.com/rucio/rucio/issues/6548)
|
|
20
20
|
|
|
@@ -33,7 +33,7 @@ from dogpile.cache.api import NoValue
|
|
|
33
33
|
from sqlalchemy.exc import DatabaseError, IntegrityError
|
|
34
34
|
|
|
35
35
|
import rucio.db.sqla.util
|
|
36
|
-
from rucio.common.cache import
|
|
36
|
+
from rucio.common.cache import MemcacheRegion
|
|
37
37
|
from rucio.common.config import config_get_bool, config_get_int
|
|
38
38
|
from rucio.common.constants import RseAttr
|
|
39
39
|
from rucio.common.exception import DatabaseException, ReplicaNotFound, ReplicaUnAvailable, ResourceTemporaryUnavailable, RSEAccessDenied, RSENotFound, RSEProtocolNotSupported, ServiceUnavailable, SourceNotFound, VONotFound
|
|
@@ -57,12 +57,12 @@ if TYPE_CHECKING:
|
|
|
57
57
|
from collections.abc import Iterable, Sequence
|
|
58
58
|
from types import FrameType
|
|
59
59
|
|
|
60
|
-
from rucio.common.types import LoggerFunction
|
|
60
|
+
from rucio.common.types import LFNDict, LoggerFunction
|
|
61
61
|
from rucio.daemons.common import HeartbeatHandler
|
|
62
62
|
|
|
63
63
|
GRACEFUL_STOP = threading.Event()
|
|
64
64
|
METRICS = MetricManager(module=__name__)
|
|
65
|
-
REGION =
|
|
65
|
+
REGION = MemcacheRegion(expiration_time=600)
|
|
66
66
|
DAEMON_NAME = 'reaper'
|
|
67
67
|
|
|
68
68
|
EXCLUDED_RSE_GAUGE = METRICS.gauge('excluded_rses.{rse}', documentation='Temporarly excluded RSEs')
|
|
@@ -474,7 +474,7 @@ def run_once(
|
|
|
474
474
|
|
|
475
475
|
rses_to_process = get_rses_to_process(rses, include_rses, exclude_rses, vos)
|
|
476
476
|
if not rses_to_process:
|
|
477
|
-
logger(logging.
|
|
477
|
+
logger(logging.WARNING, 'Reaper: No RSEs found, sleeping')
|
|
478
478
|
return must_sleep
|
|
479
479
|
else:
|
|
480
480
|
rses_to_process = [RseData(id_=rse['id'], name=rse['rse'], columns=rse) for rse in rses_to_process]
|
|
@@ -632,8 +632,13 @@ def _run_once(
|
|
|
632
632
|
del_start_time = time.time()
|
|
633
633
|
for replica in file_replicas:
|
|
634
634
|
try:
|
|
635
|
+
lfn: "LFNDict" = {
|
|
636
|
+
'scope': replica['scope'].external,
|
|
637
|
+
'name': replica['name'],
|
|
638
|
+
'path': replica['path']
|
|
639
|
+
}
|
|
635
640
|
replica['pfn'] = str(list(rsemgr.lfns2pfns(rse_settings=rse.info,
|
|
636
|
-
lfns=[
|
|
641
|
+
lfns=[lfn],
|
|
637
642
|
operation='delete', scheme=scheme).values())[0])
|
|
638
643
|
except (ReplicaUnAvailable, ReplicaNotFound) as error:
|
|
639
644
|
logger(logging.WARNING, 'Failed get pfn UNAVAILABLE replica %s:%s on %s with error %s', replica['scope'], replica['name'], rse.name, str(error))
|
|
@@ -690,7 +695,6 @@ def run(
|
|
|
690
695
|
|
|
691
696
|
:param threads: The total number of workers.
|
|
692
697
|
:param chunk_size: The size of chunk for deletion.
|
|
693
|
-
:param threads_per_worker: Total number of threads created by each worker.
|
|
694
698
|
:param once: If True, only runs one iteration of the main loop.
|
|
695
699
|
:param greedy: If True, delete right away replicas with tombstone.
|
|
696
700
|
:param rses: List of RSEs the reaper should work against.
|
|
@@ -711,14 +715,6 @@ def run(
|
|
|
711
715
|
if rucio.db.sqla.util.is_old_db():
|
|
712
716
|
raise DatabaseException('Database was not updated, daemon won\'t start')
|
|
713
717
|
|
|
714
|
-
logging.log(logging.INFO, 'main: starting processes')
|
|
715
|
-
rses_to_process = get_rses_to_process(rses, include_rses, exclude_rses, vos)
|
|
716
|
-
if not rses_to_process:
|
|
717
|
-
logging.log(logging.ERROR, 'Reaper: No RSEs found. Exiting.')
|
|
718
|
-
return
|
|
719
|
-
|
|
720
|
-
logging.log(logging.INFO, 'Reaper: This instance will work on RSEs: %s', ', '.join([rse['rse'] for rse in rses_to_process]))
|
|
721
|
-
|
|
722
718
|
logging.log(logging.INFO, 'starting reaper threads')
|
|
723
719
|
threads_list = [threading.Thread(target=reaper, kwargs={'once': once,
|
|
724
720
|
'rses': rses,
|
|
@@ -75,7 +75,7 @@ def set_status(
|
|
|
75
75
|
:param rse_id: RSE ID.
|
|
76
76
|
:param status: RSE decommissioning status.
|
|
77
77
|
"""
|
|
78
|
-
config = attr_to_config(get_rse_attribute(rse_id, RseAttr.DECOMMISSION))
|
|
78
|
+
config = attr_to_config(get_rse_attribute(rse_id, RseAttr.DECOMMISSION)) # type: ignore (get_rse_attribute could return None)
|
|
79
79
|
config['status'] = status
|
|
80
80
|
# add_rse_attribute can handle updating existing entries too
|
|
81
81
|
add_rse_attribute(rse_id, RseAttr.DECOMMISSION, config_to_attr(config))
|
|
@@ -14,7 +14,6 @@
|
|
|
14
14
|
|
|
15
15
|
"""Generic decommissioning profiles."""
|
|
16
16
|
import logging
|
|
17
|
-
from collections.abc import Callable, Iterable
|
|
18
17
|
from datetime import datetime, timedelta
|
|
19
18
|
from typing import TYPE_CHECKING, Any
|
|
20
19
|
|
|
@@ -32,6 +31,8 @@ from rucio.db.sqla.constants import ReplicaState
|
|
|
32
31
|
from .types import DecommissioningProfile, HandlerOutcome
|
|
33
32
|
|
|
34
33
|
if TYPE_CHECKING:
|
|
34
|
+
from collections.abc import Iterable
|
|
35
|
+
|
|
35
36
|
from rucio.common.types import LoggerFunction
|
|
36
37
|
|
|
37
38
|
|
|
@@ -137,7 +138,7 @@ def _generic_discover(
|
|
|
137
138
|
rse: dict[str, Any],
|
|
138
139
|
*,
|
|
139
140
|
logger: "LoggerFunction" = logging.log
|
|
140
|
-
) -> Iterable[dict[str, Any]]:
|
|
141
|
+
) -> 'Iterable[dict[str, Any]]':
|
|
141
142
|
"""Discoverer function that calls the listing function from core.rule.
|
|
142
143
|
|
|
143
144
|
:param rse: RSE table entry as a dictionary.
|
|
@@ -186,7 +187,7 @@ def _generic_finalize(
|
|
|
186
187
|
|
|
187
188
|
def _process_replicas_with_no_locks(
|
|
188
189
|
rse: dict[str, Any],
|
|
189
|
-
replicas: Iterable[dict[str, Any]],
|
|
190
|
+
replicas: 'Iterable[dict[str, Any]]',
|
|
190
191
|
limit: int = 0,
|
|
191
192
|
*,
|
|
192
193
|
logger: "LoggerFunction" = logging.log,
|
|
@@ -382,7 +383,7 @@ def _call_for_attention(
|
|
|
382
383
|
rule: dict[str, Any],
|
|
383
384
|
rse: dict[str, Any],
|
|
384
385
|
*,
|
|
385
|
-
logger:
|
|
386
|
+
logger: "LoggerFunction" = logging.log
|
|
386
387
|
) -> HandlerOutcome:
|
|
387
388
|
return HandlerOutcome.NEED_ATTENTION
|
|
388
389
|
|
|
@@ -14,12 +14,13 @@
|
|
|
14
14
|
|
|
15
15
|
"""Types used for profile definitions."""
|
|
16
16
|
import logging
|
|
17
|
-
from collections.abc import Callable, Iterable
|
|
18
17
|
from dataclasses import dataclass
|
|
19
18
|
from enum import Enum
|
|
20
19
|
from typing import TYPE_CHECKING, Any
|
|
21
20
|
|
|
22
21
|
if TYPE_CHECKING:
|
|
22
|
+
from collections.abc import Callable, Iterable
|
|
23
|
+
|
|
23
24
|
from rucio.common.types import LoggerFunction
|
|
24
25
|
|
|
25
26
|
|
|
@@ -42,10 +43,10 @@ class DecommissioningProfile:
|
|
|
42
43
|
"""
|
|
43
44
|
|
|
44
45
|
rse: dict[str, Any]
|
|
45
|
-
initializer: Callable[..., None]
|
|
46
|
-
discoverer: Callable[..., Iterable[dict[str, Any]]]
|
|
47
|
-
handlers: list[tuple[Callable[..., bool], Callable[..., HandlerOutcome]]]
|
|
48
|
-
finalizer: Callable[..., bool]
|
|
46
|
+
initializer: "Callable[..., None]"
|
|
47
|
+
discoverer: "Callable[..., Iterable[dict[str, Any]]]"
|
|
48
|
+
handlers: list[tuple["Callable[..., bool]", "Callable[..., HandlerOutcome]"]]
|
|
49
|
+
finalizer: "Callable[..., bool]"
|
|
49
50
|
|
|
50
51
|
def initialize(
|
|
51
52
|
self,
|
|
@@ -59,7 +60,7 @@ class DecommissioningProfile:
|
|
|
59
60
|
self,
|
|
60
61
|
*,
|
|
61
62
|
logger: "LoggerFunction" = logging.log
|
|
62
|
-
) -> Iterable[dict[str, Any]]:
|
|
63
|
+
) -> 'Iterable[dict[str, Any]]':
|
|
63
64
|
"""Call the discoverer."""
|
|
64
65
|
return self.discoverer(self.rse, logger=logger)
|
|
65
66
|
|
|
@@ -98,7 +98,7 @@ def run_once(
|
|
|
98
98
|
# Get the decommission attribute (encodes the decommissioning config)
|
|
99
99
|
attr = get_rse_attribute(rse['id'], RseAttr.DECOMMISSION)
|
|
100
100
|
try:
|
|
101
|
-
config = attr_to_config(attr)
|
|
101
|
+
config = attr_to_config(attr) # type: ignore (attr could be None)
|
|
102
102
|
except InvalidStatusName:
|
|
103
103
|
logger(logging.ERROR, 'RSE %s has an invalid decommissioning status',
|
|
104
104
|
rse['rse'])
|
|
@@ -35,7 +35,7 @@ from sqlalchemy.orm.exc import FlushError
|
|
|
35
35
|
|
|
36
36
|
from rucio.common import exception
|
|
37
37
|
from rucio.common.logging import formatted_logger, setup_logging
|
|
38
|
-
from rucio.common.types import InternalAccount, InternalScope
|
|
38
|
+
from rucio.common.types import InternalAccount, InternalScope, LFNDict
|
|
39
39
|
from rucio.common.utils import daemon_sleep
|
|
40
40
|
from rucio.core.heartbeat import die, live, sanity_check
|
|
41
41
|
from rucio.core.monitor import MetricManager
|
|
@@ -443,16 +443,18 @@ def process_dark_files(
|
|
|
443
443
|
logger(logging.INFO, 'Processing a dark file:\n RSE %s Scope: %s Name: %s'
|
|
444
444
|
% (rse, scope, name))
|
|
445
445
|
rse_id = get_rse_id(rse=rse)
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
446
|
+
internal_scope = InternalScope(scope=scope, vo=issuer.vo)
|
|
447
|
+
lfn: "LFNDict" = {
|
|
448
|
+
'scope': scope,
|
|
449
|
+
'name': name,
|
|
450
|
+
}
|
|
449
451
|
attributes = get_rse_info(rse=rse)
|
|
450
|
-
pfns = lfns2pfns(rse_settings=attributes, lfns=
|
|
452
|
+
pfns = lfns2pfns(rse_settings=attributes, lfns=[lfn], operation='delete')
|
|
451
453
|
pfn_key = scope + ':' + name
|
|
452
454
|
url = pfns[pfn_key]
|
|
453
455
|
urls = [url]
|
|
454
456
|
paths = parse_pfns(attributes, urls, operation='delete')
|
|
455
|
-
replicas = [{'scope':
|
|
457
|
+
replicas = [{'scope': internal_scope, 'rse_id': rse_id, 'name': name,
|
|
456
458
|
'path': paths[url]['path'] + paths[url]['name']}]
|
|
457
459
|
add_quarantined_replicas(rse_id, replicas, session=None)
|
|
458
460
|
deleted_files += 1
|