rucio-clients 36.2.0__tar.gz → 36.3.0__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 (203) hide show
  1. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/PKG-INFO +1 -1
  2. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/bin/rucio +14 -12
  3. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/bin/rucio-admin +7 -4
  4. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/client/accountclient.py +0 -1
  5. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/client/baseclient.py +26 -19
  6. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/client/commands/account.py +12 -11
  7. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/client/commands/bin_legacy/rucio_admin.py +6 -7
  8. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/client/commands/rse.py +25 -11
  9. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/client/commands/utils.py +3 -2
  10. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/client/downloadclient.py +2 -2
  11. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/common/checksum.py +2 -2
  12. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/common/config.py +3 -2
  13. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/common/exception.py +17 -3
  14. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/common/pcache.py +8 -7
  15. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/common/schema/__init__.py +33 -33
  16. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/common/utils.py +8 -8
  17. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/rse/protocols/webdav.py +14 -10
  18. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/vcsversion.py +3 -3
  19. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/pyproject.toml +15 -0
  20. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_authentication.py +5 -5
  21. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_bb8.py +13 -13
  22. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_bin_rucio.py +15 -15
  23. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_clients.py +52 -12
  24. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_conveyor.py +12 -12
  25. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_conveyor_submitter.py +15 -8
  26. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_curl.py +1 -1
  27. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_filter_engine.py +63 -63
  28. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_judge_evaluator.py +52 -52
  29. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_judge_repairer.py +4 -4
  30. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_oauthmanager.py +1 -1
  31. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_oidc.py +129 -129
  32. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_replica.py +6 -6
  33. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_replica_recoverer.py +4 -4
  34. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_rse_lfn2path.py +1 -1
  35. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_rule.py +7 -7
  36. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_trace.py +2 -2
  37. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_utils.py +1 -1
  38. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/AUTHORS.rst +0 -0
  39. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/ChangeLog +0 -0
  40. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/LICENSE +0 -0
  41. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/MANIFEST.in +0 -0
  42. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/README.md +0 -0
  43. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/etc/rse-accounts.cfg.template +0 -0
  44. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/etc/rucio.cfg.atlas.client.template +0 -0
  45. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/etc/rucio.cfg.template +0 -0
  46. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/__init__.py +0 -0
  47. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/alembicrevision.py +0 -0
  48. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/client/__init__.py +0 -0
  49. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/client/accountlimitclient.py +0 -0
  50. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/client/client.py +0 -0
  51. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/client/commands/__init__.py +0 -0
  52. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/client/commands/bin_legacy/__init__.py +0 -0
  53. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/client/commands/bin_legacy/rucio.py +0 -0
  54. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/client/commands/command.py +0 -0
  55. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/client/commands/command_base.py +0 -0
  56. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/client/commands/config.py +0 -0
  57. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/client/commands/did.py +0 -0
  58. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/client/commands/download.py +0 -0
  59. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/client/commands/lifetime_exception.py +0 -0
  60. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/client/commands/replica.py +0 -0
  61. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/client/commands/rule.py +0 -0
  62. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/client/commands/scope.py +0 -0
  63. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/client/commands/subscription.py +0 -0
  64. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/client/commands/upload.py +0 -0
  65. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/client/configclient.py +0 -0
  66. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/client/credentialclient.py +0 -0
  67. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/client/didclient.py +0 -0
  68. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/client/diracclient.py +0 -0
  69. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/client/exportclient.py +0 -0
  70. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/client/fileclient.py +0 -0
  71. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/client/importclient.py +0 -0
  72. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/client/lifetimeclient.py +0 -0
  73. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/client/lockclient.py +0 -0
  74. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/client/metaconventionsclient.py +0 -0
  75. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/client/pingclient.py +0 -0
  76. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/client/replicaclient.py +0 -0
  77. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/client/requestclient.py +0 -0
  78. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/client/richclient.py +0 -0
  79. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/client/rseclient.py +0 -0
  80. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/client/ruleclient.py +0 -0
  81. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/client/scopeclient.py +0 -0
  82. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/client/subscriptionclient.py +0 -0
  83. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/client/touchclient.py +0 -0
  84. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/client/uploadclient.py +0 -0
  85. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/common/__init__.py +0 -0
  86. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/common/bittorrent.py +0 -0
  87. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/common/cache.py +0 -0
  88. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/common/client.py +0 -0
  89. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/common/constants.py +0 -0
  90. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/common/constraints.py +0 -0
  91. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/common/didtype.py +0 -0
  92. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/common/extra.py +0 -0
  93. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/common/logging.py +0 -0
  94. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/common/plugins.py +0 -0
  95. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/common/policy.py +0 -0
  96. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/common/schema/generic.py +0 -0
  97. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/common/schema/generic_multi_vo.py +0 -0
  98. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/common/stomp_utils.py +0 -0
  99. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/common/stopwatch.py +0 -0
  100. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/common/test_rucio_server.py +0 -0
  101. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/common/types.py +0 -0
  102. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/rse/__init__.py +0 -0
  103. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/rse/protocols/__init__.py +0 -0
  104. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/rse/protocols/bittorrent.py +0 -0
  105. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/rse/protocols/cache.py +0 -0
  106. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/rse/protocols/dummy.py +0 -0
  107. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/rse/protocols/gfal.py +0 -0
  108. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/rse/protocols/globus.py +0 -0
  109. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/rse/protocols/gsiftp.py +0 -0
  110. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/rse/protocols/http_cache.py +0 -0
  111. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/rse/protocols/mock.py +0 -0
  112. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/rse/protocols/ngarc.py +0 -0
  113. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/rse/protocols/posix.py +0 -0
  114. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/rse/protocols/protocol.py +0 -0
  115. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/rse/protocols/rclone.py +0 -0
  116. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/rse/protocols/rfio.py +0 -0
  117. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/rse/protocols/srm.py +0 -0
  118. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/rse/protocols/ssh.py +0 -0
  119. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/rse/protocols/storm.py +0 -0
  120. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/rse/protocols/xrootd.py +0 -0
  121. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/rse/rsemanager.py +0 -0
  122. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/rse/translation.py +0 -0
  123. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/version.py +0 -0
  124. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio_clients.egg-info/SOURCES.txt +0 -0
  125. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/pylintrc +0 -0
  126. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/requirements/requirements.client.txt +0 -0
  127. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/setup.cfg +0 -0
  128. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/setup.py +0 -0
  129. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/setuputil.py +0 -0
  130. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_abacus_account.py +0 -0
  131. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_abacus_collection_replica.py +0 -0
  132. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_abacus_rse.py +0 -0
  133. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_account.py +0 -0
  134. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_account_limits.py +0 -0
  135. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_archive.py +0 -0
  136. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_auditor.py +0 -0
  137. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_auditor_hdfs.py +0 -0
  138. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_auditor_srmdumps.py +0 -0
  139. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_automatix.py +0 -0
  140. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_bad_replica.py +0 -0
  141. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_belleii.py +0 -0
  142. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_boolean.py +0 -0
  143. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_cli_client_structure.py +0 -0
  144. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_config.py +0 -0
  145. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_counter.py +0 -0
  146. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_credential.py +0 -0
  147. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_daemons.py +0 -0
  148. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_dataset_replicas.py +0 -0
  149. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_db.py +0 -0
  150. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_did.py +0 -0
  151. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_did_meta_plugins.py +0 -0
  152. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_download.py +0 -0
  153. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_dumper.py +0 -0
  154. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_gateway_external_representation.py +0 -0
  155. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_heartbeat.py +0 -0
  156. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_hermes.py +0 -0
  157. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_identity.py +0 -0
  158. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_impl_upload_download.py +0 -0
  159. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_import_export.py +0 -0
  160. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_judge_cleaner.py +0 -0
  161. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_judge_injector.py +0 -0
  162. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_lifetime.py +0 -0
  163. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_message.py +0 -0
  164. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_meta_conventions.py +0 -0
  165. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_meta_did.py +0 -0
  166. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_module_import.py +0 -0
  167. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_monitor.py +0 -0
  168. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_multi_vo.py +0 -0
  169. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_naming_convention.py +0 -0
  170. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_permission.py +0 -0
  171. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_pfns.py +0 -0
  172. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_ping.py +0 -0
  173. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_policy_package.py +0 -0
  174. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_preparer.py +0 -0
  175. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_qos.py +0 -0
  176. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_quarantined_replica.py +0 -0
  177. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_reaper.py +0 -0
  178. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_redirect.py +0 -0
  179. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_replica_sorting.py +0 -0
  180. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_request.py +0 -0
  181. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_root_proxy.py +0 -0
  182. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_rse.py +0 -0
  183. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_rse_expression_parser.py +0 -0
  184. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_rse_protocol_gfal2.py +0 -0
  185. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_rse_protocol_gfal2_impl.py +0 -0
  186. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_rse_protocol_posix.py +0 -0
  187. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_rse_protocol_rclone.py +0 -0
  188. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_rse_protocol_rsync.py +0 -0
  189. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_rse_protocol_srm.py +0 -0
  190. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_rse_protocol_ssh.py +0 -0
  191. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_rse_protocol_webdav.py +0 -0
  192. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_rse_protocol_xrootd.py +0 -0
  193. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_rse_selector.py +0 -0
  194. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_rucio_server.py +0 -0
  195. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_scope.py +0 -0
  196. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_subscription.py +0 -0
  197. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_throttler.py +0 -0
  198. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_tpc.py +0 -0
  199. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_transfer.py +0 -0
  200. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_transfer_plugins.py +0 -0
  201. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_undertaker.py +0 -0
  202. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_upload.py +0 -0
  203. {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tools/merge_rucio_configs.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: rucio-clients
3
- Version: 36.2.0
3
+ Version: 36.3.0
4
4
  Summary: Rucio Client Lite Package
5
5
  Home-page: https://rucio.cern.ch/
6
6
  Author: Rucio
@@ -15,10 +15,14 @@
15
15
 
16
16
  import argparse
17
17
  import sys
18
- from typing import Optional
18
+ from typing import TYPE_CHECKING, Optional
19
19
 
20
20
  from rucio.client.commands.bin_legacy.rucio import main as main_legacy
21
21
  from rucio.client.commands.command import main
22
+ from rucio.common.utils import setup_logger
23
+
24
+ if TYPE_CHECKING:
25
+ from logging import Logger
22
26
 
23
27
 
24
28
  def _get_first_command(args: list[str]) -> Optional[str]:
@@ -31,15 +35,15 @@ def _get_first_command(args: list[str]) -> Optional[str]:
31
35
  )
