rucio 37.0.0rc3__py3-none-any.whl → 37.1.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.

Files changed (90) hide show
  1. rucio/cli/account.py +14 -14
  2. rucio/cli/command.py +9 -9
  3. rucio/cli/config.py +3 -3
  4. rucio/cli/did.py +13 -13
  5. rucio/cli/lifetime_exception.py +1 -1
  6. rucio/cli/replica.py +3 -3
  7. rucio/cli/rse.py +18 -18
  8. rucio/cli/rule.py +5 -5
  9. rucio/cli/scope.py +2 -2
  10. rucio/cli/subscription.py +4 -4
  11. rucio/client/baseclient.py +0 -3
  12. rucio/client/lifetimeclient.py +46 -13
  13. rucio/common/config.py +0 -26
  14. rucio/common/stomp_utils.py +119 -383
  15. rucio/common/utils.py +14 -17
  16. rucio/core/account_limit.py +56 -79
  17. rucio/core/did_meta_plugins/filter_engine.py +1 -3
  18. rucio/core/rse_selector.py +3 -3
  19. rucio/core/rule_grouping.py +0 -1
  20. rucio/daemons/cache/consumer.py +90 -26
  21. rucio/daemons/conveyor/receiver.py +123 -53
  22. rucio/daemons/hermes/hermes.py +343 -41
  23. rucio/daemons/tracer/kronos.py +139 -114
  24. rucio/gateway/account_limit.py +40 -76
  25. rucio/transfertool/fts3.py +1 -1
  26. rucio/vcsversion.py +4 -4
  27. rucio/web/rest/flaskapi/v1/accounts.py +3 -9
  28. rucio/web/rest/flaskapi/v1/auth.py +3 -3
  29. rucio/web/rest/flaskapi/v1/common.py +10 -4
  30. {rucio-37.0.0rc3.data → rucio-37.1.0.data}/scripts/rucio-replica-recoverer +1 -1
  31. {rucio-37.0.0rc3.dist-info → rucio-37.1.0.dist-info}/METADATA +1 -1
  32. {rucio-37.0.0rc3.dist-info → rucio-37.1.0.dist-info}/RECORD +90 -90
  33. {rucio-37.0.0rc3.data → rucio-37.1.0.data}/data/rucio/etc/alembic.ini.template +0 -0
  34. {rucio-37.0.0rc3.data → rucio-37.1.0.data}/data/rucio/etc/alembic_offline.ini.template +0 -0
  35. {rucio-37.0.0rc3.data → rucio-37.1.0.data}/data/rucio/etc/globus-config.yml.template +0 -0
  36. {rucio-37.0.0rc3.data → rucio-37.1.0.data}/data/rucio/etc/ldap.cfg.template +0 -0
  37. {rucio-37.0.0rc3.data → rucio-37.1.0.data}/data/rucio/etc/mail_templates/rule_approval_request.tmpl +0 -0
  38. {rucio-37.0.0rc3.data → rucio-37.1.0.data}/data/rucio/etc/mail_templates/rule_approved_admin.tmpl +0 -0
  39. {rucio-37.0.0rc3.data → rucio-37.1.0.data}/data/rucio/etc/mail_templates/rule_approved_user.tmpl +0 -0
  40. {rucio-37.0.0rc3.data → rucio-37.1.0.data}/data/rucio/etc/mail_templates/rule_denied_admin.tmpl +0 -0
  41. {rucio-37.0.0rc3.data → rucio-37.1.0.data}/data/rucio/etc/mail_templates/rule_denied_user.tmpl +0 -0
  42. {rucio-37.0.0rc3.data → rucio-37.1.0.data}/data/rucio/etc/mail_templates/rule_ok_notification.tmpl +0 -0
  43. {rucio-37.0.0rc3.data → rucio-37.1.0.data}/data/rucio/etc/rse-accounts.cfg.template +0 -0
  44. {rucio-37.0.0rc3.data → rucio-37.1.0.data}/data/rucio/etc/rucio.cfg.atlas.client.template +0 -0
  45. {rucio-37.0.0rc3.data → rucio-37.1.0.data}/data/rucio/etc/rucio.cfg.template +0 -0
  46. {rucio-37.0.0rc3.data → rucio-37.1.0.data}/data/rucio/etc/rucio_multi_vo.cfg.template +0 -0
  47. {rucio-37.0.0rc3.data → rucio-37.1.0.data}/data/rucio/requirements.server.txt +0 -0
  48. {rucio-37.0.0rc3.data → rucio-37.1.0.data}/data/rucio/tools/bootstrap.py +0 -0
  49. {rucio-37.0.0rc3.data → rucio-37.1.0.data}/data/rucio/tools/merge_rucio_configs.py +0 -0
  50. {rucio-37.0.0rc3.data → rucio-37.1.0.data}/data/rucio/tools/reset_database.py +0 -0
  51. {rucio-37.0.0rc3.data → rucio-37.1.0.data}/scripts/rucio +0 -0
  52. {rucio-37.0.0rc3.data → rucio-37.1.0.data}/scripts/rucio-abacus-account +0 -0
  53. {rucio-37.0.0rc3.data → rucio-37.1.0.data}/scripts/rucio-abacus-collection-replica +0 -0
  54. {rucio-37.0.0rc3.data → rucio-37.1.0.data}/scripts/rucio-abacus-rse +0 -0
  55. {rucio-37.0.0rc3.data → rucio-37.1.0.data}/scripts/rucio-admin +0 -0
  56. {rucio-37.0.0rc3.data → rucio-37.1.0.data}/scripts/rucio-atropos +0 -0
  57. {rucio-37.0.0rc3.data → rucio-37.1.0.data}/scripts/rucio-auditor +0 -0
  58. {rucio-37.0.0rc3.data → rucio-37.1.0.data}/scripts/rucio-automatix +0 -0
  59. {rucio-37.0.0rc3.data → rucio-37.1.0.data}/scripts/rucio-bb8 +0 -0
  60. {rucio-37.0.0rc3.data → rucio-37.1.0.data}/scripts/rucio-cache-client +0 -0
  61. {rucio-37.0.0rc3.data → rucio-37.1.0.data}/scripts/rucio-cache-consumer +0 -0
  62. {rucio-37.0.0rc3.data → rucio-37.1.0.data}/scripts/rucio-conveyor-finisher +0 -0
  63. {rucio-37.0.0rc3.data → rucio-37.1.0.data}/scripts/rucio-conveyor-poller +0 -0
  64. {rucio-37.0.0rc3.data → rucio-37.1.0.data}/scripts/rucio-conveyor-preparer +0 -0
  65. {rucio-37.0.0rc3.data → rucio-37.1.0.data}/scripts/rucio-conveyor-receiver +0 -0
  66. {rucio-37.0.0rc3.data → rucio-37.1.0.data}/scripts/rucio-conveyor-stager +0 -0
  67. {rucio-37.0.0rc3.data → rucio-37.1.0.data}/scripts/rucio-conveyor-submitter +0 -0
  68. {rucio-37.0.0rc3.data → rucio-37.1.0.data}/scripts/rucio-conveyor-throttler +0 -0
  69. {rucio-37.0.0rc3.data → rucio-37.1.0.data}/scripts/rucio-dark-reaper +0 -0
  70. {rucio-37.0.0rc3.data → rucio-37.1.0.data}/scripts/rucio-dumper +0 -0
  71. {rucio-37.0.0rc3.data → rucio-37.1.0.data}/scripts/rucio-follower +0 -0
  72. {rucio-37.0.0rc3.data → rucio-37.1.0.data}/scripts/rucio-hermes +0 -0
  73. {rucio-37.0.0rc3.data → rucio-37.1.0.data}/scripts/rucio-judge-cleaner +0 -0
  74. {rucio-37.0.0rc3.data → rucio-37.1.0.data}/scripts/rucio-judge-evaluator +0 -0
  75. {rucio-37.0.0rc3.data → rucio-37.1.0.data}/scripts/rucio-judge-injector +0 -0
  76. {rucio-37.0.0rc3.data → rucio-37.1.0.data}/scripts/rucio-judge-repairer +0 -0
  77. {rucio-37.0.0rc3.data → rucio-37.1.0.data}/scripts/rucio-kronos +0 -0
  78. {rucio-37.0.0rc3.data → rucio-37.1.0.data}/scripts/rucio-minos +0 -0
  79. {rucio-37.0.0rc3.data → rucio-37.1.0.data}/scripts/rucio-minos-temporary-expiration +0 -0
  80. {rucio-37.0.0rc3.data → rucio-37.1.0.data}/scripts/rucio-necromancer +0 -0
  81. {rucio-37.0.0rc3.data → rucio-37.1.0.data}/scripts/rucio-oauth-manager +0 -0
  82. {rucio-37.0.0rc3.data → rucio-37.1.0.data}/scripts/rucio-reaper +0 -0
  83. {rucio-37.0.0rc3.data → rucio-37.1.0.data}/scripts/rucio-rse-decommissioner +0 -0
  84. {rucio-37.0.0rc3.data → rucio-37.1.0.data}/scripts/rucio-storage-consistency-actions +0 -0
  85. {rucio-37.0.0rc3.data → rucio-37.1.0.data}/scripts/rucio-transmogrifier +0 -0
  86. {rucio-37.0.0rc3.data → rucio-37.1.0.data}/scripts/rucio-undertaker +0 -0
  87. {rucio-37.0.0rc3.dist-info → rucio-37.1.0.dist-info}/WHEEL +0 -0
  88. {rucio-37.0.0rc3.dist-info → rucio-37.1.0.dist-info}/licenses/AUTHORS.rst +0 -0
  89. {rucio-37.0.0rc3.dist-info → rucio-37.1.0.dist-info}/licenses/LICENSE +0 -0
  90. {rucio-37.0.0rc3.dist-info → rucio-37.1.0.dist-info}/top_level.txt +0 -0
