rucio-clients 37.0.0rc1__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-clients might be problematic. Click here for more details.

Files changed (104) hide show
  1. rucio/__init__.py +17 -0
  2. rucio/alembicrevision.py +15 -0
  3. rucio/cli/__init__.py +14 -0
  4. rucio/cli/account.py +216 -0
  5. rucio/cli/bin_legacy/__init__.py +13 -0
  6. rucio/cli/bin_legacy/rucio.py +2825 -0
  7. rucio/cli/bin_legacy/rucio_admin.py +2500 -0
  8. rucio/cli/command.py +272 -0
  9. rucio/cli/config.py +72 -0
  10. rucio/cli/did.py +191 -0
  11. rucio/cli/download.py +128 -0
  12. rucio/cli/lifetime_exception.py +33 -0
  13. rucio/cli/replica.py +162 -0
  14. rucio/cli/rse.py +293 -0
  15. rucio/cli/rule.py +158 -0
  16. rucio/cli/scope.py +40 -0
  17. rucio/cli/subscription.py +73 -0
  18. rucio/cli/upload.py +60 -0
  19. rucio/cli/utils.py +226 -0
  20. rucio/client/__init__.py +15 -0
  21. rucio/client/accountclient.py +432 -0
  22. rucio/client/accountlimitclient.py +183 -0
  23. rucio/client/baseclient.py +983 -0
  24. rucio/client/client.py +120 -0
  25. rucio/client/configclient.py +126 -0
  26. rucio/client/credentialclient.py +59 -0
  27. rucio/client/didclient.py +868 -0
  28. rucio/client/diracclient.py +56 -0
  29. rucio/client/downloadclient.py +1783 -0
  30. rucio/client/exportclient.py +44 -0
  31. rucio/client/fileclient.py +50 -0
  32. rucio/client/importclient.py +42 -0
  33. rucio/client/lifetimeclient.py +90 -0
  34. rucio/client/lockclient.py +109 -0
  35. rucio/client/metaconventionsclient.py +140 -0
  36. rucio/client/pingclient.py +44 -0
  37. rucio/client/replicaclient.py +452 -0
  38. rucio/client/requestclient.py +125 -0
  39. rucio/client/richclient.py +317 -0
  40. rucio/client/rseclient.py +746 -0
  41. rucio/client/ruleclient.py +294 -0
  42. rucio/client/scopeclient.py +90 -0
  43. rucio/client/subscriptionclient.py +173 -0
  44. rucio/client/touchclient.py +82 -0
  45. rucio/client/uploadclient.py +969 -0
  46. rucio/common/__init__.py +13 -0
  47. rucio/common/bittorrent.py +234 -0
  48. rucio/common/cache.py +111 -0
  49. rucio/common/checksum.py +168 -0
  50. rucio/common/client.py +122 -0
  51. rucio/common/config.py +788 -0
  52. rucio/common/constants.py +217 -0
  53. rucio/common/constraints.py +17 -0
  54. rucio/common/didtype.py +237 -0
  55. rucio/common/exception.py +1208 -0
  56. rucio/common/extra.py +31 -0
  57. rucio/common/logging.py +420 -0
  58. rucio/common/pcache.py +1409 -0
  59. rucio/common/plugins.py +185 -0
  60. rucio/common/policy.py +93 -0
  61. rucio/common/schema/__init__.py +200 -0
  62. rucio/common/schema/generic.py +416 -0
  63. rucio/common/schema/generic_multi_vo.py +395 -0
  64. rucio/common/stomp_utils.py +423 -0
  65. rucio/common/stopwatch.py +55 -0
  66. rucio/common/test_rucio_server.py +154 -0
  67. rucio/common/types.py +483 -0
  68. rucio/common/utils.py +1688 -0
  69. rucio/rse/__init__.py +96 -0
  70. rucio/rse/protocols/__init__.py +13 -0
  71. rucio/rse/protocols/bittorrent.py +194 -0
  72. rucio/rse/protocols/cache.py +111 -0
  73. rucio/rse/protocols/dummy.py +100 -0
  74. rucio/rse/protocols/gfal.py +708 -0
  75. rucio/rse/protocols/globus.py +243 -0
  76. rucio/rse/protocols/http_cache.py +82 -0
  77. rucio/rse/protocols/mock.py +123 -0
  78. rucio/rse/protocols/ngarc.py +209 -0
  79. rucio/rse/protocols/posix.py +250 -0
  80. rucio/rse/protocols/protocol.py +361 -0
  81. rucio/rse/protocols/rclone.py +365 -0
  82. rucio/rse/protocols/rfio.py +145 -0
  83. rucio/rse/protocols/srm.py +338 -0
  84. rucio/rse/protocols/ssh.py +414 -0
  85. rucio/rse/protocols/storm.py +195 -0
  86. rucio/rse/protocols/webdav.py +594 -0
  87. rucio/rse/protocols/xrootd.py +302 -0
  88. rucio/rse/rsemanager.py +881 -0
  89. rucio/rse/translation.py +260 -0
  90. rucio/vcsversion.py +11 -0
  91. rucio/version.py +45 -0
  92. rucio_clients-37.0.0rc1.data/data/etc/rse-accounts.cfg.template +25 -0
  93. rucio_clients-37.0.0rc1.data/data/etc/rucio.cfg.atlas.client.template +43 -0
  94. rucio_clients-37.0.0rc1.data/data/etc/rucio.cfg.template +241 -0
  95. rucio_clients-37.0.0rc1.data/data/requirements.client.txt +19 -0
  96. rucio_clients-37.0.0rc1.data/data/rucio_client/merge_rucio_configs.py +144 -0
  97. rucio_clients-37.0.0rc1.data/scripts/rucio +133 -0
  98. rucio_clients-37.0.0rc1.data/scripts/rucio-admin +97 -0
  99. rucio_clients-37.0.0rc1.dist-info/METADATA +54 -0
  100. rucio_clients-37.0.0rc1.dist-info/RECORD +104 -0
  101. rucio_clients-37.0.0rc1.dist-info/WHEEL +5 -0
  102. rucio_clients-37.0.0rc1.dist-info/licenses/AUTHORS.rst +100 -0
  103. rucio_clients-37.0.0rc1.dist-info/licenses/LICENSE +201 -0
  104. rucio_clients-37.0.0rc1.dist-info/top_level.txt +1 -0