32
36
 
33
37
 
34
- def make_warning():
35
- base_warning = "\nWARNING: This method is being deprecated."
38
+ def make_warning(logger: "Logger") -> None:
39
+ base_warning = "This method is being deprecated."
36
40
  new_command = map_legacy_command()
37
41
  if new_command is not None:
38
- warning = f"{base_warning}\nPlease replace your command with `rucio {' '.join(new_command)}`.\n"
42
+ warning = f"{base_warning} Please replace your command with `rucio {' '.join(new_command)}`"
39
43
  else:
40
- warning = base_warning + "\nPlease view rucio -h for an updated help menu.\n"
44
+ warning = base_warning + " Please view rucio -h for an updated help menu."
41
45
 
42
- return warning
46
+ logger.warning(warning)
43
47
 
44
48
 
45
49
  def map_legacy_command() -> Optional[list[str]]:
@@ -96,7 +100,7 @@ def map_legacy_command() -> Optional[list[str]]:
96
100
 
97
101
  if __name__ == "__main__":
98
102
  commands = ("-h", "--help", "--version", "account", "config", "did", "replica", "rse", "rule", "scope", "subscription", "ping", "whoami", "test-server", "lifetime-exception", "upload", "download")
99
-
103
+ logger = setup_logger(module_name=__name__)
100
104
  first_command = _get_first_command(sys.argv[1:])