@@ -15,18 +15,22 @@
15
15
  """
16
16
  Conveyor is a daemon to manage file transfers.
17
17
  """
18
+
18
19
  import json
19
20
  import logging
21
+ import socket
20
22
  import threading
21
23
  import time
22
24
  import traceback
23
- from typing import TYPE_CHECKING, Any
25
+ from typing import TYPE_CHECKING, Any, Optional
26
+
27
+ import stomp
24
28
 
25
29
  import rucio.db.sqla.util
26
30
  from rucio.common import exception
27
- from rucio.common.logging import formatted_logger, setup_logging
31
+ from rucio.common.config import config_get, config_get_bool, config_get_int, config_get_list
32
+ from rucio.common.logging import setup_logging
28
33
  from rucio.common.policy import get_policy
29
- from rucio.common.stomp_utils import Connection, ListenerBase, StompConnectionManager
30
34
  from rucio.core import request as request_core
31
35
  from rucio.core import transfer as transfer_core
32
36
  from rucio.core.monitor import MetricManager
@@ -49,22 +53,26 @@ GRACEFUL_STOP = threading.Event()
49
53
  DAEMON_NAME = 'conveyor-receiver'
50
54
 
51
55
 
52
- class Receiver(ListenerBase):
56
+ class Receiver:
53
57
 
