rucio-clients 35.5.0__tar.gz → 35.6.1__tar.gz

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 (188) hide show
  1. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/PKG-INFO +11 -2
  2. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/bin/rucio +20 -19
  3. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/lib/rucio/common/exception.py +47 -12
  4. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/lib/rucio/common/schema/__init__.py +4 -4
  5. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/lib/rucio/vcsversion.py +3 -3
  6. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/tests/test_replica_sorting.py +22 -1
  7. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/tests/test_transfer_plugins.py +88 -75
  8. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/AUTHORS.rst +0 -0
  9. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/ChangeLog +0 -0
  10. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/LICENSE +0 -0
  11. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/MANIFEST.in +0 -0
  12. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/README.md +0 -0
  13. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/bin/rucio-admin +0 -0
  14. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/etc/rse-accounts.cfg.template +0 -0
  15. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/etc/rucio.cfg.atlas.client.template +0 -0
  16. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/etc/rucio.cfg.template +0 -0
  17. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/lib/rucio/__init__.py +0 -0
  18. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/lib/rucio/alembicrevision.py +0 -0
  19. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/lib/rucio/client/__init__.py +0 -0
  20. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/lib/rucio/client/accountclient.py +0 -0
  21. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/lib/rucio/client/accountlimitclient.py +0 -0
  22. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/lib/rucio/client/baseclient.py +0 -0
  23. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/lib/rucio/client/client.py +0 -0
  24. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/lib/rucio/client/configclient.py +0 -0
  25. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/lib/rucio/client/credentialclient.py +0 -0
  26. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/lib/rucio/client/didclient.py +0 -0
  27. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/lib/rucio/client/diracclient.py +0 -0
  28. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/lib/rucio/client/downloadclient.py +0 -0
  29. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/lib/rucio/client/exportclient.py +0 -0
  30. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/lib/rucio/client/fileclient.py +0 -0
  31. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/lib/rucio/client/importclient.py +0 -0
  32. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/lib/rucio/client/lifetimeclient.py +0 -0
  33. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/lib/rucio/client/lockclient.py +0 -0
  34. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/lib/rucio/client/metaconventionsclient.py +0 -0
  35. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/lib/rucio/client/pingclient.py +0 -0
  36. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/lib/rucio/client/replicaclient.py +0 -0
  37. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/lib/rucio/client/requestclient.py +0 -0
  38. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/lib/rucio/client/rseclient.py +0 -0
  39. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/lib/rucio/client/ruleclient.py +0 -0
  40. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/lib/rucio/client/scopeclient.py +0 -0
  41. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/lib/rucio/client/subscriptionclient.py +0 -0
  42. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/lib/rucio/client/touchclient.py +0 -0
  43. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/lib/rucio/client/uploadclient.py +0 -0
  44. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/lib/rucio/common/__init__.py +0 -0
  45. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/lib/rucio/common/cache.py +0 -0
  46. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/lib/rucio/common/config.py +0 -0
  47. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/lib/rucio/common/constants.py +0 -0
  48. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/lib/rucio/common/constraints.py +0 -0
  49. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/lib/rucio/common/didtype.py +0 -0
  50. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/lib/rucio/common/extra.py +0 -0
  51. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/lib/rucio/common/logging.py +0 -0
  52. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/lib/rucio/common/pcache.py +0 -0
  53. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/lib/rucio/common/plugins.py +0 -0
  54. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/lib/rucio/common/policy.py +0 -0
  55. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/lib/rucio/common/schema/atlas.py +0 -0
  56. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/lib/rucio/common/schema/belleii.py +0 -0
  57. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/lib/rucio/common/schema/domatpc.py +0 -0
  58. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/lib/rucio/common/schema/escape.py +0 -0
  59. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/lib/rucio/common/schema/generic.py +0 -0
  60. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/lib/rucio/common/schema/generic_multi_vo.py +0 -0
  61. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/lib/rucio/common/schema/icecube.py +0 -0
  62. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/lib/rucio/common/stomp_utils.py +0 -0
  63. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/lib/rucio/common/stopwatch.py +0 -0
  64. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/lib/rucio/common/test_rucio_server.py +0 -0
  65. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/lib/rucio/common/types.py +0 -0
  66. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/lib/rucio/common/utils.py +0 -0
  67. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/lib/rucio/rse/__init__.py +0 -0
  68. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/lib/rucio/rse/protocols/__init__.py +0 -0
  69. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/lib/rucio/rse/protocols/bittorrent.py +0 -0
  70. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/lib/rucio/rse/protocols/cache.py +0 -0
  71. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/lib/rucio/rse/protocols/dummy.py +0 -0
  72. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/lib/rucio/rse/protocols/gfal.py +0 -0
  73. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/lib/rucio/rse/protocols/globus.py +0 -0
  74. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/lib/rucio/rse/protocols/gsiftp.py +0 -0
  75. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/lib/rucio/rse/protocols/http_cache.py +0 -0
  76. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/lib/rucio/rse/protocols/mock.py +0 -0
  77. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/lib/rucio/rse/protocols/ngarc.py +0 -0
  78. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/lib/rucio/rse/protocols/posix.py +0 -0
  79. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/lib/rucio/rse/protocols/protocol.py +0 -0
  80. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/lib/rucio/rse/protocols/rclone.py +0 -0
  81. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/lib/rucio/rse/protocols/rfio.py +0 -0
  82. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/lib/rucio/rse/protocols/srm.py +0 -0
  83. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/lib/rucio/rse/protocols/ssh.py +0 -0
  84. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/lib/rucio/rse/protocols/storm.py +0 -0
  85. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/lib/rucio/rse/protocols/webdav.py +0 -0
  86. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/lib/rucio/rse/protocols/xrootd.py +0 -0
  87. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/lib/rucio/rse/rsemanager.py +0 -0
  88. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/lib/rucio/version.py +0 -0
  89. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/lib/rucio_clients.egg-info/SOURCES.txt +0 -0
  90. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/pylintrc +0 -0
  91. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/pyproject.toml +0 -0
  92. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/requirements/requirements.client.txt +0 -0
  93. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/setup.cfg +0 -0
  94. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/setup.py +0 -0
  95. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/setuputil.py +0 -0
  96. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/tests/test_abacus_account.py +0 -0
  97. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/tests/test_abacus_collection_replica.py +0 -0
  98. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/tests/test_abacus_rse.py +0 -0
  99. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/tests/test_account.py +0 -0
  100. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/tests/test_account_limits.py +0 -0
  101. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/tests/test_archive.py +0 -0
  102. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/tests/test_auditor.py +0 -0
  103. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/tests/test_auditor_hdfs.py +0 -0
  104. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/tests/test_auditor_srmdumps.py +0 -0
  105. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/tests/test_authentication.py +0 -0
  106. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/tests/test_automatix.py +0 -0
  107. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/tests/test_bad_replica.py +0 -0
  108. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/tests/test_bb8.py +0 -0
  109. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/tests/test_belleii.py +0 -0
  110. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/tests/test_bin_rucio.py +0 -0
  111. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/tests/test_boolean.py +0 -0
  112. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/tests/test_clients.py +0 -0
  113. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/tests/test_common_types.py +0 -0
  114. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/tests/test_config.py +0 -0
  115. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/tests/test_conveyor.py +0 -0
  116. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/tests/test_conveyor_submitter.py +0 -0
  117. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/tests/test_counter.py +0 -0
  118. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/tests/test_credential.py +0 -0
  119. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/tests/test_curl.py +0 -0
  120. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/tests/test_daemons.py +0 -0
  121. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/tests/test_dataset_replicas.py +0 -0
  122. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/tests/test_db.py +0 -0
  123. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/tests/test_did.py +0 -0
  124. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/tests/test_did_meta_plugins.py +0 -0
  125. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/tests/test_didtype.py +0 -0
  126. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/tests/test_download.py +0 -0
  127. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/tests/test_dumper.py +0 -0
  128. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/tests/test_dumper_consistency.py +0 -0
  129. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/tests/test_dumper_data_model.py +0 -0
  130. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/tests/test_dumper_path_parsing.py +0 -0
  131. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/tests/test_filter_engine.py +0 -0
  132. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/tests/test_gateway_external_representation.py +0 -0
  133. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/tests/test_heartbeat.py +0 -0
  134. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/tests/test_hermes.py +0 -0
  135. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/tests/test_identity.py +0 -0
  136. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/tests/test_impl_upload_download.py +0 -0
  137. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/tests/test_import_export.py +0 -0
  138. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/tests/test_judge_cleaner.py +0 -0
  139. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/tests/test_judge_evaluator.py +0 -0
  140. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/tests/test_judge_injector.py +0 -0
  141. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/tests/test_judge_repairer.py +0 -0
  142. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/tests/test_lifetime.py +0 -0
  143. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/tests/test_message.py +0 -0
  144. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/tests/test_meta_conventions.py +0 -0
  145. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/tests/test_meta_did.py +0 -0
  146. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/tests/test_module_import.py +0 -0
  147. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/tests/test_monitor.py +0 -0
  148. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/tests/test_multi_vo.py +0 -0
  149. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/tests/test_naming_convention.py +0 -0
  150. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/tests/test_oauthmanager.py +0 -0
  151. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/tests/test_oidc.py +0 -0
  152. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/tests/test_permission.py +0 -0
  153. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/tests/test_pfns.py +0 -0
  154. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/tests/test_ping.py +0 -0
  155. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/tests/test_preparer.py +0 -0
  156. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/tests/test_qos.py +0 -0
  157. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/tests/test_quarantined_replica.py +0 -0
  158. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/tests/test_reaper.py +0 -0
  159. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/tests/test_redirect.py +0 -0
  160. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/tests/test_replica.py +0 -0
  161. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/tests/test_replica_recoverer.py +0 -0
  162. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/tests/test_request.py +0 -0
  163. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/tests/test_root_proxy.py +0 -0
  164. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/tests/test_rse.py +0 -0
  165. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/tests/test_rse_expression_parser.py +0 -0
  166. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/tests/test_rse_lfn2path.py +0 -0
  167. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/tests/test_rse_protocol_gfal2.py +0 -0
  168. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/tests/test_rse_protocol_gfal2_impl.py +0 -0
  169. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/tests/test_rse_protocol_posix.py +0 -0
  170. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/tests/test_rse_protocol_rclone.py +0 -0
  171. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/tests/test_rse_protocol_rsync.py +0 -0
  172. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/tests/test_rse_protocol_srm.py +0 -0
  173. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/tests/test_rse_protocol_ssh.py +0 -0
  174. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/tests/test_rse_protocol_webdav.py +0 -0
  175. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/tests/test_rse_protocol_xrootd.py +0 -0
  176. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/tests/test_rse_selector.py +0 -0
  177. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/tests/test_rucio_server.py +0 -0
  178. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/tests/test_rule.py +0 -0
  179. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/tests/test_scope.py +0 -0
  180. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/tests/test_subscription.py +0 -0
  181. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/tests/test_throttler.py +0 -0
  182. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/tests/test_tpc.py +0 -0
  183. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/tests/test_trace.py +0 -0
  184. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/tests/test_transfer.py +0 -0
  185. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/tests/test_undertaker.py +0 -0
  186. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/tests/test_upload.py +0 -0
  187. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/tests/test_utils.py +0 -0
  188. {rucio_clients-35.5.0 → rucio_clients-35.6.1}/tools/merge_rucio_configs.py +0 -0
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.2
2
2
  Name: rucio-clients
