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.
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/PKG-INFO +1 -1
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/bin/rucio +14 -12
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/bin/rucio-admin +7 -4
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/client/accountclient.py +0 -1
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/client/baseclient.py +26 -19
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/client/commands/account.py +12 -11
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/client/commands/bin_legacy/rucio_admin.py +6 -7
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/client/commands/rse.py +25 -11
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/client/commands/utils.py +3 -2
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/client/downloadclient.py +2 -2
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/common/checksum.py +2 -2
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/common/config.py +3 -2
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/common/exception.py +17 -3
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/common/pcache.py +8 -7
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/common/schema/__init__.py +33 -33
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/common/utils.py +8 -8
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/rse/protocols/webdav.py +14 -10
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/vcsversion.py +3 -3
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/pyproject.toml +15 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_authentication.py +5 -5
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_bb8.py +13 -13
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_bin_rucio.py +15 -15
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_clients.py +52 -12
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_conveyor.py +12 -12
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_conveyor_submitter.py +15 -8
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_curl.py +1 -1
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_filter_engine.py +63 -63
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_judge_evaluator.py +52 -52
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_judge_repairer.py +4 -4
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_oauthmanager.py +1 -1
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_oidc.py +129 -129
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_replica.py +6 -6
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_replica_recoverer.py +4 -4
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_rse_lfn2path.py +1 -1
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_rule.py +7 -7
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_trace.py +2 -2
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_utils.py +1 -1
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/AUTHORS.rst +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/ChangeLog +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/LICENSE +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/MANIFEST.in +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/README.md +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/etc/rse-accounts.cfg.template +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/etc/rucio.cfg.atlas.client.template +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/etc/rucio.cfg.template +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/__init__.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/alembicrevision.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/client/__init__.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/client/accountlimitclient.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/client/client.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/client/commands/__init__.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/client/commands/bin_legacy/__init__.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/client/commands/bin_legacy/rucio.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/client/commands/command.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/client/commands/command_base.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/client/commands/config.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/client/commands/did.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/client/commands/download.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/client/commands/lifetime_exception.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/client/commands/replica.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/client/commands/rule.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/client/commands/scope.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/client/commands/subscription.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/client/commands/upload.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/client/configclient.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/client/credentialclient.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/client/didclient.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/client/diracclient.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/client/exportclient.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/client/fileclient.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/client/importclient.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/client/lifetimeclient.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/client/lockclient.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/client/metaconventionsclient.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/client/pingclient.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/client/replicaclient.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/client/requestclient.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/client/richclient.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/client/rseclient.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/client/ruleclient.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/client/scopeclient.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/client/subscriptionclient.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/client/touchclient.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/client/uploadclient.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/common/__init__.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/common/bittorrent.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/common/cache.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/common/client.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/common/constants.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/common/constraints.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/common/didtype.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/common/extra.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/common/logging.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/common/plugins.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/common/policy.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/common/schema/generic.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/common/schema/generic_multi_vo.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/common/stomp_utils.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/common/stopwatch.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/common/test_rucio_server.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/common/types.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/rse/__init__.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/rse/protocols/__init__.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/rse/protocols/bittorrent.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/rse/protocols/cache.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/rse/protocols/dummy.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/rse/protocols/gfal.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/rse/protocols/globus.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/rse/protocols/gsiftp.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/rse/protocols/http_cache.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/rse/protocols/mock.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/rse/protocols/ngarc.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/rse/protocols/posix.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/rse/protocols/protocol.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/rse/protocols/rclone.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/rse/protocols/rfio.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/rse/protocols/srm.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/rse/protocols/ssh.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/rse/protocols/storm.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/rse/protocols/xrootd.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/rse/rsemanager.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/rse/translation.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio/version.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/lib/rucio_clients.egg-info/SOURCES.txt +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/pylintrc +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/requirements/requirements.client.txt +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/setup.cfg +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/setup.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/setuputil.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_abacus_account.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_abacus_collection_replica.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_abacus_rse.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_account.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_account_limits.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_archive.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_auditor.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_auditor_hdfs.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_auditor_srmdumps.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_automatix.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_bad_replica.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_belleii.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_boolean.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_cli_client_structure.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_config.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_counter.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_credential.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_daemons.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_dataset_replicas.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_db.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_did.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_did_meta_plugins.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_download.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_dumper.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_gateway_external_representation.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_heartbeat.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_hermes.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_identity.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_impl_upload_download.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_import_export.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_judge_cleaner.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_judge_injector.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_lifetime.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_message.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_meta_conventions.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_meta_did.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_module_import.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_monitor.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_multi_vo.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_naming_convention.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_permission.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_pfns.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_ping.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_policy_package.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_preparer.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_qos.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_quarantined_replica.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_reaper.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_redirect.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_replica_sorting.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_request.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_root_proxy.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_rse.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_rse_expression_parser.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_rse_protocol_gfal2.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_rse_protocol_gfal2_impl.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_rse_protocol_posix.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_rse_protocol_rclone.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_rse_protocol_rsync.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_rse_protocol_srm.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_rse_protocol_ssh.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_rse_protocol_webdav.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_rse_protocol_xrootd.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_rse_selector.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_rucio_server.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_scope.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_subscription.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_throttler.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_tpc.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_transfer.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_transfer_plugins.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_undertaker.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tests/test_upload.py +0 -0
- {rucio_clients-36.2.0 → rucio_clients-36.3.0}/tools/merge_rucio_configs.py +0 -0
|
@@ -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 = "
|
|
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}
|
|
42
|
+
warning = f"{base_warning} Please replace your command with `rucio {' '.join(new_command)}`"
|
|
39
43
|
else:
|
|
40
|
-
warning = base_warning + "
|
|
44
|
+
warning = base_warning + " Please view rucio -h for an updated help menu."
|
|
41
45
|
|
|
42
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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}
|
|
94
|
+
warning = f"{base_warning} Please replace your command with `rucio {new_command}`"
|
|
92
95
|
else:
|
|
93
|
-
warning = base_warning + "
|
|
96
|
+
warning = base_warning + " Please view rucio -h for an updated help menu."
|
|
94
97
|
|
|
95
|
-
|
|
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
|
-
|
|
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.2.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
|
|
|
@@ -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='
|
|
1528
|
-
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',
|
|
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('
|
|
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'
|
|
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
|
|
|
@@ -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
|
-
|
|
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
|
|
|
@@ -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
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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]
|