54
- def __init__(self,
55
- conn: Connection,
56
- id_: str,
57
- total_threads: int,
58
- transfer_stats_manager: request_core.TransferStatsManager,
59
- all_vos: bool = False,
60
- logger: "LoggerFunction" = logging.log,
61
- **kwargs: dict) -> None:
62
- super().__init__(conn, logger, **kwargs)
58
+ def __init__(
59
+ self,
60
+ broker: str,
61
+ id_: str,
62
+ total_threads: int,
63
+ transfer_stats_manager: request_core.TransferStatsManager,
64
+ all_vos: bool = False
65
+ ):
63
66
  self.__all_vos = all_vos
67
+ self.__broker = broker
64
68
  self.__id = id_
65
69
  self.__total_threads = total_threads
66
70
  self._transfer_stats_manager = transfer_stats_manager
67
71
 
72
+ @METRICS.count_it
73
+ def on_error(self, frame: "Frame") -> None:
74
+ logging.error('[%s] %s' % (self.__broker, frame.body))
75
+
68
76
  @METRICS.count_it
69
77
  def on_message(self, frame: "Frame") -> None:
70
78
  msg = json.loads(frame.body) # type: ignore
@@ -78,8 +86,7 @@ class Receiver(ListenerBase):
78
86
  and 'issuer' in msg['job_metadata'].keys() \
79
87
  and str(msg['job_metadata']['issuer']) == 'rucio':
80
88
 