101
105
 
102
106
  is_legacy = '--legacy' in sys.argv
@@ -105,19 +109,17 @@ if __name__ == "__main__":
105
109
  main()
106
110
 
107
111
  elif is_legacy:
108
- warning = make_warning()
109
- print(warning)
112
+ make_warning(logger)
110
113
  sys.argv.pop(sys.argv.index('--legacy'))
111
114
  main_legacy()
112
115
 
113
116
  else:
114
- warning = make_warning()
115
- print(warning)
117
+ make_warning(logger)
116
118
  try:
117
119
  main_legacy()
118
120
  # Make a custom warning - show the new help menu when invalid commands are called.
119
121
  except argparse.ArgumentError:
120
- print("Invalid argument(s) - %s " % sys.argv[1:])
122
+ logger.error("Invalid argument(s) - %s " % sys.argv[1:])
121
123
  command = map_legacy_command()
122
124
  if command is not None:
123
125
  sys.argv = ["rucio"] + command + ["-h"]
@@ -15,10 +15,13 @@
15
15
  import sys
16
16
 
17
17
  from rucio.client.commands.bin_legacy.rucio_admin import main as main_legacy
18
+ from rucio.common.utils import setup_logger
18
19
 
19
20
 
20
21
  def make_warning():
21
- base_warning = "\nWARNING: This method is being deprecated."
22
+ logger = setup_logger(module_name=__name__)
23
+
24
+ base_warning = "This method is being deprecated."
22
25
  args = [arg for arg in sys.argv if arg[0] != "-" or arg in ("-h", "--help", "--version")]
23
26
  try:
24
27
  first_command = args[1]
@@ -88,11 +91,11 @@ def make_warning():
88
91
  except KeyError:
89
92
  new_command = "-h"
90
93
 
91
- warning = f"{base_warning}\nPlease replace your command with `rucio {new_command}`.\n"
94
+ warning = f"{base_warning} Please replace your command with `rucio {new_command}`"
92
95
  else:
93
- warning = base_warning + "\nPlease view rucio -h for an updated help menu.\n"
96
+ warning = base_warning + " Please view rucio -h for an updated help menu."
94
97
 
95
- print(warning)
98
+ logger.warning(warning)
96
99
 
97
100
 
98
101
  if __name__ == "__main__":
@@ -200,7 +200,6 @@ class AccountClient(BaseClient):
200
200
  :param account: The account name.
201
201
  :param identity: The identity key name. For example x509 DN, or a username.
202
202
  :param authtype: The type of the authentication (x509, gss, userpass).