rucio/common/config.py ADDED
@@ -0,0 +1,788 @@
1
+ # Copyright European Organization for Nuclear Research (CERN) since 2012
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ """Provides functions to access the local configuration. The configuration locations are provided by get_config_dirs."""
16
+
17
+ import configparser
18
+ import json
19
+ import os
20
+ from functools import cache
21
+ from typing import TYPE_CHECKING, Any, Optional, TypeVar, Union, overload
22
+
23
+ from rucio.common import exception
24
+ from rucio.common.exception import ConfigLoadingError, ConfigNotFound, DatabaseException
25
+
26
+ _T = TypeVar('_T')
27
+ _U = TypeVar('_U')
28
+
29
+ if TYPE_CHECKING:
30
+ from collections.abc import Callable
31
+
32
+ from sqlalchemy.orm import Session
33
+
34
+ LEGACY_SECTION_NAME = {}
35
+ LEGACY_OPTION_NAME = {}
36
+
37
+
38
+ def convert_to_any_type(value: str) -> Union[bool, int, float, str]:
39
+ if value.lower() in ['true', 'yes', 'on']:
40
+ return True
41
+ elif value.lower() in ['false', 'no', 'off']:
42
+ return False
43
+
44
+ for conv in (int, float):
45
+ try:
46
+ return conv(value)
47
+ except:
48
+ pass
49
+
50
+ return value
51
+
52
+
53
+ def _convert_to_boolean(value: Union[str, bool]) -> bool:
54
+ if isinstance(value, bool):
55
+ return value
56
+ if value.lower() in ['true', 'yes', 'on', '1']:
57
+ return True
58
+ elif value.lower() in ['false', 'no', 'off', '0']:
59
+ return False
60
+ raise ValueError('Not a boolean: %s' % value)
61
+
62
+
63
+ @overload
64
+ def config_get(
65
+ section: str,
66
+ option: str,
67
+ *,
68
+ clean_cached: bool = ...,
69
+ check_config_table: bool = ...,
70
+ session: "Optional[Session]" = ...,
71
+ use_cache: bool = ...,
72
+ expiration_time: int = ...,
73
+ ) -> str:
74
+ ...
75
+
76
+
77
+ @overload
78
+ def config_get(
79
+ section: str,
80
+ option: str,
81
+ *,
82
+ default: _T = ...,
83
+ clean_cached: bool = ...,
84
+ check_config_table: bool = ...,
85
+ session: "Optional[Session]" = ...,
86
+ use_cache: bool = ...,
87
+ expiration_time: int = ...,
88
+ ) -> Union[str, _T]:
89
+ ...
90
+
91
+
92
+ @overload
93
+ def config_get(
94
+ section: str,
95
+ option: str,
96
+ raise_exception: bool,
97
+ default: _T = ...,
98
+ *,
99
+ clean_cached: bool = ...,
100
+ check_config_table: bool = ...,
101
+ session: "Optional[Session]" = ...,
102
+ use_cache: bool = ...,
103
+ expiration_time: int = ...,
104
+ ) -> Union[str, _T]:
105
+ ...
106
+
107
+
108
+ @overload
109
+ def config_get(
110
+ section: str,
111
+ option: str,
112
+ *,
113
+ clean_cached: bool = ...,
114
+ check_config_table: bool = ...,
115
+ session: "Optional[Session]" = ...,
116
+ use_cache: bool = ...,
117
+ expiration_time: int = ...,
118
+ convert_type_fnc: 'Callable[[str], _T]',
119
+ ) -> _T:
120
+ ...
121
+
122
+
123
+ @overload
124
+ def config_get(
125
+ section: str,
126
+ option: str,
127
+ *,
128
+ default: _T = ...,
129
+ clean_cached: bool = ...,
130
+ check_config_table: bool = ...,
131
+ session: "Optional[Session]" = ...,
132
+ use_cache: bool = ...,
133
+ expiration_time: int = ...,
134
+ convert_type_fnc: 'Callable[[str], _U]',
135
+ ) -> Union[_T, _U]:
136
+ ...
137
+
138
+
139
+ @overload
140
+ def config_get(
141
+ section: str,
142
+ option: str,
143
+ raise_exception: bool,
144
+ default: _T = ...,
145
+ *,
146
+ clean_cached: bool = ...,
147
+ check_config_table: bool = ...,
148
+ session: "Optional[Session]" = ...,
149
+ use_cache: bool = ...,
150
+ expiration_time: int = ...,
151
+ convert_type_fnc: 'Callable[[str], _U]',
152
+ ) -> Union[_T, _U]:
153
+ ...
154
+
155
+
156
+ def config_get(
157
+ section: str,
158
+ option: str,
159
+ raise_exception: bool = True,
160
+ default: _U = None,
161
+ clean_cached: bool = False,
162
+ check_config_table: bool = True,
163
+ session: "Optional[Session]" = None,
164
+ use_cache: bool = True,
165
+ expiration_time: int = 900,
166
+ convert_type_fnc: 'Callable[[str], _T]' = lambda x: x,
167
+ ) -> Union[_T, _U]:
168
+ """
169
+ Return the string value for a given option in a section
170
+
171
+ First it looks at the configuration file and, if it is not found, check in the config table only if it is called
172
+ from a server/daemon (and if check_config_table is set).
173
+
174
+ :param section: the named section.
175
+ :param option: the named option.
176
+ :param raise_exception: Boolean to raise or not NoOptionError, NoSectionError or RuntimeError.
177
+ :param default: the default value if not found.
178
+ :param clean_cached: Deletes the cached config singleton instance if no config value is found
179
+ :param check_config_table: if not set, avoid looking at config table even if it is called from server/daemon
180
+ :param session: The database session in use. Only used if not found in config file and if it is called from
181
+ server/daemon
182
+ :param use_cache: Boolean if the cache should be used. Only used if not found in config file and if it is called
183
+ from server/daemon
184
+ :param expiration_time: Time after that the cached value gets ignored. Only used if not found in config file and if
185
+ it is called from server/daemon
186
+ :param convert_type_fnc: A function used to parse the string config value into the desired destination type
187
+
188
+ :returns: the configuration value.
189
+
190
+ :raises NoOptionError
191
+ :raises NoSectionError
192
+ :raises RuntimeError
193
+ """
194
+ try:
195
+ return convert_type_fnc(get_config().get(section, option))
196
+ except (configparser.NoOptionError, configparser.NoSectionError, ConfigNotFound) as err:
197
+ try:
198
+ legacy_config = get_legacy_config(section, option)
199
+ if legacy_config is not None:
200
+ return convert_type_fnc(legacy_config)
201
+ except ConfigNotFound:
202
+ pass
203
+
204
+ from rucio.common.client import is_client
205
+ client_mode = is_client()
206
+
207
+ if not client_mode and check_config_table:
208
+ try:
209
+ return __config_get_table(section=section, option=option, raise_exception=raise_exception,
210
+ default=default, clean_cached=clean_cached, session=session,
211
+ use_cache=use_cache, expiration_time=expiration_time,
212
+ convert_type_fnc=convert_type_fnc)
213
+ except (ConfigNotFound, DatabaseException, ImportError):
214
+ raise err
215
+ else:
216
+ if raise_exception and default is None:
217
+ raise err
218
+ if clean_cached:
219
+ clean_cached_config()
220
+ return default
221
+
222
+
223
+ def get_legacy_config(section: str, option: str):
224
+ """
225
+ Returns a legacy config value, if it is present.
226
+
227
+ :param section: The section of the new config.
228
+ :param option: The option of the new config.
229
+ :returns: The string value of the legacy option if one is found, None otherwise.
230
+ """
231
+
232
+ section = LEGACY_SECTION_NAME.get(section, section)
233
+ option = LEGACY_OPTION_NAME.get(option, option)
234
+
235
+ if config_has_option(section, option):
236
+ return get_config().get(section, option)
237
+
238
+ return None
239
+
240
+
241
+ def config_has_section(section: str) -> bool:
242
+ """
243
+ Indicates whether the named section is present in the configuration. The DEFAULT section is not acknowledged.
244
+
245
+ :param section: Name of section in the Rucio config to verify.
246
+ :returns: True if the section exists in the configuration; False otherwise
247
+ """
248
+ return get_config().has_section(section)
249
+
250
+
251
+ def config_has_option(section: str, option: str) -> bool:
252
+ """
253
+ Indicates whether the named option is present in the configuration. The DEFAULT section is not acknowledged.
254
+
255
+ :param section: Name of section in the Rucio config to verify.
256
+ :param option: Name of option in the Rucio config to verify.
257
+ :returns: True if the section and option exists in the configuration; False otherwise
258
+ """
259
+ return get_config().has_option(section, option)
260
+
261
+
262
+ def config_add_section(section: str):
263
+ """
264
+ Add a new section to the configuration object. Throws DuplicateSectionError if it already exists.
265
+
266
+ :param section: Name of section in the Rucio config to add.
267
+ :returns: None
268
+ """
269
+ return get_config().add_section(section)
270
+
271
+
272
+ @overload
273
+ def config_get_int(
274
+ section: str,
275
+ option: str,
276
+ *,
277
+ check_config_table: bool = ...,
278
+ session: "Optional[Session]" = ...,
279
+ use_cache: bool = ...,
280
+ expiration_time: int = ...,
281
+ ) -> int:
282
+ ...
283
+
284
+
285
+ @overload
286
+ def config_get_int(
287
+ section: str,
288
+ option: str,
289
+ *,
290
+ default: int = ...,
291
+ check_config_table: bool = ...,
292
+ session: "Optional[Session]" = ...,
293
+ use_cache: bool = ...,
294
+ expiration_time: int = ...,
295
+ ) -> int:
296
+ ...
297
+
298
+
299
+ @overload
300
+ def config_get_int(
301
+ section: str,
302
+ option: str,
303
+ raise_exception: bool,
304
+ default: _T = ...,
305
+ *,
306
+ check_config_table: bool = ...,
307
+ session: "Optional[Session]" = ...,
308
+ use_cache: bool = ...,
309
+ expiration_time: int = ...,
310
+ ) -> Union[int, _T]:
311
+ ...
312
+
313
+
314
+ def config_get_int(
315
+ section: str,
316
+ option: str,
317
+ raise_exception: bool = True,
318
+ default=None,
319
+ check_config_table: bool = True,
320
+ session: "Optional[Session]" = None,
321
+ use_cache: bool = True,
322
+ expiration_time: int = 900,
323
+ ):
324
+ """
325
+ Return the integer value for a given option in a section
326
+
327
+ :param section: the named section.
328
+ :param option: the named option.
329
+ :param raise_exception: Boolean to raise or not NoOptionError, NoSectionError or RuntimeError.
330
+ :param default: the default value if not found.
331
+ :param check_config_table: if not set, avoid looking at config table even if it is called from server/daemon
332
+ :param session: The database session in use. Only used if not found in config file and if it is called from
333
+ server/daemon
334
+ :param use_cache: Boolean if the cache should be used. Only used if not found in config file and if it is called
335
+ from server/daemon
336
+ :param expiration_time: Time after that the cached value gets ignored. Only used if not found in config file and if
337
+ it is called from server/daemon
338
+ :returns: the configuration value.
339
+
340
+ :raises NoOptionError
341
+ :raises NoSectionError
342
+ :raises RuntimeError
343
+ :raises ValueError
344
+ """
345
+ return config_get(
346
+ section,
347
+ option,
348
+ raise_exception=raise_exception,
349
+ default=default,
350
+ check_config_table=check_config_table,
351
+ session=session,
352
+ use_cache=use_cache,
353
+ expiration_time=expiration_time,
354
+ convert_type_fnc=int,
355
+ )
356
+
357
+
358
+ @overload
359
+ def config_get_float(
360
+ section: str,
361
+ option: str,
362
+ *,
363
+ check_config_table: bool = ...,
364
+ session: "Optional[Session]" = ...,
365
+ use_cache: bool = ...,
366
+ expiration_time: int = ...,
367
+ ) -> float:
368
+ ...
369
+
370
+
371
+ @overload
372
+ def config_get_float(
373
+ section: str,
374
+ option: str,
375
+ *,
376
+ default: float = ...,
377
+ check_config_table: bool = ...,
378
+ session: "Optional[Session]" = ...,
379
+ use_cache: bool = ...,
380
+ expiration_time: int = ...,
381
+ ) -> float:
382
+ ...
383
+
384
+
385
+ @overload
386
+ def config_get_float(
387
+ section: str,
388
+ option: str,
389
+ raise_exception,
390
+ default: _T = ...,
391
+ *,
392
+ check_config_table: bool = ...,
393
+ session: "Optional[Session]" = ...,
394
+ use_cache: bool = ...,
395
+ expiration_time: int = ...,
396
+ ) -> Union[float, _T]:
397
+ ...
398
+
399
+
400
+ def config_get_float(
401
+ section: str,
402
+ option: str,
403
+ raise_exception: bool = True,
404
+ default=None,
405
+ check_config_table: bool = True,
406
+ session: "Optional[Session]" = None,
407
+ use_cache: bool = True,
408
+ expiration_time: int = 900,
409
+ ):
410
+ """
411
+ Return the floating point value for a given option in a section
412
+
413
+ :param section: the named section.
414
+ :param option: the named option.
415
+ :param raise_exception: Boolean to raise or not NoOptionError, NoSectionError or RuntimeError.
416
+ :param default: the default value if not found.
417
+ :param check_config_table: if not set, avoid looking at config table even if it is called from server/daemon
418
+ :param session: The database session in use. Only used if not found in config file and if it is called from
419
+ server/daemon
420
+ :param use_cache: Boolean if the cache should be used. Only used if not found in config file and if it is called
421
+ from server/daemon
422
+ :param expiration_time: Time after that the cached value gets ignored. Only used if not found in config file and if
423
+ it is called from server/daemon
424
+
425
+ :returns: the configuration value.
426
+
427
+ :raises NoOptionError
428
+ :raises NoSectionError
429
+ :raises RuntimeError
430
+ :raises ValueError
431
+ """
432
+ return config_get(
433
+ section,
434
+ option,
435
+ raise_exception=raise_exception,
436
+ default=default,
437
+ check_config_table=check_config_table,
438
+ session=session,
439
+ use_cache=use_cache,
440
+ expiration_time=expiration_time,
441
+ convert_type_fnc=float,
442
+ )
443
+
444
+
445
+ @overload
446
+ def config_get_bool(
447
+ section: str,
448
+ option: str,
449
+ *,
450
+ check_config_table: bool = ...,
451
+ session: "Optional[Session]" = ...,
452
+ use_cache: bool = ...,
453
+ expiration_time: int = ...,
454
+ ) -> bool:
455
+ ...
456
+
457
+
458
+ @overload
459
+ def config_get_bool(
460
+ section: str,
461
+ option: str,
462
+ *,
463
+ default: bool = ...,
464
+ check_config_table: bool = ...,
465
+ session: "Optional[Session]" = ...,
466
+ use_cache: bool = ...,
467
+ expiration_time: int = ...,
468
+ ) -> bool:
469
+ ...
470
+
471
+
472
+ @overload
473
+ def config_get_bool(
474
+ section: str,
475
+ option: str,
476
+ raise_exception,
477
+ default: _T = ...,
478
+ *,
479
+ check_config_table: bool = ...,
480
+ session: "Optional[Session]" = ...,
481
+ use_cache: bool = ...,
482
+ expiration_time: int = ...,
483
+ ) -> Union[bool, _T]:
484
+ ...
485
+
486
+
487
+ def config_get_bool(
488
+ section: str,
489
+ option: str,
490
+ raise_exception: bool = True,
491
+ default=None,
492
+ check_config_table: bool = True,
493
+ session: "Optional[Session]" = None,
494
+ use_cache: bool = True,
495
+ expiration_time: int = 900,
496
+ ):
497
+ """
498
+ Return the boolean value for a given option in a section
499
+
500
+ :param section: the named section.
501
+ :param option: the named option.
502
+ :param raise_exception: Boolean to raise or not NoOptionError, NoSectionError or RuntimeError.
503
+ :param default: the default value if not found.
504
+ :param check_config_table: if not set, avoid looking at config table even if it is called from server/daemon
505
+ :param session: The database session in use. Only used if not found in config file and if it is called from
506
+ server/daemon
507
+ :param use_cache: Boolean if the cache should be used. Only used if not found in config file and if it is called
508
+ from server/daemon
509
+ :param expiration_time: Time after that the cached value gets ignored. Only used if not found in config file and if
510
+ it is called from server/daemon
511
+ .
512
+ :returns: the configuration value.
513
+
514
+ :raises NoOptionError
515
+ :raises NoSectionError
516
+ :raises RuntimeError
517
+ :raises ValueError
518
+ """
519
+ return config_get(
520
+ section,
521
+ option,
522
+ raise_exception=raise_exception,
523
+ default=default,
524
+ check_config_table=check_config_table,
525
+ session=session,
526
+ use_cache=use_cache,
527
+ expiration_time=expiration_time,
528
+ convert_type_fnc=_convert_to_boolean,
529
+ )
530
+
531
+
532
+ @overload
533
+ def config_get_list(
534
+ section: str,
535
+ option: str,
536
+ *,
537
+ check_config_table: bool = ...,
538
+ session: "Optional[Session]" = ...,
539
+ use_cache: bool = ...,
540
+ expiration_time: int = ...,
541
+ ) -> list[str]:
542
+ ...
543
+
544
+
545
+ @overload
546
+ def config_get_list(
547
+ section: str,
548
+ option: str,
549
+ *,
550
+ default: _T = ...,
551
+ check_config_table: bool = ...,
552
+ session: "Optional[Session]" = ...,
553
+ use_cache: bool = ...,
554
+ expiration_time: int = ...,
555
+ ) -> Union[list[str], _T]:
556
+ ...
557
+
558
+
559
+ @overload
560
+ def config_get_list(
561
+ section: str,
562
+ option: str,
563
+ raise_exception,
564
+ default: _T = ...,
565
+ *,
566
+ check_config_table: bool = ...,
567
+ session: "Optional[Session]" = ...,
568
+ use_cache: bool = ...,
569
+ expiration_time: int = ...,
570
+ ) -> Union[list[str], _T]:
571
+ ...
572
+
573
+
574
+ def config_get_list(
575
+ section: str,
576
+ option: str,
577
+ raise_exception: bool = True,
578
+ default=None,
579
+ check_config_table: bool = True,
580
+ session: "Optional[Session]" = None,
581
+ use_cache: bool = True,
582
+ expiration_time: int = 900,
583
+ ):
584
+ """
585
+ Return a list for a given option in a section
586
+
587
+ :param section: the named section.
588
+ :param option: the named option.
589
+ :param raise_exception: Boolean to raise or not NoOptionError, NoSectionError or RuntimeError.
590
+ :param default: the default value if not found.
591
+ :param check_config_table: if not set, avoid looking at config table even if it is called from server/daemon
592
+ :param session: The database session in use. Only used if not found in config file and if it is called from
593
+ server/daemon
594
+ :param use_cache: Boolean if the cache should be used. Only used if not found in config file and if it is called
595
+ from server/daemon
596
+ :param expiration_time: Time after that the cached value gets ignored. Only used if not found in config file and if
597
+ it is called from server/daemon
598
+ .
599
+ :returns: the configuration value.
600
+
601
+ :raises NoOptionError
602
+ :raises NoSectionError
603
+ :raises RuntimeError
604
+ :raises ValueError
605
+ """
606
+ value = config_get(
607
+ section,
608
+ option,
609
+ raise_exception=raise_exception,
610
+ default=default,
611
+ check_config_table=check_config_table,
612
+ session=session,
613
+ use_cache=use_cache,
614
+ expiration_time=expiration_time,
615
+ )
616
+ if isinstance(value, str):
617
+ value = __convert_string_to_list(value)
618
+ return value
619
+
620
+
621
+ def __convert_string_to_list(string: str) -> list[str]:
622
+ """
623
+ Convert a comma separated string to a list
624
+ :param string: The input string.
625
+
626
+ :returns: A list extracted from the string.
627
+ """
628
+ if not string or not string.strip():
629
+ return []
630
+ return [item.strip(' ') for item in string.split(',')]
631
+
632
+
633
+ def __config_get_table(
634
+ section: str,
635
+ option: str,
636
+ *,
637
+ raise_exception: bool = True,
638
+ default: _T = None,
639
+ clean_cached: bool = True,
640
+ session: "Optional[Session]" = None,
641
+ use_cache: bool = True,
642
+ expiration_time: int = 900,
643
+ convert_type_fnc: Optional['Callable[[str], _T]'],
644
+ ) -> _T:
645
+ """
646
+ Search for a section-option configuration parameter in the configuration table
647
+
648
+ :param section: the named section.
649
+ :param option: the named option.
650
+ :param raise_exception: Boolean to raise or not ConfigNotFound.
651
+ :param default: the default value if not found.
652
+ :param session: The database session in use.
653
+ :param use_cache: Boolean if the cache should be used.
654
+ :param expiration_time: Time after that the cached value gets ignored.
655
+
656
+ :returns: the configuration value from the config table.
657
+
658
+ :raises ConfigNotFound
659
+ :raises DatabaseException
660
+ """
661
+ try:
662
+ from rucio.core.config import get as core_config_get
663
+ return core_config_get(section, option, default=default, session=session, use_cache=use_cache,
664
+ expiration_time=expiration_time, convert_type_fnc=convert_type_fnc)
665
+ except (ConfigNotFound, DatabaseException, ImportError) as err:
666
+ if raise_exception and default is None:
667
+ raise err
668
+ if clean_cached:
669
+ clean_cached_config()
670
+ return default
671
+
672
+
673
+ def config_get_options(section: str) -> list[str]:
674
+ """Return all options from a given section"""
675
+ return get_config().options(section)
676
+
677
+
678
+ def config_get_items(section: str) -> list[tuple[str, str]]:
679
+ """Return all (name, value) pairs from a given section"""
680
+ return get_config().items(section)
681
+
682
+
683
+ def config_remove_option(section: str, option: str) -> bool:
684
+ """
685
+ Remove the specified option from a given section.
686
+
687
+ :param section: Name of section in the Rucio config.
688
+ :param option: Name of option to remove from Rucio configuration.
689
+ :returns: True if the option existed in the configuration, False otherwise.
690
+
691
+ :raises NoSectionError: If the section does not exist.
692
+ """
693
+ return get_config().remove_option(section, option)
694
+
695
+
696
+ def config_set(section: str, option: str, value: str) -> None:
697
+ """
698
+ Set a configuration option in a given section.
699
+
700
+ :param section: Name of section in the Rucio config.
701
+ :param option: Name of option to set in the Rucio configuration.
702
+ :param value: New value for the option.
703
+
704
+ :raises NoSectionError: If the section does not exist.
705
+ """
706
+ return get_config().set(section, option, value)
707
+
708
+
709
+ def get_config_dirs() -> list[str]:
710
+ """
711
+ Returns all available configuration directories in order:
712
+ - $RUCIO_HOME/etc/
713
+ - $VIRTUAL_ENV/etc/
714
+ - $CONDA_PREFIX/etc
715
+ - /opt/rucio/
716
+ """
717
+ configdirs = []
718
+
719
+ env_vars = ['RUCIO_HOME', 'VIRTUAL_ENV', 'CONDA_PREFIX']
720
+ configdirs.extend([os.path.join(os.environ[var], 'etc', '') for var in env_vars if var in os.environ])
721
+
722
+ configdirs.append('/opt/rucio/etc/')
723
+
724
+ return configdirs
725
+
726
+
727
+ def get_lfn2pfn_algorithm_default() -> str:
728
+ """Returns the default algorithm name for LFN2PFN translation for this server."""
729
+ default_lfn2pfn = "hash"
730
+ try:
731
+ default_lfn2pfn = config_get('policy', 'lfn2pfn_algorithm_default')
732
+ except (configparser.NoOptionError, configparser.NoSectionError, ConfigNotFound, RuntimeError):
733
+ pass
734
+ return default_lfn2pfn
735
+
736
+
737
+ def get_rse_credentials(path_to_credentials_file: Optional[Union[str, os.PathLike]] = None) -> dict[str, Any]:
738
+ """ Returns credentials for RSEs. """
739
+
740
+ path = ''
741
+ if path_to_credentials_file: # Use specific file for this connect
742
+ path = path_to_credentials_file
743
+ else: # Use file defined in th RSEMgr
744
+ for confdir in get_config_dirs():
745
+ p = os.path.join(confdir, 'rse-accounts.cfg')
746
+ if os.path.exists(p):
747
+ path = p
748
+ try:
749
+ # Load all user credentials
750
+ with open(path) as cred_file:
751
+ credentials = json.load(cred_file)
752
+ except Exception as error:
753
+ raise exception.ErrorLoadingCredentials(error)
754
+ return credentials
755
+
756
+
757
+ @cache
758
+ def get_config() -> configparser.ConfigParser:
759
+ """Factory function for the configuration class. Returns the ConfigParser instance."""
760
+ return Config().parser
761
+
762
+
763
+ def clean_cached_config() -> None:
764
+ """Deletes the cached config singleton instance."""
765
+ get_config.cache_clear()
766
+
767
+
768
+ class Config:
769
+ """
770
+ The configuration class reading the config file on init, located by using
771
+ get_config_dirs or the use of the RUCIO_CONFIG environment variable.
772
+ """
773
+ def __init__(self):
774
+ self.parser = configparser.ConfigParser()
775
+
776
+ if 'RUCIO_CONFIG' in os.environ:
777
+ self.configfile = os.environ['RUCIO_CONFIG']
778
+ else:
779
+ configs = [os.path.join(confdir, 'rucio.cfg') for confdir in get_config_dirs()]
780
+ self.configfile = next(iter(filter(os.path.exists, configs)), None)
781
+ if self.configfile is None:
782
+ raise ConfigNotFound(
783
+ 'Could not load Rucio configuration file. '
784
+ 'Rucio looked in the following paths for a configuration file, in order:'
785
+ '\n\t' + '\n\t'.join(configs))
786
+
787
+ if not self.parser.read(self.configfile) == [self.configfile]:
788
+ raise ConfigLoadingError(self.configfile)