81
- if ('job_state' in msg.keys() and (str(msg['job_state']) != 'ACTIVE'
82
- or msg.get('job_multihop', False) is True)):
89
+ if 'job_state' in msg.keys() and (str(msg['job_state']) != 'ACTIVE' or msg.get('job_multihop', False) is True):
83
90
  METRICS.counter('message_rucio').inc()
84
91
 
85
92
  self._perform_request_update(msg)
@@ -89,15 +96,13 @@ class Receiver(ListenerBase):
89
96
  self,
90
97
  msg: dict[str, Any],
91
98
  *,
92
- session: "Session | None",
99
+ session: Optional["Session"] = None,
93
100
  logger: "LoggerFunction" = logging.log
94
101
  ) -> None:
95
102
  external_host = msg.get('endpnt', None)
96
103
  request_id = msg['file_metadata'].get('request_id', None)
97
104
  try:
98
- tt_status_report = FTS3CompletionMessageTransferStatusReport(external_host,
99
- request_id=request_id,
100
- fts_message=msg)
105
+ tt_status_report = FTS3CompletionMessageTransferStatusReport(external_host, request_id=request_id, fts_message=msg)
101
106
  if tt_status_report.get_db_fields_to_update(session=session, logger=logger): # type: ignore
102
107
  logging.info('RECEIVED %s', tt_status_report)
103
108
 
@@ -115,39 +120,103 @@ class Receiver(ListenerBase):
115
120
  logging.critical(traceback.format_exc())
116
121
 
117
122
 
118
- def receiver(id_: str,
119
- total_threads: int = 1,
120
- all_vos: bool = False,
121
- logger: "LoggerFunction" = logging.log):
123
+ def receiver(
124
+ id_: str,
125
+ total_threads: int = 1,
126
+ all_vos: bool = False
127
+ ) -> None:
122
128
  """
123
129
  Main loop to consume messages from the FTS3 producer.
124
130
  """
125
- logger(logging.INFO, 'receiver starting')
126
-
127
- conn_mgr = StompConnectionManager(config_section='messaging-fts3', logger=logger)
128
131
 