203
- :param default: If True, the account should be used by default with the provided identity.
204
203
  """
205
204
 
206
205
  data = dumps({'identity': identity, 'authtype': authtype})
@@ -38,7 +38,7 @@ from requests.status_codes import codes
38
38
  from rucio import version
39
39
  from rucio.common import exception
40
40
  from rucio.common.config import config_get, config_get_bool, config_get_int
41
- from rucio.common.exception import CannotAuthenticate, ClientProtocolNotSupported, ConfigNotFound, MissingClientParameter, MissingModuleException, NoAuthInformation, ServerConnectionException
41
+ from rucio.common.exception import CannotAuthenticate, ClientProtocolNotFound, ClientProtocolNotSupported, ConfigNotFound, MissingClientParameter, MissingModuleException, NoAuthInformation, ServerConnectionException
42
42
  from rucio.common.extra import import_extras
43
43
  from rucio.common.utils import build_url, get_tmp_dir, my_key_generator, parse_response, setup_logger, ssh_sign
44
44
 
@@ -157,11 +157,18 @@ class BaseClient:
157
157
  rucio_scheme = urlparse(self.host).scheme
158
158
  auth_scheme = urlparse(self.auth_host).scheme
159
159
 
160
- if rucio_scheme != 'http' and rucio_scheme != 'https':
161
- raise ClientProtocolNotSupported('\'%s\' not supported' % rucio_scheme)
160
+ rucio_scheme_allowed = ['http', 'https']
161
+ auth_scheme_allowed = ['http', 'https']
162
162
 
163
- if auth_scheme != 'http' and auth_scheme != 'https':
164
- raise ClientProtocolNotSupported('\'%s\' not supported' % auth_scheme)
163
+ if not rucio_scheme:
164
+ raise ClientProtocolNotFound(host=self.host, protocols_allowed=rucio_scheme_allowed)
165
+ elif rucio_scheme not in rucio_scheme_allowed:
166
+ raise ClientProtocolNotSupported(host=self.host, protocol=rucio_scheme, protocols_allowed=rucio_scheme_allowed)
167
+
168
+ if not auth_scheme:
169
+ raise ClientProtocolNotFound(host=self.auth_host, protocols_allowed=auth_scheme_allowed)
170
+ elif auth_scheme not in auth_scheme_allowed:
171
+ raise ClientProtocolNotSupported(host=self.auth_host, protocol=auth_scheme, protocols_allowed=auth_scheme_allowed)
165
172
 
166
173
  if (rucio_scheme == 'https' or auth_scheme == 'https') and ca_cert is None:
167
174
  self.logger.debug('HTTPS is required, but no ca_cert was passed. Trying to get it from X509_CERT_DIR.')
@@ -519,7 +526,7 @@ class BaseClient:
519
526
  self.auth_token = result.headers['x-rucio-auth-token']
520
527
  return True
521
528
 
522
- def __refresh_token_OIDC(self) -> bool:
529
+ def __refresh_token_oidc(self) -> bool:
523
530
  """
524
531
  Checks if there is active refresh token and if so returns
525
532
  either active token with expiration timestamp or requests a new
@@ -573,7 +580,7 @@ class BaseClient:
573
580
  \nRucio Auth Server when attempting token refresh.")
574
581
  return False
575
582
 
