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