3
- Version: 35.5.0
3
+ Version: 35.6.1
4
4
  Summary: Rucio Client Lite Package
5
5
  Home-page: https://rucio.cern.ch/
6
6
  Author: Rucio
@@ -38,3 +38,12 @@ Provides-Extra: sftp
38
38
  Requires-Dist: paramiko>=3.4.0; extra == "sftp"
39
39
  Provides-Extra: dumper
40
40
  Requires-Dist: python-magic>=0.4.27; extra == "dumper"
41
+ Dynamic: author
42
+ Dynamic: author-email
43
+ Dynamic: classifier
44
+ Dynamic: home-page
45
+ Dynamic: license
46
+ Dynamic: provides-extra
47
+ Dynamic: requires-dist
48
+ Dynamic: requires-python
49
+ Dynamic: summary
@@ -412,7 +412,7 @@ def list_file_replicas(args):
412
412
  pfn_dir, dst_dir = args.link.split(':')
413
413
  if args.rses:
414
414
  for replica, rse in itertools.product(replicas, rses):
415
- if rse in list(replica['rses'].keys()) and replica['rses'][rse]:
415
+ if replica['rses'].get(rse):
416
416
  for pfn in replica['rses'][rse]:
417
417
  os.symlink(dst_dir + pfn.rsplit(pfn_dir)[-1], replica['name'])