576
- def __get_token_OIDC(self) -> bool:
583
+ def __get_token_oidc(self) -> bool:
577
584
  """
578
585
  First authenticates the user via a Identity Provider server
579
586
  (with user's username & password), by specifying oidc_scope,
@@ -602,14 +609,14 @@ class BaseClient:
602
609
  request_auth_url = build_url(self.auth_host, path='auth/oidc')
603
610
  # requesting authorization URL specific to the user & Rucio OIDC Client
604
611
  self.logger.debug("Initial auth URL request headers %s to files" % str(headers))
605
- OIDC_auth_res = self._send_request(request_auth_url, headers=headers, get_token=True)
606
- self.logger.debug("Response headers %s and text %s" % (str(OIDC_auth_res.headers), str(OIDC_auth_res.text)))
612
+ oidc_auth_res = self._send_request(request_auth_url, headers=headers, get_token=True)
613
+ self.logger.debug("Response headers %s and text %s" % (str(oidc_auth_res.headers), str(oidc_auth_res.text)))
607
614
  # with the obtained authorization URL we will contact the Identity Provider to get to the login page
608
- if 'X-Rucio-OIDC-Auth-URL' not in OIDC_auth_res.headers:
615
+ if 'X-Rucio-OIDC-Auth-URL' not in oidc_auth_res.headers:
609
616
  print("Rucio Client did not succeed to get AuthN/Z URL from the Rucio Auth Server. \
610
617
  \nThis could be due to wrongly requested/configured scope, audience or issuer.")
611
618
  return False
612
- auth_url = OIDC_auth_res.headers['X-Rucio-OIDC-Auth-URL']
619
+ auth_url = oidc_auth_res.headers['X-Rucio-OIDC-Auth-URL']
613
620
  if not self.creds['oidc_auto']:
614
621
  print("\nPlease use your internet browser, go to:")
615
622
  print("\n " + auth_url + " \n")
@@ -694,7 +701,7 @@ class BaseClient:
694
701
  with fdopen(file_d, "w") as f_exp_epoch:
695
702
  f_exp_epoch.write(str(self.token_exp_epoch))
696
703
  move(file_n, self.token_exp_epoch_file)
697
- self.__refresh_token_OIDC()
704
+ self.__refresh_token_oidc()
698
705
  return True
699
706
 
700
707
  def __get_token_x509(self) -> bool:
@@ -834,11 +841,11 @@ class BaseClient:
834
841
  url = build_url(self.auth_host, path='auth/saml')
835
842
 
836
843
  result = None
837
- SAML_auth_result = self._send_request(url, get_token=True)
838
- if SAML_auth_result.headers['X-Rucio-Auth-Token']:
839
- return SAML_auth_result.headers['X-Rucio-Auth-Token']
840
- SAML_auth_url = SAML_auth_result.headers['X-Rucio-SAML-Auth-URL']
841
- result = self._send_request(SAML_auth_url, type_='POST', data=userpass, verify=False)
844
+ saml_auth_result = self._send_request(url, get_token=True)
845
+ if saml_auth_result.headers['X-Rucio-Auth-Token']:
846
+ return saml_auth_result.headers['X-Rucio-Auth-Token']
847
+ saml_auth_url = saml_auth_result.headers['X-Rucio-SAML-Auth-URL']
848
+ result = self._send_request(saml_auth_url, type_='POST', data=userpass, verify=False)
842
849
  result = self._send_request(url, get_token=True)
843
850
 
844
851
  if not result:
@@ -870,7 +877,7 @@ class BaseClient:
870
877
  raise CannotAuthenticate('x509 authentication failed for account=%s with identity=%s' % (self.account,
871
878
  self.creds))
872
879
  elif self.auth_type == 'oidc':
873
- if not self.__get_token_OIDC():
880
+ if not self.__get_token_oidc():
874
881
  raise CannotAuthenticate('OIDC authentication failed for account=%s' % self.account)
875
882
 
876
883
  elif self.auth_type == 'gss':
@@ -914,7 +921,7 @@ class BaseClient:
914
921
  except Exception:
915
922
  raise
916
923
  if self.auth_oidc_refresh_active and self.auth_type == 'oidc':
917
- self.__refresh_token_OIDC()
924
+ self.__refresh_token_oidc()
918
925
  self.logger.debug('got token from file')
919
926
  return True
920
927
 
@@ -11,6 +11,7 @@
11
11
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
+
14
15
  from argparse import SUPPRESS
15
16
  from typing import TYPE_CHECKING
16
17
 
@@ -60,20 +61,20 @@ class Account(CommandBase):
60
61
  parser.add_argument("--filters", dest="filters", action="store", help="Filter arguments in form `key=value,another_key=next_value`")
61
62
 
62
63
  def add_namespace(self, parser: "ArgumentParser") -> None:
63
- parser.add_argument("--type", dest="accounttype", help="Account Type (USER, GROUP, SERVICE)", required=True)
64
+ parser.add_argument("--type", dest="account_type", help="Account Type", choices={"USER", "GROUP", "SERVICE"}, required=True)
64
65
  parser.add_argument("-a", "--account", dest="account", help="Account name", required=True)
65
- parser.add_argument("--email", dest="accountemail", help="Add an email address associated with the account")
66
+ parser.add_argument("--email", dest="email", help="Add an email address associated with the account")
66
67
 
67
68
  def show_namespace(self, parser: "ArgumentParser") -> None:
68
69
  parser.add_argument("-a", "--account", dest="account", help="Account name", required=True)
69
70
 
70
71
  def update_namespace(self, parser: "ArgumentParser") -> None:
71
- parser.add_argument("-a", "--account", help="Account name", required=True)
72
- parser.add_argument("--email", help="Account email")
73
- parser.add_argument("--ban", type=bool, choices=(True, False), help='Ban the account, to disable it. Use --ban False to unban.', default=None)
72
+ parser.add_argument("-a", "--account", dest="account", help="Account name", required=True)
73
+ parser.add_argument("--email", dest="email", help="Account email")
74
+ parser.add_argument("--ban", dest="ban", type=bool, choices=(True, False), help='Ban the account, to disable it. Use --ban False to unban.', default=None)
74
75
 
75
76
  def remove_namespace(self, parser: "ArgumentParser") -> None:
76
- parser.add_argument("-a", "--account", dest="acnt", action="store", help="Account name", required=True)
77
+ parser.add_argument("-a", "--account", dest="account", action="store", help="Account name", required=True)
77
78
 
78
79
  def _operations(self) -> dict[str, "OperationDict"]:
79
80
  return {
@@ -120,7 +121,7 @@ class Attribute(Account):
120
121
  return {}
121
122
 
122
123
  def namespace(self, subparser):
123
- subparser.add_argument("-a", "--account", help="Account name")
124
+ subparser.add_argument("-a", "--account", dest="account", help="Account name")
124
125
  subparser.add_argument("--key", dest="key", action="store", help="Attribute key")
125
126
  subparser.add_argument("--value", dest="value", action="store", help="Attribute value")
126
127
 
@@ -153,7 +154,7 @@ class Limit(Account):
153
154
  parser.add_argument("-a", "--account", dest="account", help="Account name", required=True)
154
155
  parser.add_argument("--rses", "--rse-exp", dest='rse', action="store", help="RSE expression")
155
156
  parser.add_argument("--bytes", action="store", help='Value can be specified in bytes ("10000"), with a storage unit ("10GB"), or "infinity"')
156
- parser.add_argument("--locality", nargs="?", default="local", choices=["local", "global"], help="Global or local limit scope")
157
+ parser.add_argument("--locality", nargs="?", default="local", choices={"local", "global"}, help="Global or local limit scope")
157
158
  parser.add_argument("--human", default=True, help=SUPPRESS)
158
159
 
159
160
  def _operations(self) -> dict[str, "OperationDict"]:
@@ -186,10 +187,10 @@ class Identity(Account):
186
187
 
187
188
  def namespace(self, parser: "ArgumentParser") -> None:
188
189
  parser.add_argument("--account", dest="account", action="store", help="Account name", required=True)
189
- parser.add_argument("--type", dest="authtype", action="store", choices=["X509", "GSS", "USERPASS", "SSH", "SAML", "OIDC"], help="Authentication type")
190
- parser.add_argument("--id", dest="identity", action="store", help="Identity as a DNs for X509 IDs.")
190
+ parser.add_argument("--type", dest="authtype", action="store", choices={"X509", "GSS", "USERPASS", "SSH", "SAML", "OIDC"}, help="Authentication type")
191
+ parser.add_argument("--id", dest="identity", action="store", help="Identity as a DNs for X509 IDs")
191
192
  parser.add_argument("--email", dest="email", action="store", help="Email address associated with the identity")
192
- parser.add_argument("--password", dest="password", action="store", help="Password if authtype is USERPASS")
193
+ parser.add_argument("--password", dest="password", action="store", help="Password if type is USERPASS")
193
194
  parser.add_argument("--human", default=True, help=SUPPRESS)
194
195
 
195
196
  def _operations(self) -> dict[str, "OperationDict"]:
@@ -71,7 +71,6 @@ def get_scope(did, client):
71
71
  scopes = client.list_scopes()
72
72
  scope, name = extract_scope(did, scopes)
73
73
  return scope, name
74
- return None, did
75
74
 
76
75
 
77
76
  @exception_handler
@@ -82,7 +81,7 @@ def add_account(args, client, logger, console, spinner):
82
81
  Adds a new account. Specify metadata fields as arguments.
83
82
 
84
83
  """
