rucio-clients 36.1.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.
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/PKG-INFO +1 -1
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/bin/rucio +27 -16
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/bin/rucio-admin +11 -5
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/lib/rucio/client/accountclient.py +0 -1
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/lib/rucio/client/baseclient.py +26 -19
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/lib/rucio/client/commands/account.py +12 -11
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/lib/rucio/client/commands/bin_legacy/rucio_admin.py +11 -11
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/lib/rucio/client/commands/rse.py +25 -11
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/lib/rucio/client/commands/utils.py +3 -2
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/lib/rucio/client/downloadclient.py +2 -2
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/lib/rucio/common/checksum.py +2 -2
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/lib/rucio/common/config.py +10 -18
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/lib/rucio/common/exception.py +32 -3
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/lib/rucio/common/pcache.py +8 -7
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/lib/rucio/common/schema/__init__.py +33 -33
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/lib/rucio/common/utils.py +8 -8
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/lib/rucio/rse/protocols/webdav.py +14 -10
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/lib/rucio/rse/translation.py +3 -2
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/lib/rucio/vcsversion.py +3 -3
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/lib/rucio_clients.egg-info/SOURCES.txt +0 -3
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/pyproject.toml +15 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/tests/test_authentication.py +5 -5
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/tests/test_bb8.py +13 -13
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/tests/test_bin_rucio.py +15 -15
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/tests/test_clients.py +52 -12
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/tests/test_conveyor.py +12 -12
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/tests/test_conveyor_submitter.py +15 -8
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/tests/test_curl.py +1 -1
- rucio_clients-36.3.0/tests/test_dumper.py +47 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/tests/test_filter_engine.py +63 -63
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/tests/test_hermes.py +2 -2
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/tests/test_judge_evaluator.py +52 -52
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/tests/test_judge_repairer.py +4 -4
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/tests/test_oauthmanager.py +1 -1
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/tests/test_oidc.py +129 -129
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/tests/test_replica.py +6 -6
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/tests/test_replica_recoverer.py +4 -4
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/tests/test_rse_lfn2path.py +1 -1
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/tests/test_rule.py +7 -7
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/tests/test_trace.py +2 -2
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/tests/test_utils.py +1 -1
- rucio_clients-36.1.0/tests/test_dumper.py +0 -237
- rucio_clients-36.1.0/tests/test_dumper_consistency.py +0 -407
- rucio_clients-36.1.0/tests/test_dumper_data_model.py +0 -334
- rucio_clients-36.1.0/tests/test_dumper_path_parsing.py +0 -47
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/AUTHORS.rst +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/ChangeLog +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/LICENSE +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/MANIFEST.in +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/README.md +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/etc/rse-accounts.cfg.template +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/etc/rucio.cfg.atlas.client.template +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/etc/rucio.cfg.template +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/lib/rucio/__init__.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/lib/rucio/alembicrevision.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/lib/rucio/client/__init__.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/lib/rucio/client/accountlimitclient.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/lib/rucio/client/client.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/lib/rucio/client/commands/__init__.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/lib/rucio/client/commands/bin_legacy/__init__.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/lib/rucio/client/commands/bin_legacy/rucio.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/lib/rucio/client/commands/command.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/lib/rucio/client/commands/command_base.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/lib/rucio/client/commands/config.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/lib/rucio/client/commands/did.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/lib/rucio/client/commands/download.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/lib/rucio/client/commands/lifetime_exception.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/lib/rucio/client/commands/replica.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/lib/rucio/client/commands/rule.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/lib/rucio/client/commands/scope.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/lib/rucio/client/commands/subscription.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/lib/rucio/client/commands/upload.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/lib/rucio/client/configclient.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/lib/rucio/client/credentialclient.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/lib/rucio/client/didclient.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/lib/rucio/client/diracclient.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/lib/rucio/client/exportclient.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/lib/rucio/client/fileclient.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/lib/rucio/client/importclient.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/lib/rucio/client/lifetimeclient.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/lib/rucio/client/lockclient.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/lib/rucio/client/metaconventionsclient.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/lib/rucio/client/pingclient.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/lib/rucio/client/replicaclient.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/lib/rucio/client/requestclient.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/lib/rucio/client/richclient.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/lib/rucio/client/rseclient.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/lib/rucio/client/ruleclient.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/lib/rucio/client/scopeclient.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/lib/rucio/client/subscriptionclient.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/lib/rucio/client/touchclient.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/lib/rucio/client/uploadclient.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/lib/rucio/common/__init__.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/lib/rucio/common/bittorrent.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/lib/rucio/common/cache.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/lib/rucio/common/client.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/lib/rucio/common/constants.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/lib/rucio/common/constraints.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/lib/rucio/common/didtype.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/lib/rucio/common/extra.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/lib/rucio/common/logging.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/lib/rucio/common/plugins.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/lib/rucio/common/policy.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/lib/rucio/common/schema/generic.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/lib/rucio/common/schema/generic_multi_vo.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/lib/rucio/common/stomp_utils.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/lib/rucio/common/stopwatch.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/lib/rucio/common/test_rucio_server.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/lib/rucio/common/types.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/lib/rucio/rse/__init__.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/lib/rucio/rse/protocols/__init__.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/lib/rucio/rse/protocols/bittorrent.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/lib/rucio/rse/protocols/cache.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/lib/rucio/rse/protocols/dummy.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/lib/rucio/rse/protocols/gfal.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/lib/rucio/rse/protocols/globus.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/lib/rucio/rse/protocols/gsiftp.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/lib/rucio/rse/protocols/http_cache.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/lib/rucio/rse/protocols/mock.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/lib/rucio/rse/protocols/ngarc.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/lib/rucio/rse/protocols/posix.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/lib/rucio/rse/protocols/protocol.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/lib/rucio/rse/protocols/rclone.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/lib/rucio/rse/protocols/rfio.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/lib/rucio/rse/protocols/srm.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/lib/rucio/rse/protocols/ssh.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/lib/rucio/rse/protocols/storm.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/lib/rucio/rse/protocols/xrootd.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/lib/rucio/rse/rsemanager.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/lib/rucio/version.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/pylintrc +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/requirements/requirements.client.txt +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/setup.cfg +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/setup.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/setuputil.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/tests/test_abacus_account.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/tests/test_abacus_collection_replica.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/tests/test_abacus_rse.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/tests/test_account.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/tests/test_account_limits.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/tests/test_archive.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/tests/test_auditor.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/tests/test_auditor_hdfs.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/tests/test_auditor_srmdumps.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/tests/test_automatix.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/tests/test_bad_replica.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/tests/test_belleii.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/tests/test_boolean.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/tests/test_cli_client_structure.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/tests/test_config.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/tests/test_counter.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/tests/test_credential.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/tests/test_daemons.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/tests/test_dataset_replicas.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/tests/test_db.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/tests/test_did.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/tests/test_did_meta_plugins.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/tests/test_download.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/tests/test_gateway_external_representation.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/tests/test_heartbeat.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/tests/test_identity.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/tests/test_impl_upload_download.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/tests/test_import_export.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/tests/test_judge_cleaner.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/tests/test_judge_injector.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/tests/test_lifetime.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/tests/test_message.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/tests/test_meta_conventions.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/tests/test_meta_did.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/tests/test_module_import.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/tests/test_monitor.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/tests/test_multi_vo.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/tests/test_naming_convention.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/tests/test_permission.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/tests/test_pfns.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/tests/test_ping.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/tests/test_policy_package.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/tests/test_preparer.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/tests/test_qos.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/tests/test_quarantined_replica.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/tests/test_reaper.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/tests/test_redirect.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/tests/test_replica_sorting.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/tests/test_request.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/tests/test_root_proxy.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/tests/test_rse.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/tests/test_rse_expression_parser.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/tests/test_rse_protocol_gfal2.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/tests/test_rse_protocol_gfal2_impl.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/tests/test_rse_protocol_posix.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/tests/test_rse_protocol_rclone.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/tests/test_rse_protocol_rsync.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/tests/test_rse_protocol_srm.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/tests/test_rse_protocol_ssh.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/tests/test_rse_protocol_webdav.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/tests/test_rse_protocol_xrootd.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/tests/test_rse_selector.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/tests/test_rucio_server.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/tests/test_scope.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/tests/test_subscription.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/tests/test_throttler.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/tests/test_tpc.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/tests/test_transfer.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/tests/test_transfer_plugins.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/tests/test_undertaker.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/tests/test_upload.py +0 -0
- {rucio_clients-36.1.0 → rucio_clients-36.3.0}/tools/merge_rucio_configs.py +0 -0
|
@@ -15,28 +15,39 @@
|
|
|
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
|
|
22
23
|
|
|
24
|
+
if TYPE_CHECKING:
|
|
25
|
+
from logging import Logger
|
|
23
26
|
|
|
24
|
-
|
|
25
|
-
|
|
27
|
+
|
|
28
|
+
def _get_first_command(args: list[str]) -> Optional[str]:
|
|
29
|
+
return next(
|
|
30
|
+
(
|
|
31
|
+
arg for arg in args
|
|
32
|
+
if arg != 'rucio' and (arg[0] != "-" or arg in ("-h", "--help", "--version"))
|
|
33
|
+
),
|
|
34
|
+
None
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def make_warning(logger: "Logger") -> None:
|
|
39
|
+
base_warning = "This method is being deprecated."
|
|
26
40
|
new_command = map_legacy_command()
|
|
27
41
|
if new_command is not None:
|
|
28
|
-
warning = f"{base_warning}
|
|
42
|
+
warning = f"{base_warning} Please replace your command with `rucio {' '.join(new_command)}`"
|
|
29
43
|
else:
|
|
30
|
-
warning = base_warning + "
|
|
44
|
+
warning = base_warning + " Please view rucio -h for an updated help menu."
|
|
31
45
|
|
|
32
|
-
|
|
46
|
+
logger.warning(warning)
|
|
33
47
|
|
|
34
48
|
|
|
35
49
|
def map_legacy_command() -> Optional[list[str]]:
|
|
36
|
-
|
|
37
|
-
command = [arg for arg in sys.argv if arg[0] != "-" or arg in ("-h", "--version")][1]
|
|
38
|
-
except IndexError:
|
|
39
|
-
command = None
|
|
50
|
+
command = _get_first_command(sys.argv[1:])
|
|
40
51
|
|
|
41
52
|
new_command = None
|
|
42
53
|
if command not in ("-h", "--version", None):
|
|
@@ -89,26 +100,26 @@ def map_legacy_command() -> Optional[list[str]]:
|
|
|
89
100
|
|
|
90
101
|
if __name__ == "__main__":
|
|
91
102
|
commands = ("-h", "--help", "--version", "account", "config", "did", "replica", "rse", "rule", "scope", "subscription", "ping", "whoami", "test-server", "lifetime-exception", "upload", "download")
|
|
92
|
-
|
|
103
|
+
logger = setup_logger(module_name=__name__)
|
|
104
|
+
first_command = _get_first_command(sys.argv[1:])
|
|
105
|
+
|
|
93
106
|
is_legacy = '--legacy' in sys.argv
|
|
94
107
|
|
|
95
108
|
if (first_command in commands) and not is_legacy:
|
|
96
109
|
main()
|
|
97
110
|
|
|
98
111
|
elif is_legacy:
|
|
99
|
-
|
|
100
|
-
print(warning)
|
|
112
|
+
make_warning(logger)
|
|
101
113
|
sys.argv.pop(sys.argv.index('--legacy'))
|
|
102
114
|
main_legacy()
|
|
103
115
|
|
|
104
116
|
else:
|
|
105
|
-
|
|
106
|
-
print(warning)
|
|
117
|
+
make_warning(logger)
|
|
107
118
|
try:
|
|
108
119
|
main_legacy()
|
|
109
120
|
# Make a custom warning - show the new help menu when invalid commands are called.
|
|
110
121
|
except argparse.ArgumentError:
|
|
111
|
-
|
|
122
|
+
logger.error("Invalid argument(s) - %s " % sys.argv[1:])
|
|
112
123
|
command = map_legacy_command()
|
|
113
124
|
if command is not None:
|
|
114
125
|
sys.argv = ["rucio"] + command + ["-h"]
|
|
@@ -15,12 +15,18 @@
|
|
|
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
|
-
|
|
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:
|
|
27
|
+
first_command = args[1]
|
|
28
|
+
except IndexError:
|
|
29
|
+
first_command = None
|
|
24
30
|
try:
|
|
25
31
|
second_command = args[2]
|
|
26
32
|
except IndexError:
|
|
@@ -85,11 +91,11 @@ def make_warning():
|
|
|
85
91
|
except KeyError:
|
|
86
92
|
new_command = "-h"
|
|
87
93
|
|
|
88
|
-
warning = f"{base_warning}
|
|
94
|
+
warning = f"{base_warning} Please replace your command with `rucio {new_command}`"
|
|
89
95
|
else:
|
|
90
|
-
warning = base_warning + "
|
|
96
|
+
warning = base_warning + " Please view rucio -h for an updated help menu."
|
|
91
97
|
|
|
92
|
-
|
|
98
|
+
logger.warning(warning)
|
|
93
99
|
|
|
94
100
|
|
|
95
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
|
-
|
|
161
|
-
|
|
160
|
+
rucio_scheme_allowed = ['http', 'https']
|
|
161
|
+
auth_scheme_allowed = ['http', 'https']
|
|
162
162
|
|
|
163
|
-
if
|
|
164
|
-
raise
|
|
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
|
|
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
|
|
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
|
-
|
|
606
|
-
self.logger.debug("Response headers %s and text %s" % (str(
|
|
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
|
|
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 =
|
|
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.
|
|
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
|
-
|
|
838
|
-
if
|
|
839
|
-
return
|
|
840
|
-
|
|
841
|
-
result = self._send_request(
|
|
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.
|
|
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.
|
|
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="
|
|
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="
|
|
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="
|
|
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=
|
|
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=
|
|
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
|
|
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"]:
|
{rucio_clients-36.1.0 → rucio_clients-36.3.0}/lib/rucio/client/commands/bin_legacy/rucio_admin.py
RENAMED
|
@@ -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.
|
|
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.
|
|
99
|
-
print('Deleted account: %s' % args.
|
|
97
|
+
client.delete_account(args.account)
|
|
98
|
+
print('Deleted account: %s' % args.account)
|
|
100
99
|
return SUCCESS
|
|
101
100
|
|
|
102
101
|
|
|
@@ -418,7 +417,6 @@ def info_rse(args, client, logger, console, spinner):
|
|
|
418
417
|
if cli_config == 'rich':
|
|
419
418
|
table = generate_table(table_data, row_styles=['none'], col_alignments=['left', 'left'])
|
|
420
419
|
output.append(table)
|
|
421
|
-
table_data = []
|
|
422
420
|
else:
|
|
423
421
|
print('Protocols:')
|
|
424
422
|
print('==========')
|
|
@@ -430,6 +428,7 @@ def info_rse(args, client, logger, console, spinner):
|
|
|
430
428
|
else:
|
|
431
429
|
print(' ' + protocol['scheme'])
|
|
432
430
|
|
|
431
|
+
table_data = []
|
|
433
432
|
for item in sorted(protocol):
|
|
434
433
|
if cli_config == 'rich':
|
|
435
434
|
if item == 'domains':
|
|
@@ -447,10 +446,11 @@ def info_rse(args, client, logger, console, spinner):
|
|
|
447
446
|
else:
|
|
448
447
|
print(' ' + item + ': ' + str(protocol[item]))
|
|
449
448
|
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
449
|
+
if cli_config == 'rich':
|
|
450
|
+
table = generate_table(table_data, col_alignments=['left', 'left'], row_styles=['none'])
|
|
451
|
+
output.append(Padding.indent(table, 2))
|
|
453
452
|
|
|
453
|
+
if cli_config == 'rich':
|
|
454
454
|
header = ['SOURCE', 'USED', 'FILES', 'FREE', 'TOTAL', 'UPDATED AT']
|
|
455
455
|
key2id = {header[i].lower().replace(' ', '_'): i for i in range(len(header))}
|
|
456
456
|
table_data = []
|
|
@@ -1523,8 +1523,8 @@ def get_parser():
|
|
|
1523
1523
|
'\n')
|
|
1524
1524
|
add_account_parser.set_defaults(which='add_account')
|
|
1525
1525
|
add_account_parser.add_argument('account', action='store', help='Account name')
|
|
1526
|
-
add_account_parser.add_argument('--type', dest='
|
|
1527
|
-
add_account_parser.add_argument('--email', dest='
|
|
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',
|
|
1528
1528
|
help='Email address associated with the account')
|
|
1529
1529
|
|
|
1530
1530
|
# The disable_account command
|
|
@@ -1539,7 +1539,7 @@ def get_parser():
|
|
|
1539
1539
|
' Deleted account: jdoe-sister\n'
|
|
1540
1540
|
'\n')
|
|
1541
1541
|
delete_account_parser.set_defaults(which='delete_account')
|
|
1542
|
-
delete_account_parser.add_argument('
|
|
1542
|
+
delete_account_parser.add_argument('account', action='store', help='Account name')
|
|
1543
1543
|
|
|
1544
1544
|
# The info_account command
|
|
1545
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'
|
|
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
|
|
129
|
-
"$ rucio rse attribute add --rse ThisRSE --key given-attribute --value updated
|
|
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
|
-
|
|
153
|
-
"
|
|
154
|
-
"
|
|
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
|
|
166
|
-
parser.add_argument("--source", dest="source",
|
|
167
|
-
parser.add_argument("--destination", dest="destination",
|
|
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
|
|
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
|
-
|
|
1679
|
-
if
|
|
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
|
|
141
|
-
prev = zlib.crc32(
|
|
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
|
|
|
@@ -17,10 +17,11 @@
|
|
|
17
17
|
import configparser
|
|
18
18
|
import json
|
|
19
19
|
import os
|
|
20
|
+
from functools import cache
|
|
20
21
|
from typing import TYPE_CHECKING, Any, Optional, TypeVar, Union, overload
|
|
21
22
|
|
|
22
23
|
from rucio.common import exception
|
|
23
|
-
from rucio.common.exception import ConfigNotFound, DatabaseException
|
|
24
|
+
from rucio.common.exception import ConfigLoadingError, ConfigNotFound, DatabaseException
|
|
24
25
|
|
|
25
26
|
_T = TypeVar('_T')
|
|
26
27
|
_U = TypeVar('_U')
|
|
@@ -30,6 +31,9 @@ if TYPE_CHECKING:
|
|
|
30
31
|
|
|
31
32
|
from sqlalchemy.orm import Session
|
|
32
33
|
|
|
34
|
+
LEGACY_SECTION_NAME = {}
|
|
35
|
+
LEGACY_OPTION_NAME = {}
|
|
36
|
+
|
|
33
37
|
|
|
34
38
|
def convert_to_any_type(value: str) -> Union[bool, int, float, str]:
|
|
35
39
|
if value.lower() in ['true', 'yes', 'on']:
|
|
@@ -224,8 +228,6 @@ def get_legacy_config(section: str, option: str):
|
|
|
224
228
|
:param option: The option of the new config.
|
|
225
229
|
:returns: The string value of the legacy option if one is found, None otherwise.
|
|
226
230
|
"""
|
|
227
|
-
LEGACY_SECTION_NAME = {}
|
|
228
|
-
LEGACY_OPTION_NAME = {}
|
|
229
231
|
|
|
230
232
|
section = LEGACY_SECTION_NAME.get(section, section)
|
|
231
233
|
option = LEGACY_OPTION_NAME.get(option, option)
|
|
@@ -656,7 +658,6 @@ def __config_get_table(
|
|
|
656
658
|
:raises ConfigNotFound
|
|
657
659
|
:raises DatabaseException
|
|
658
660
|
"""
|
|
659
|
-
global __CONFIG
|
|
660
661
|
try:
|
|
661
662
|
from rucio.core.config import get as core_config_get
|
|
662
663
|
return core_config_get(section, option, default=default, session=session, use_cache=use_cache,
|
|
@@ -665,7 +666,7 @@ def __config_get_table(
|
|
|
665
666
|
if raise_exception and default is None:
|
|
666
667
|
raise err
|
|
667
668
|
if clean_cached:
|
|
668
|
-
|
|
669
|
+
clean_cached_config()
|
|
669
670
|
return default
|
|
670
671
|
|
|
671
672
|
|
|
@@ -753,21 +754,15 @@ def get_rse_credentials(path_to_credentials_file: Optional[Union[str, os.PathLik
|
|
|
753
754
|
return credentials
|
|
754
755
|
|
|
755
756
|
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
757
|
+
@cache
|
|
759
758
|
def get_config() -> configparser.ConfigParser:
|
|
760
759
|
"""Factory function for the configuration class. Returns the ConfigParser instance."""
|
|
761
|
-
|
|
762
|
-
if __CONFIG is None:
|
|
763
|
-
__CONFIG = Config()
|
|
764
|
-
return __CONFIG.parser
|
|
760
|
+
return Config().parser
|
|
765
761
|
|
|
766
762
|
|
|
767
763
|
def clean_cached_config() -> None:
|
|
768
764
|
"""Deletes the cached config singleton instance."""
|
|
769
|
-
|
|
770
|
-
__CONFIG = None
|
|
765
|
+
get_config.cache_clear()
|
|
771
766
|
|
|
772
767
|
|
|
773
768
|
class Config:
|
|
@@ -790,7 +785,4 @@ class Config:
|
|
|
790
785
|
'\n\t' + '\n\t'.join(configs))
|
|
791
786
|
|
|
792
787
|
if not self.parser.read(self.configfile) == [self.configfile]:
|
|
793
|
-
raise
|
|
794
|
-
'Could not load Rucio configuration file. '
|
|
795
|
-
'Rucio tried loading the following configuration file:'
|
|
796
|
-
'\n\t' + self.configfile)
|
|
788
|
+
raise ConfigLoadingError(self.configfile)
|
|
@@ -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
|
-
|
|
98
|
+
Client protocol not supported
|
|
97
99
|
"""
|
|
98
|
-
|
|
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
|
|
|
@@ -1167,3 +1170,29 @@ class ChecksumCalculationError(RucioException):
|
|
|
1167
1170
|
self.filepath = filepath
|
|
1168
1171
|
self._message = 'An error occurred while calculating the %s checksum of file %s.' % (self.algorithm_name, self.filepath)
|
|
1169
1172
|
self.error_code = 111
|
|
1173
|
+
|
|
1174
|
+
|
|
1175
|
+
class ConfigLoadingError(RucioException):
|
|
1176
|
+
"""
|
|
1177
|
+
An error occurred while loading the configuration.
|
|
1178
|
+
"""
|
|
1179
|
+
def __init__(
|
|
1180
|
+
self,
|
|
1181
|
+
config_file: str,
|
|
1182
|
+
*args,
|
|
1183
|
+
**kwargs
|
|
1184
|
+
):
|
|
1185
|
+
super(ConfigLoadingError, self).__init__(*args, **kwargs)
|
|
1186
|
+
self._message = 'Could not load Rucio configuration file. Rucio tried loading the following configuration file:\n\t %s' % (config_file)
|
|
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
|