418
418
  else:
@@ -423,16 +423,17 @@ def list_file_replicas(args):
423
423
  os.symlink(dst_dir + pfn.rsplit(pfn_dir)[-1], replica['name'])
424
424
  elif args.pfns:
425
425
  if args.rses:
426
- for replica, rse in itertools.product(replicas, rses):
427
- if rse in list(replica['rses'].keys()) and replica['rses'][rse]:
428
- for pfn in replica['rses'][rse]:
426
+ for replica in replicas:
427
+ for pfn in replica['pfns']:
428
+ rse = replica['pfns'][pfn]['rse']
429
+ if replica['rses'].get(rse):
429
430
  print(pfn)
430
431
  else:
431
432
  for replica in replicas:
432
- for rse in replica['rses']:
433
+ for pfn in replica['pfns']:
434
+ rse = replica['pfns'][pfn]['rse']
433
435
  if replica['rses'][rse]:
434
- for pfn in replica['rses'][rse]:
435
- print(pfn)
436
+ print(pfn)
436
437
  else:
437
438
  if args.all_states:
438
439
  header = ['SCOPE', 'NAME', 'FILESIZE', 'ADLER32', '(STATE) RSE: REPLICA']
@@ -440,18 +441,18 @@ def list_file_replicas(args):
440
441
  header = ['SCOPE', 'NAME', 'FILESIZE', 'ADLER32', 'RSE: REPLICA']