85
- client.add_account(account=args.account, type_=args.accounttype, email=args.accountemail)
84
+ client.add_account(account=args.account, type_=args.account_type, email=args.email)
86
85
  print('Added new account: %s' % args.account)
87
86
  return SUCCESS
88
87
 
@@ -95,8 +94,8 @@ def delete_account(args, client, logger, console, spinner):
95
94
  Delete account.
96
95
 
97
96
  """
98
- client.delete_account(args.acnt)
99
- print('Deleted account: %s' % args.acnt)
97
+ client.delete_account(args.account)
98
+ print('Deleted account: %s' % args.account)
100
99
  return SUCCESS
101
100
 
102
101
 
@@ -1524,8 +1523,8 @@ def get_parser():
1524
1523
  '\n')
1525
1524
  add_account_parser.set_defaults(which='add_account')
1526
1525
  add_account_parser.add_argument('account', action='store', help='Account name')
1527
- add_account_parser.add_argument('--type', dest='accounttype', default='USER', help='Account Type (USER, GROUP, SERVICE)')
1528
- add_account_parser.add_argument('--email', dest='accountemail', action='store',
1526
+ add_account_parser.add_argument('--type', dest='account_type', default='USER', help='Account Type (USER, GROUP, SERVICE)')
1527
+ add_account_parser.add_argument('--email', dest='email', action='store',
1529
1528
  help='Email address associated with the account')
1530
1529
 
1531
1530
  # The disable_account command
@@ -1540,7 +1539,7 @@ def get_parser():
1540
1539
  ' Deleted account: jdoe-sister\n'
1541
1540
  '\n')
1542
1541
  delete_account_parser.set_defaults(which='delete_account')
1543
- delete_account_parser.add_argument('acnt', action='store', help='Account name')
1542
+ delete_account_parser.add_argument('account', action='store', help='Account name')
1544
1543
 
1545
1544
  # The info_account command
1546
1545
  info_account_parser = account_subparser.add_parser('info',
@@ -62,7 +62,7 @@ class RSE(CommandBase):
62
62
  def usage_example(self) -> list[str]:
63
63
  return [
64
64
  "$ rucio rse list # Show all current RSEs, can also access with",
65
- "$ rucio rse list --rses 'deterministic=True' # Show all RSEs that match the RSE Expression 'deterministic=True'",
65
+ "$ rucio rse list --rses 'deterministic=True' # Show all RSEs that match the RSE Expression 'deterministic=True'",
66
66
  "$ rucio rse remove --rse RemoveThisRSE # Disable an RSE by name",
67
67
  "$ rucio rse add --rse CreateANewRSE # add a new RSE named CreateANewRSE",
68
68
  "$ rucio rse update --rse rse123456 --setting deterministic --value False # Make an RSE Non-Deterministic",
@@ -125,8 +125,8 @@ class Attribute(RSE):
125
125
  def usage_example(self) -> list[str]:
126
126
  return [
127
127
  "$ rucio rse attribute list --rse ThisRSE # Show all the attributes for a given RSE",
128
- "$ rucio rse attribute list --rse ThisRSE --key name # Show all the attribute 'name' for a given RSE",
129
- "$ rucio rse attribute add --rse ThisRSE --key given-attribute --value updated # Set the attribute 'given-attribute' to 'updated' for an RSE",
128
+ "$ rucio rse attribute list --rse ThisRSE --key name # Show all the attribute 'name' for a given RSE",
129
+ "$ rucio rse attribute add --rse ThisRSE --key given-attribute --value updated # Set the attribute 'given-attribute' to 'updated' for an RSE",
130
130
  ]
131
131
 
132
132
  def add(self):
@@ -148,10 +148,15 @@ class Distance(RSE):
148
148
 
149
149
  def _operations(self) -> dict[str, "OperationDict"]:
150
150
  return {
151
- "list": {"call": self.list_, "docs": "Show distances between RSEs"},
152
- "add": {"call": self.add, "docs": "Add or update a distance between RSEs"},
153
- "remove": {"call": self.remove, "docs": "Delete the distance between a pair of RSEs. The mandatory parameters are source and destination"},
154
- "set": {"call": self.set_, "docs": "Update the distance between a pair of RSE that already have a distance between them"},
151
+ "list": {"call": self.list_, "docs": "Show distances between RSEs",
152
+ "namespace": self.list_namespace},
153
+ "add": {"call": self.add, "docs": "Add a distance between RSEs", "namespace": self.add_namespace},
154
+ "remove": {"call": self.remove,
155
+ "docs": "Delete the distance between a pair of RSEs",
156
+ "namespace": self.remove_namespace},
157
+ "set": {"call": self.set_,
158
+ "docs": "Update the distance between a pair of RSE that already have a distance between them",
159
+ "namespace": self.set_namespace},
155
160
  }
156
161
 
157
162
  def usage_example(self) -> list[str]:
@@ -162,11 +167,20 @@ class Distance(RSE):
162
167
  "$ rucio rse distance set --source rse1 --destination rse2 --distance 20 # Update an existing distance",
163
168
  ]
164
169
 
165
- def namespace(self, parser: "ArgumentParser") -> None:
166
- parser.add_argument("--source", dest="source", action="store", help="Source RSE name")
167
- parser.add_argument("--destination", dest="destination", action="store", help="Destination RSE name")
170
+ def list_namespace(self, parser: "ArgumentParser") -> None:
171
+ parser.add_argument("--source", dest="source", help="Source RSE name")
172
+ parser.add_argument("--destination", dest="destination", help="Destination RSE name")
173
+
174
+ def remove_namespace(self, parser: "ArgumentParser") -> None:
175
+ self.list_namespace(parser)
176
+
177
+ def add_namespace(self, parser: "ArgumentParser") -> None:
178
+ self.list_namespace(parser)
168
179
  parser.add_argument("--distance", dest="distance", type=int, help="Distance between RSEs")
169
180
 
181
+ def set_namespace(self, parser: "ArgumentParser") -> None:
182
+ self.add_namespace(parser)
183
+
170
184
  def list_(self):
171
185
  get_distance_rses(self.args, self.client, self.logger, self.console, self.spinner)
172
186
 
@@ -258,7 +272,7 @@ class QOS(RSE):
258
272
  return [
259
273
  "$ rucio rse qospolicy list --rse JDOE_DATADISK # List QoS Policy for a given RSE",
260
274
  "$ rucio rse qospolicy add --rse JDOE_DATADISK --policy SLOW_BUT_CHEAP # Add a SLOW_BUT_CHEAP policy to the JDOE_DATADISK RSE",
261
- "$ rucio rse qospolicy remove --rse JDOE_DATADISK --policy SLOW_BUT_CHEAP # Remove the same policy",
275
+ "$ rucio rse qospolicy remove --rse JDOE_DATADISK --policy SLOW_BUT_CHEAP # Remove the same policy",
262
276
  ]
263
277
 
264
278
  def add(self):
@@ -51,6 +51,9 @@ if TYPE_CHECKING:
51
51
  docs: NotRequired[str]
52
52
  namespace: NotRequired[Callable]
53
53
 
54
+ SUCCESS = 0
55
+ FAILURE = 1
56
+
54
57
 
55
58
  def exception_handler(function):
56
59
  verbosity = ("-v" in sys.argv) or ("--verbose" in sys.argv)
@@ -58,8 +61,6 @@ def exception_handler(function):
58
61
 
59
62
  @wraps(function)
60
63
  def new_funct(*args, **kwargs):
61
- SUCCESS = 0
62
- FAILURE = 1
63
64
  try:
64
65
  return function(*args, **kwargs)
65
66
  except NotImplementedError as error:
@@ -1675,8 +1675,8 @@ class DownloadClient:
1675
1675
  num_successful = 0
1676
1676
  num_failed = 0
1677
1677
  for item in output_items:
1678
- clientState = item.get('clientState', FileDownloadState.FAILED)
1679
- if clientState in success_states:
1678
+ client_state = item.get('clientState', FileDownloadState.FAILED)
1679
+ if client_state in success_states:
1680
1680
  num_successful += 1
1681
1681
  else:
1682
1682
  num_failed += 1
@@ -137,8 +137,8 @@ def crc32(file: "FileDescriptorOrPath") -> str:
137
137
  :returns: string of 32 hexadecimal digits
138
138
  """