129
- logger(logging.INFO, 'receiver started')
130
-
131
- with (HeartbeatHandler(executable=DAEMON_NAME, renewal_interval=30),
132
+ logging.info('receiver starting')
133
+
134
+ brokers_alias = []
135
+ brokers_resolved = []
136
+ try:
137
+ brokers_alias = config_get_list('messaging-fts3', 'brokers')
138
+ except Exception:
139
+ raise Exception('Could not load brokers from configuration')
140
+
141
+ logging.info('resolving broker dns alias: %s' % brokers_alias)
142
+
143
+ brokers_resolved = []
144
+ for broker in brokers_alias:
145
+ addrinfos = socket.getaddrinfo(broker, 0, socket.AF_INET, 0, socket.IPPROTO_TCP)
146
+ brokers_resolved.extend(ai[4][0] for ai in addrinfos)
147
+
148
+ logging.info('brokers resolved to %s', brokers_resolved)
149
+
150
+ logging.info('checking authentication method')
151
+ use_ssl = True
152
+ try:
153
+ use_ssl = config_get_bool('messaging-fts3', 'use_ssl')
154
+ except:
155
+ logging.info('could not find use_ssl in configuration -- please update your rucio.cfg')
156
+
157
+ port = config_get_int('messaging-fts3', 'port')
158
+ vhost = config_get('messaging-fts3', 'broker_virtual_host', raise_exception=False)
159
+ if not use_ssl:
160
+ username = config_get('messaging-fts3', 'username')
161
+ password = config_get('messaging-fts3', 'password')
162
+ port = config_get_int('messaging-fts3', 'nonssl_port')
163
+
164
+ conns = []
165
+ for broker in brokers_resolved:
166
+ if not use_ssl:
167
+ logging.info('setting up username/password authentication: %s' % broker)
168
+ else:
169
+ logging.info('setting up ssl cert/key authentication: %s' % broker)
170
+ con = stomp.Connection12(host_and_ports=[(broker, port)],
171
+ vhost=vhost,
172
+ reconnect_attempts_max=999)
173
+ if use_ssl:
174
+ con.set_ssl(
175
+ key_file=config_get('messaging-fts3', 'ssl_key_file'),
176
+ cert_file=config_get('messaging-fts3', 'ssl_cert_file'),
177
+ )
178
+ conns.append(con)
179
+
180
+ logging.info('receiver started')
181
+
182
+ with (HeartbeatHandler(executable=DAEMON_NAME, renewal_interval=30) as heartbeat_handler,
132
183
  request_core.TransferStatsManager() as transfer_stats_manager):
133
-
134
- conn_mgr.set_listener_factory('rucio-messaging-fts3', Receiver,
135
- id_=id_,
136
- total_threads=total_threads,
137
- transfer_stats_manager=transfer_stats_manager,
138
- all_vos=all_vos,
139
- heartbeats=conn_mgr.config.heartbeats)
140
-
141
184
  while not GRACEFUL_STOP.is_set():
142
185
 
143
- conn_mgr.subscribe(id_='rucio-messaging-fts3', ack='auto')
144
-
186
+ _, _, logger = heartbeat_handler.live()
187
+
188
+ for conn in conns:
189
+
190
+ if not conn.is_connected():
191
+ logger(logging.INFO, 'connecting to %s' % conn.transport._Transport__host_and_ports[0][0])
192
+ METRICS.counter('reconnect.{host}').labels(host=conn.transport._Transport__host_and_ports[0][0].split('.')[0]).inc()
193
+
194
+ conn.set_listener(
195
+ 'rucio-messaging-fts3',
196
+ Receiver(
197
+ broker=conn.transport._Transport__host_and_ports[0],
198
+ id_=id_,
199
+ total_threads=total_threads,
200
+ transfer_stats_manager=transfer_stats_manager,
201
+ all_vos=all_vos
202
+ ))
203
+ if not use_ssl:
204
+ conn.connect(username, password, wait=True)
205
+ else:
206
+ conn.connect(wait=True)
207
+ conn.subscribe(destination=config_get('messaging-fts3', 'destination'),
208
+ id='rucio-messaging-fts3',
209
+ ack='auto')
145
210
  time.sleep(1)
146
211
 
147
- conn_mgr.disconnect()
212
+ for conn in conns:
213
+ try:
214
+ conn.disconnect()
215
+ except Exception:
216
+ pass
148
217
 
149
218
 
150
- def stop(signum: "int | None" = None, frame: "FrameType | None" = None) -> None:
219
+ def stop(signum: Optional[int] = None, frame: Optional["FrameType"] = None) -> None:
151
220
  """
152
221
  Graceful exit.
153
222
  """
@@ -155,25 +224,26 @@ def stop(signum: "int | None" = None, frame: "FrameType | None" = None) -> None:
155
224
  GRACEFUL_STOP.set()
156
225
 
157
226
 
158
- def run(once: bool = False, total_threads: int = 1) -> None:
227
+ def run(
228
+ once: bool = False,
229
+ total_threads: int = 1
230
+ ) -> None:
159
231
  """
160
232
  Starts up the receiver thread
161
233
  """
162
234
  setup_logging(process_name=DAEMON_NAME)
163
- logger = formatted_logger(logging.log, DAEMON_NAME + ' %s')
164
235
 
165
236
  if rucio.db.sqla.util.is_old_db():
166
237
  raise exception.DatabaseException('Database was not updated, daemon won\'t start')
167
238
 
168
- logger(logging.INFO, 'starting receiver thread')
169
- threads = []
170
- for i in range(total_threads):
171
- rec_thread = threading.Thread(target=receiver,
172
- kwargs={'id_': i, 'logger': logger, 'total_threads': total_threads})
173
- rec_thread.start()
174
- threads.append(rec_thread)
239
+ logging.info('starting receiver thread')
240
+ threads = [threading.Thread(target=receiver, kwargs={'id_': i,
241
+ 'total_threads': total_threads}) for i in range(0, total_threads)]
242
+
243
+ [thread.start() for thread in threads]
175
244
 
176
- logger(logging.INFO, 'waiting for interrupts')
245
+ logging.info('waiting for interrupts')
177
246
 
178
- while [thread.join(timeout=3.14) for thread in threads if thread.is_alive()]:
179
- pass
247
+ # Interruptible joins require a timeout.
248
+ while threads:
249
+ threads = [thread.join(timeout=3.14) for thread in threads if thread and thread.is_alive()]