441
442
  for replica in replicas:
442
443
  if 'bytes' in replica:
443
- for rse in replica['rses']:
444
- for pfn in replica['rses'][rse]:
445
- if args.all_states:
446
- rse_string = '({2}) {0}: {1}'.format(rse, pfn, ReplicaState[replica['states'][rse]].value)
447
- else:
448
- rse_string = '{0}: {1}'.format(rse, pfn)
449
- if args.rses:
450
- for selected_rse in rses:
451
- if rse == selected_rse:
452
- table.append([replica['scope'], replica['name'], sizefmt(replica['bytes'], args.human), replica['adler32'], rse_string])
453
- else:
454
- table.append([replica['scope'], replica['name'], sizefmt(replica['bytes'], args.human), replica['adler32'], rse_string])
444
+ for pfn in replica['pfns']:
445
+ rse = replica['pfns'][pfn]['rse']
446
+ if args.all_states:
447
+ rse_string = '({2}) {0}: {1}'.format(rse, pfn, ReplicaState[replica['states'][rse]].value)
448
+ else:
449
+ rse_string = '{0}: {1}'.format(rse, pfn)
450
+ if args.rses:
451
+ for selected_rse in rses:
452
+ if rse == selected_rse:
453
+ table.append([replica['scope'], replica['name'], sizefmt(replica['bytes'], args.human), replica['adler32'], rse_string])
454
+ else:
455
+ table.append([replica['scope'], replica['name'], sizefmt(replica['bytes'], args.human), replica['adler32'], rse_string])
455
456
  print(tabulate(table, tablefmt=tablefmt, headers=header, disable_numparse=True))
456
457
  return SUCCESS
457
458
 
@@ -955,13 +955,22 @@ class NoDistance(RucioException):
955
955
  self.error_code = 92
956
956
 
957
957
 
958
- class PolicyPackageNotFound(RucioException):
958
+ class PolicyPackageBaseException(RucioException):
959
+ """
960
+ Base exception for policy package errors.
961
+ """
962
+ def __init__(self, package: str, *args):
963
+ super(PolicyPackageBaseException, self).__init__(*args)
964
+ self.package = package
965
+
966
+
967
+ class PolicyPackageNotFound(PolicyPackageBaseException):
959
968
  """
960
969
  The policy package specified in the config file was not found
961
970
  """