139
139
  prev = 0
140
- for eachLine in open(file, "rb"):
141
- prev = zlib.crc32(eachLine, prev)
140
+ for each_line in open(file, "rb"):
141
+ prev = zlib.crc32(each_line, prev)
142
142
  return "%X" % (prev & 0xFFFFFFFF)
143
143
 
144
144
 
@@ -31,6 +31,9 @@ if TYPE_CHECKING:
31
31
 
32
32
  from sqlalchemy.orm import Session
33
33
 
34
+ LEGACY_SECTION_NAME = {}
35
+ LEGACY_OPTION_NAME = {}
36
+
34
37
 
35
38
  def convert_to_any_type(value: str) -> Union[bool, int, float, str]:
36
39
  if value.lower() in ['true', 'yes', 'on']:
@@ -225,8 +228,6 @@ def get_legacy_config(section: str, option: str):
225
228
  :param option: The option of the new config.
226
229
  :returns: The string value of the legacy option if one is found, None otherwise.
227
230
  """
228
- LEGACY_SECTION_NAME = {}
229
- LEGACY_OPTION_NAME = {}
230
231
 
231
232
  section = LEGACY_SECTION_NAME.get(section, section)
232
233
  option = LEGACY_OPTION_NAME.get(option, option)
@@ -20,6 +20,8 @@
20
20
 
21
21
  """
22
22
 
23
+ from typing import Optional
24
+
23
25
  from rucio.common.constraints import AUTHORIZED_VALUE_TYPES
24
26
 
25
27
 
@@ -93,11 +95,12 @@ class ClientParameterMismatch(RucioException):
93
95
 
94
96
  class ClientProtocolNotSupported(RucioException):
95
97
  """
96
- RucioException
98
+ Client protocol not supported
97
99
  """
98
- def __init__(self, *args):
100
+
101
+ def __init__(self, host: str, protocol: str, protocols_allowed: Optional[list[str]] = None, *args):
99
102
  super(ClientProtocolNotSupported, self).__init__(*args)
100
- self._message = "Client protocol not supported."
103
+ self._message = f"Client protocol '{protocol}' not supported when connecting to host '{host}'.{' Allowed protocols: ' + ', '.join(protocols_allowed) if protocols_allowed else ''}"
101
104
  self.error_code = 6
102
105
 
103
106
 
@@ -1182,3 +1185,14 @@ class ConfigLoadingError(RucioException):
1182
1185
  super(ConfigLoadingError, self).__init__(*args, **kwargs)
1183
1186
  self._message = 'Could not load Rucio configuration file. Rucio tried loading the following configuration file:\n\t %s' % (config_file)
1184
1187
  self.error_code = 112
1188
+
1189
+
1190
+ class ClientProtocolNotFound(RucioException):
1191
+ """
1192
+ Missing protocol in client configuration (e.g. no http/https in url).
1193
+ """
1194
+
1195
+ def __init__(self, host: str, protocols_allowed: Optional[list[str]] = None, *args):
1196
+ super(ClientProtocolNotFound, self).__init__(*args)
1197
+ self._message = f"Client protocol missing when connecting to host '{host}'.{' Allowed protocols: ' + ', '.join(protocols_allowed) if protocols_allowed else ''}"
1198
+ self.error_code = 113
@@ -44,6 +44,8 @@ DEBUG, INFO, WARN, ERROR = "DEBUG", "INFO ", "WARN ", "ERROR"
44
44
  # filename for locking
45
45
  LOCK_NAME = ".LOCK"
46
46
 
47
+ MAXFD = 1024
48
+
47
49
  # Session ID
48
50
  sessid = "%s.%s" % (int(time.time()), os.getpid())
49
51
 
@@ -131,7 +133,7 @@ def unitize(x: int) -> str:
131
133
 
132
134
  class Pcache:
133
135
 
134
- def Usage(self) -> None:
136
+ def usage(self) -> None:
135
137
  msg = """Usage: %s [flags] copy_prog [copy_flags] input output""" % self.progname
136
138
  sys.stderr.write("%s\n" % msg) # py3, py2
137
139
  # print>>sys.stderr, " flags are: "
@@ -227,7 +229,7 @@ class Pcache:
227
229
  # TODO: move checksum/size validation from lsm to pcache
228
230
  except getopt.GetoptError as err:
229
231
  sys.stderr.write("%s\n" % str(err))
230
- self.Usage()
232
+ self.usage()
231
233
  self.fail(100)
232
234
 
233
235
  for opt, arg in opts:
@@ -356,7 +358,7 @@ class Pcache:
356
358
 
357
359
  # Fail on extra args
358
360
  if not self.scratch_dir:
359
- self.Usage()
361
+ self.usage()
360
362
  self.fail(100)
361
363
 
362
364
  # hardcoded pcache dir
@@ -417,7 +419,7 @@ class Pcache:
417
419
 
418
420
  # Fail on extra args
419
421
  if not scratch_dir:
420
- self.Usage()
422
+ self.usage()
421
423
  self.fail(100)
422
424
 
423
425
  # If the source is lfn:, execute original command, no further action
@@ -491,7 +493,7 @@ class Pcache:
491
493
 
492
494
  # Must have a list of arguments
493
495
  if (self.parse_args(args[1:])):
494
- self.Usage()
496
+ self.usage()
495
497
  self.fail(100)
496
498
 
497
499
  # Cache dir may have been wiped
@@ -522,7 +524,7 @@ class Pcache:
522
524
 
523
525
  # Fail on extra args
524
526
  if (len(self.args) < 3):
525
- self.Usage()
527
+ self.usage()
526
528
  self.fail(100)
527
529
 
528
530
  self.copy_util = self.args[0]
@@ -1059,7 +1061,6 @@ class Pcache:
1059
1061
  os.dup2(n, i)
1060
1062
  os.dup2(n, o)
1061
1063
  os.dup2(n, e)
1062
- MAXFD = 1024
1063
1064
  try:
1064
1065
  import resource # Resource usage information.
1065
1066
  maxfd = resource.getrlimit(resource.RLIMIT_NOFILE)[1]