962
- def __init__(self, *args):
963
- super(PolicyPackageNotFound, self).__init__(*args)
964
- self._message = 'The specified policy package was not found'
971
+ def __init__(self, package: str, *args):
972
+ super(PolicyPackageNotFound, self).__init__(package, *args)
973
+ self._message = 'The specified policy package %s was not found' % self.package
965
974
  self.error_code = 93
966
975
 
967
976
 
@@ -1055,13 +1064,19 @@ class MetadataSchemaMismatchError(RucioException):
1055
1064
  self.error_code = 102
1056
1065
 
1057
1066
 
1058
- class PolicyPackageVersionError(RucioException):
1067
+ class PolicyPackageVersionError(PolicyPackageBaseException):
1059
1068
  """
1060
1069
  Policy package is not compatible with this version of Rucio.
1061
1070
  """
1062
- def __init__(self, package, *args):
1063
- super(PolicyPackageVersionError, self).__init__(*args)
1064
- self._message = 'Policy package %s is not compatible with this Rucio version' % package
1071
+ def __init__(self, package: str, rucio_version: str, supported_versions: list[str], *args):
1072
+ super(PolicyPackageVersionError, self).__init__(package, *args)
1073
+ self.rucio_version = rucio_version
1074
+ self.supported_versions = supported_versions
1075
+ self._message = 'Policy package %s is not compatible with this Rucio version.\nRucio version: %s\nVersions supported by the package: %s' % (
1076
+ self.package,
1077
+ self.rucio_version,
1078
+ self.supported_versions
1079
+ )
1065
1080
  self.error_code = 103
1066
1081
 
1067
1082
 
@@ -1096,13 +1111,13 @@ class SortingAlgorithmNotSupported(RucioException):
1096
1111
  self.error_code = 106
1097
1112
 
1098
1113
 
1099
- class ErrorLoadingPolicyPackage(RucioException):
1114
+ class ErrorLoadingPolicyPackage(PolicyPackageBaseException):
1100
1115
  """
1101
1116
  An error occurred while loading the policy package.
1102
1117
  """
1103
- def __init__(self, *args):
1104
- super(ErrorLoadingPolicyPackage, self).__init__(*args)
1105
- self._message = 'An error occurred while loading the specified policy package'
1118
+ def __init__(self, package: str, *args):
1119
+ super(ErrorLoadingPolicyPackage, self).__init__(package, *args)
1120
+ self._message = 'An error occurred while loading the policy package %s' % self.package
1106
1121
  self.error_code = 107
1107
1122
 
1108
1123
 
@@ -1114,3 +1129,23 @@ class TraceValidationSchemaNotFound(RucioException):
1114
1129
  super(TraceValidationSchemaNotFound, self).__init__(*args, **kwargs)
1115
1130
  self._message = 'Trace validation schema not found.'
1116
1131
  self.error_code = 108
1132
+
1133
+
1134
+ class PolicyPackageIsNotVersioned(PolicyPackageBaseException):
1135
+ """
1136
+ Policy package does not contain version information.
1137
+ """
1138
+ def __init__(self, package: str, *args):
1139
+ super(PolicyPackageIsNotVersioned, self).__init__(package, *args)
1140
+ self._message = 'Policy package %s does not include information about which Rucio versions it supports.' % self.package
1141
+ self.error_code = 109
1142
+
1143
+
1144
+ class UnsupportedMetadataPlugin(RucioException):
1145
+ """
1146
+ Raised when attempting to use a metadata plugin that is not enabled on the server.
1147
+ """
1148
+ def __init__(self, *args):
1149
+ super(UnsupportedMetadataPlugin, self).__init__(*args)
1150
+ self._message = "The requested metadata plugin is not enabled on the server."
1151
+ self.error_code = 110
@@ -61,9 +61,9 @@ if not multivo:
61
61
  try:
62
62
  module = importlib.import_module(POLICY)
63
63
  except ModuleNotFoundError:
64
- raise exception.PolicyPackageNotFound('Module ' + POLICY + ' not found')
64
+ raise exception.PolicyPackageNotFound(POLICY)
65
65
  except ImportError:
66
- raise exception.ErrorLoadingPolicyPackage('An error occurred while loading module ' + POLICY)
66
+ raise exception.ErrorLoadingPolicyPackage(POLICY)
67
67
 
68
68
  schema_modules["def"] = module
69
69
  scope_name_regexps.append(module.SCOPE_NAME_REGEXP)
@@ -93,9 +93,9 @@ def load_schema_for_vo(vo: str) -> None:
93
93
  try:
94
94
  module = importlib.import_module(POLICY)
95
95
  except ModuleNotFoundError:
96
- raise exception.PolicyPackageNotFound('Module ' + POLICY + ' not found')
96
+ raise exception.PolicyPackageNotFound(POLICY)
97
97
  except ImportError:
98
- raise exception.ErrorLoadingPolicyPackage('An error occurred while loading module ' + POLICY)
98
+ raise exception.ErrorLoadingPolicyPackage(POLICY)
99
99
 
100
100
  schema_modules[vo] = module
101
101
 
@@ -4,8 +4,8 @@ This file is automatically generated; Do not edit it. :)
4
4
  '''
5
5
  VERSION_INFO = {
6
6
  'final': True,
7
- 'version': '35.5.0',
7
+ 'version': '35.6.1',
8
8
  'branch_nick': 'release-35-LTS',
9
- 'revision_id': 'f5e7f329eb6baed9096242ee497152cd14464b2c',
10
- 'revno': 13174
9
+ 'revision_id': 'da061cd8b9e3955a4196b81dc6c0a4b1202bbe20',
10
+ 'revno': 13193
11
11
  }
@@ -22,6 +22,7 @@ from urllib.parse import urlparse
22
22
  import geoip2.database
23
23
  import pytest
24
24
 
25
+ import rucio.core.config as core_config
25
26
  from rucio.common.config import config_get
26
27
  from rucio.common.constants import RseAttr
27
28
  from rucio.common.utils import parse_replicas_from_string
@@ -448,7 +449,7 @@ def test_not_sorting_lan_replicas(vo, rest_client, auth_token, protocols_setup,
448
449
  @pytest.mark.noparallel(reason='fails when run in parallel')
449
450
  @pytest.mark.parametrize("content_type", [Mime.METALINK, Mime.JSON_STREAM])
450
451
  def test_sort_geoip_address_not_found_error(vo, rest_client, auth_token, protocols_setup, content_type):
451
- """Replicas: test sorting via geoip with ignoring geoip errors."""
452
+ """Replicas: test sorting via geoip with ignoring geoip errors (and without)."""
452
453
 
453
454
  class MockedGeoIPError(Exception):
454
455
  def __init__(self, *args):
@@ -479,6 +480,26 @@ def test_sort_geoip_address_not_found_error(vo, rest_client, auth_token, protoco
479
480
 
480
481
  get_geoip_db_mock.assert_called()
481
482
 
483
+ # now set config to not ignore errors
484
+ core_config.set("core", "geoip_ignore_error", False)
485
+
486
+ # invalidate cache for __get_distance so that __get_geoip_db is called
487
+ replica_sorter.REGION.invalidate()
488
+
489
+ with mock.patch('rucio.core.replica_sorter.__geoip_db', side_effect=fake_get_geoip_db) as get_geoip_db_mock:
490
+ response = rest_client.post(
491
+ '/replicas/list',
492
+ headers=headers(auth(auth_token), vohdr(vo), accept(content_type)),
493
+ json=data
494
+ )
495
+ # this time the call should fail
496
+ assert response.status_code != 200
497
+
498
+ get_geoip_db_mock.assert_called()
499
+
500
+ # reset to ignore errors for other tests
501
+ core_config.set("core", "geoip_ignore_error", True)
502
+
482
503
 
483
504
  @pytest.mark.noparallel(reason='fails when run in parallel, replicas should not be changed')
484
505
  def test_get_sorted_list_replicas_no_metalink(vo, rest_client, auth_token, protocols_setup, mock_scope):
@@ -25,6 +25,7 @@ from rucio.core.topology import Topology
25
25
  from rucio.core.transfer import ProtocolFactory, build_transfer_paths
26
26
  from rucio.db.sqla.session import get_session
27
27
  from rucio.transfertool.fts3 import FTS3Transfertool, build_job_params
28
+ from rucio.transfertool.fts3_plugins import FTS3TapeMetadataPlugin
28
29
 
29
30
  mock_session = get_session()
30
31
 
@@ -108,7 +109,7 @@ def test_scheduling_hints(file_config_mock, did_factory, rse_factory, root_accou
108
109
  assert len(job_params["archive_metadata"].keys()) == 1
109
110
  generated_scheduling_hints = job_params["archive_metadata"]["scheduling_hints"]
110
111
 
111
- expected_scheduling_hints = {"priority": "100"}
112
+ expected_scheduling_hints = {"priority": 100}
112
113
  assert expected_scheduling_hints == generated_scheduling_hints
113
114
 
114
115
 
@@ -150,93 +151,105 @@ def test_activity_missing(file_config_mock, did_factory, rse_factory, root_accou
150
151
  assert "archive_metadata" in job_params
151
152
  generated_scheduling_hints = job_params["archive_metadata"]["scheduling_hints"]
152
153
 
153
- expected_scheduling_hints = {"priority": "20"}
154
+ expected_scheduling_hints = {"priority": 20}
154
155
  assert expected_scheduling_hints == generated_scheduling_hints
155
156
 
156
157
 
157
- @pytest.mark.parametrize("file_config_mock", [
158
- {
159
- "overrides": [
160
- ("transfers", "fts3tape_metadata_plugins", "test")
161
- ]
162
- }
163
- ], indirect=True)
164
- def test_collocation_hints(file_config_mock, did_factory, rse_factory, root_account):
165
- """For a mock collocation algorithm, it can produce the 4 levels of hints required for each did"""
158
+ class TestCollocationHints:
159
+ class TestCollocationPlugin(FTS3TapeMetadataPlugin):
160
+ def __init__(self) -> None:
161
+ self.register(
162
+ 'test',
163
+ func=lambda x: self._test_collocation(x))
164
+ super().__init__('test')
166
165
 
167
- mock_did = did_factory.random_file_did()
168
- transfer_path = _make_transfer_path(mock_did, rse_factory, root_account)
166
+ def _test_collocation(self, hints: dict[str, str]) -> dict[str, dict]:
167
+ return {"collocation_hints": {"0": "", "1": "", "2": "", "3": ""}}
169
168
 
170
- # Mock Transfer Tool
171
- fts3_tool = FTS3Transfertool(TEST_FTS_HOST)
169
+ TestCollocationPlugin()
172
170
 
173
- job_params = build_job_params(
174
- transfer_path=transfer_path,
175
- bring_online=None,
176
- default_lifetime=None,
177
- archive_timeout_override=None,
178
- max_time_in_queue=None,
179
- logger=logging.log,
180
- )
181
-
182
- # Get the job params used for each transfer
183
- job_params = fts3_tool._file_from_transfer(transfer_path[0], job_params)
184
-
185
- expected_collocation_hints = {
186
- "collocation_hints": {
187
- "0": "",
188
- "1": "",
189
- "2": "",
190
- "3": "",
171
+ @pytest.mark.parametrize("file_config_mock", [
172
+ {
173
+ "overrides": [
174
+ ("transfers", "fts3tape_metadata_plugins", "test")
175
+ ]
191
176
  }
192
- }
193
-
194
- assert "archive_metadata" in job_params
195
- generated_collocation_hints = job_params["archive_metadata"]["collocation_hints"]
196
-
197
- assert (
198
- expected_collocation_hints["collocation_hints"] == generated_collocation_hints
199
- )
200
-
201
-
202
- @pytest.mark.parametrize("file_config_mock", [
203
- {
204
- "overrides": [
205
- ("transfers", "fts3tape_metadata_plugins", "activity, test")
206
- ]
207
- }
208
- ], indirect=True)
209
- def test_multiple_plugin_concat(file_config_mock, did_factory, rse_factory, root_account):
210
- """When multiple plugins are used (like priority and collocation), both logics are applied"""
177
+ ], indirect=True)
178
+ def test_collocation_hints(self, file_config_mock, did_factory, rse_factory, root_account):
179
+ """For a mock collocation algorithm, it can produce the 4 levels of hints required for each did"""
180
+
181
+ mock_did = did_factory.random_file_did()
182
+ transfer_path = _make_transfer_path(mock_did, rse_factory, root_account)
183
+
184
+ # Mock Transfer Tool
185
+ fts3_tool = FTS3Transfertool(TEST_FTS_HOST)
186
+
187
+ job_params = build_job_params(
188
+ transfer_path=transfer_path,
189
+ bring_online=None,
190
+ default_lifetime=None,
191
+ archive_timeout_override=None,
192
+ max_time_in_queue=None,
193
+ logger=logging.log,
194
+ )
195
+
196
+ # Get the job params used for each transfer
197
+ job_params = fts3_tool._file_from_transfer(transfer_path[0], job_params)
211
198
 
212
- mock_did = did_factory.random_file_did()
213
- transfer_path = _make_transfer_path(mock_did, rse_factory, root_account)
199
+ expected_collocation_hints = {
200
+ "collocation_hints": {
201
+ "0": "",
202
+ "1": "",
203
+ "2": "",
204
+ "3": "",
205
+ }
206
+ }
214
207
 
215
- # Mock Transfer Tool
216
- fts3_tool = FTS3Transfertool(TEST_FTS_HOST)
208
+ assert "archive_metadata" in job_params
209
+ generated_collocation_hints = job_params["archive_metadata"]["collocation_hints"]
217
210
 
218
- job_params = build_job_params(
219
- transfer_path=transfer_path,
220
- bring_online=None,
221
- default_lifetime=None,
222
- archive_timeout_override=None,
223
- max_time_in_queue=None,
224
- logger=logging.log,
225
- )
211
+ assert (
212
+ expected_collocation_hints["collocation_hints"] == generated_collocation_hints
213
+ )
226
214
 
227
- # Get the job params used for each transfer
228
- job_params = fts3_tool._file_from_transfer(transfer_path[0], job_params)
229
- expected_hints = {
230
- "scheduling_hints": {"priority": "20"},
231
- "collocation_hints": {"0": "", "1": "", "2": "", "3": ""},
232
- }
233
- assert "archive_metadata" in job_params
215
+ @pytest.mark.parametrize("file_config_mock", [
216
+ {
217
+ "overrides": [
218
+ ("transfers", "fts3tape_metadata_plugins", "activity, test")
219
+ ]
220
+ }
221
+ ], indirect=True)
222
+ def test_multiple_plugin_concat(self, file_config_mock, did_factory, rse_factory, root_account):
223
+ """When multiple plugins are used (like priority and collocation), both logics are applied"""
224
+
225
+ mock_did = did_factory.random_file_did()
226
+ transfer_path = _make_transfer_path(mock_did, rse_factory, root_account)
227
+
228
+ # Mock Transfer Tool
229
+ fts3_tool = FTS3Transfertool(TEST_FTS_HOST)
230
+
231
+ job_params = build_job_params(
232
+ transfer_path=transfer_path,
233
+ bring_online=None,
234
+ default_lifetime=None,
235
+ archive_timeout_override=None,
236
+ max_time_in_queue=None,
237
+ logger=logging.log,
238
+ )
239
+
240
+ # Get the job params used for each transfer
241
+ job_params = fts3_tool._file_from_transfer(transfer_path[0], job_params)
242
+ expected_hints = {
243
+ "scheduling_hints": {"priority": 20},
244
+ "collocation_hints": {"0": "", "1": "", "2": "", "3": ""},
245
+ }
246
+ assert "archive_metadata" in job_params
234
247
 
235
- generated_collocation_hints = job_params["archive_metadata"]["collocation_hints"]
236
- assert expected_hints["collocation_hints"] == generated_collocation_hints
248
+ generated_collocation_hints = job_params["archive_metadata"]["collocation_hints"]
249
+ assert expected_hints["collocation_hints"] == generated_collocation_hints
237
250
 
238
- generated_scheduling_hints = job_params["archive_metadata"]["scheduling_hints"]
239
- assert expected_hints["scheduling_hints"] == generated_scheduling_hints
251
+ generated_scheduling_hints = job_params["archive_metadata"]["scheduling_hints"]
252
+ assert expected_hints["scheduling_hints"] == generated_scheduling_hints
240
253
 
241
254
 
242
255
  @pytest.mark.parametrize("file_config_mock", [
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes