rucio-clients 35.5.0__tar.gz → 36.0.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-35.5.0 → rucio_clients-36.0.0}/AUTHORS.rst +1 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/PKG-INFO +3 -1
- rucio_clients-36.0.0/bin/rucio +118 -0
- rucio_clients-36.0.0/bin/rucio-admin +89 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/etc/rucio.cfg.atlas.client.template +3 -2
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/etc/rucio.cfg.template +2 -1
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/client/baseclient.py +7 -5
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/client/downloadclient.py +3 -1
- rucio_clients-36.0.0/lib/rucio/client/richclient.py +324 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/client/rseclient.py +4 -4
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/client/uploadclient.py +4 -1
- rucio_clients-36.0.0/lib/rucio/common/bittorrent.py +234 -0
- rucio_clients-36.0.0/lib/rucio/common/cache.py +111 -0
- rucio_clients-36.0.0/lib/rucio/common/checksum.py +151 -0
- rucio_clients-36.0.0/lib/rucio/common/client.py +122 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/common/config.py +10 -15
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/common/constants.py +60 -2
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/common/didtype.py +72 -24
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/common/exception.py +67 -14
- rucio_clients-36.0.0/lib/rucio/common/extra.py +31 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/common/logging.py +13 -13
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/common/plugins.py +59 -27
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/common/schema/__init__.py +53 -11
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/common/test_rucio_server.py +14 -8
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/common/types.py +108 -50
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/common/utils.py +63 -630
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/rse/__init__.py +3 -3
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/rse/protocols/bittorrent.py +14 -1
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/rse/protocols/gfal.py +1 -1
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/rse/protocols/gsiftp.py +15 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/rse/protocols/posix.py +1 -1
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/rse/protocols/protocol.py +16 -298
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/rse/protocols/rclone.py +2 -1
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/rse/protocols/rfio.py +9 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/rse/protocols/ssh.py +2 -1
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/rse/protocols/xrootd.py +2 -1
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/rse/rsemanager.py +11 -8
- rucio_clients-36.0.0/lib/rucio/rse/translation.py +273 -0
- rucio_clients-36.0.0/lib/rucio/vcsversion.py +11 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/version.py +7 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio_clients.egg-info/SOURCES.txt +7 -7
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/pyproject.toml +21 -1
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/requirements/requirements.client.txt +2 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/setup.py +1 -1
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/setuputil.py +3 -1
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_belleii.py +1 -1
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_bin_rucio.py +103 -102
- rucio_clients-36.0.0/tests/test_cli_client_structure.py +673 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_conveyor.py +2 -1
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_download.py +1 -15
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_impl_upload_download.py +30 -30
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_multi_vo.py +0 -2
- rucio_clients-36.0.0/tests/test_policy_package.py +60 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_replica_recoverer.py +5 -5
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_replica_sorting.py +22 -1
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_rse.py +4 -4
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_rse_lfn2path.py +1 -1
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_rse_protocol_rclone.py +2 -1
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_rse_protocol_rsync.py +2 -1
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_rse_protocol_ssh.py +2 -1
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_transfer_plugins.py +88 -75
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_upload.py +6 -1
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_utils.py +2 -24
- rucio_clients-35.5.0/bin/rucio +0 -2541
- rucio_clients-35.5.0/bin/rucio-admin +0 -2447
- rucio_clients-35.5.0/lib/rucio/common/cache.py +0 -74
- rucio_clients-35.5.0/lib/rucio/common/extra.py +0 -36
- rucio_clients-35.5.0/lib/rucio/common/schema/atlas.py +0 -413
- rucio_clients-35.5.0/lib/rucio/common/schema/belleii.py +0 -408
- rucio_clients-35.5.0/lib/rucio/common/schema/domatpc.py +0 -401
- rucio_clients-35.5.0/lib/rucio/common/schema/escape.py +0 -426
- rucio_clients-35.5.0/lib/rucio/common/schema/icecube.py +0 -406
- rucio_clients-35.5.0/lib/rucio/vcsversion.py +0 -11
- rucio_clients-35.5.0/tests/test_common_types.py +0 -50
- rucio_clients-35.5.0/tests/test_didtype.py +0 -96
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/ChangeLog +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/LICENSE +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/MANIFEST.in +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/README.md +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/etc/rse-accounts.cfg.template +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/__init__.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/alembicrevision.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/client/__init__.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/client/accountclient.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/client/accountlimitclient.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/client/client.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/client/configclient.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/client/credentialclient.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/client/didclient.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/client/diracclient.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/client/exportclient.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/client/fileclient.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/client/importclient.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/client/lifetimeclient.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/client/lockclient.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/client/metaconventionsclient.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/client/pingclient.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/client/replicaclient.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/client/requestclient.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/client/ruleclient.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/client/scopeclient.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/client/subscriptionclient.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/client/touchclient.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/common/__init__.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/common/constraints.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/common/pcache.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/common/policy.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/common/schema/generic.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/common/schema/generic_multi_vo.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/common/stomp_utils.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/common/stopwatch.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/rse/protocols/__init__.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/rse/protocols/cache.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/rse/protocols/dummy.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/rse/protocols/globus.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/rse/protocols/http_cache.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/rse/protocols/mock.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/rse/protocols/ngarc.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/rse/protocols/srm.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/rse/protocols/storm.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/lib/rucio/rse/protocols/webdav.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/pylintrc +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/setup.cfg +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_abacus_account.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_abacus_collection_replica.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_abacus_rse.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_account.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_account_limits.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_archive.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_auditor.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_auditor_hdfs.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_auditor_srmdumps.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_authentication.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_automatix.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_bad_replica.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_bb8.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_boolean.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_clients.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_config.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_conveyor_submitter.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_counter.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_credential.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_curl.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_daemons.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_dataset_replicas.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_db.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_did.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_did_meta_plugins.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_dumper.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_dumper_consistency.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_dumper_data_model.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_dumper_path_parsing.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_filter_engine.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_gateway_external_representation.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_heartbeat.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_hermes.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_identity.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_import_export.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_judge_cleaner.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_judge_evaluator.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_judge_injector.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_judge_repairer.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_lifetime.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_message.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_meta_conventions.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_meta_did.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_module_import.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_monitor.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_naming_convention.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_oauthmanager.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_oidc.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_permission.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_pfns.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_ping.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_preparer.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_qos.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_quarantined_replica.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_reaper.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_redirect.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_replica.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_request.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_root_proxy.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_rse_expression_parser.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_rse_protocol_gfal2.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_rse_protocol_gfal2_impl.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_rse_protocol_posix.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_rse_protocol_srm.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_rse_protocol_webdav.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_rse_protocol_xrootd.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_rse_selector.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_rucio_server.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_rule.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_scope.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_subscription.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_throttler.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_tpc.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_trace.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_transfer.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tests/test_undertaker.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-36.0.0}/tools/merge_rucio_configs.py +0 -0
|
@@ -67,6 +67,7 @@ Individual contributors to the source code
|
|
|
67
67
|
- Aksel Lunde Aase <aksel.lunde.aase@gmail.com>, 2022
|
|
68
68
|
- Elena Gazzarrini <gazzarrini.elena@gmail.com>, 2022-2023
|
|
69
69
|
- Maximilian Linhoff, <maximilian.linhoff@tu-dortmund.de>, 2024
|
|
70
|
+
- Eric Banzuzi, <eric.banzuzi@gmail.com>, 2024
|
|
70
71
|
|
|
71
72
|
Organisations employing contributors
|
|
72
73
|
------------------------------------
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: rucio-clients
|
|
3
|
-
Version:
|
|
3
|
+
Version: 36.0.0
|
|
4
4
|
Summary: Rucio Client Lite Package
|
|
5
5
|
Home-page: https://rucio.cern.ch/
|
|
6
6
|
Author: Rucio
|
|
@@ -24,6 +24,8 @@ Requires-Dist: urllib3>=1.26.18
|
|
|
24
24
|
Requires-Dist: dogpile-cache>=1.2.2
|
|
25
25
|
Requires-Dist: tabulate>=0.9.0
|
|
26
26
|
Requires-Dist: jsonschema>=4.20.0
|
|
27
|
+
Requires-Dist: packaging>=24.1
|
|
28
|
+
Requires-Dist: rich>=13.7.1
|
|
27
29
|
Provides-Extra: ssh
|
|
28
30
|
Requires-Dist: paramiko>=3.4.0; extra == "ssh"
|
|
29
31
|
Provides-Extra: kerberos
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
# Copyright European Organization for Nuclear Research (CERN) since 2012
|
|
3
|
+
#
|
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
# you may not use this file except in compliance with the License.
|
|
6
|
+
# You may obtain a copy of the License at
|
|
7
|
+
#
|
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
#
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
# See the License for the specific language governing permissions and
|
|
14
|
+
# limitations under the License.
|
|
15
|
+
|
|
16
|
+
import argparse
|
|
17
|
+
import sys
|
|
18
|
+
from typing import Optional
|
|
19
|
+
|
|
20
|
+
from rucio.client.commands.bin_legacy.rucio import main as main_legacy
|
|
21
|
+
from rucio.client.commands.command import main
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def make_warning():
|
|
25
|
+
base_warning = "\nWARNING: This method is being deprecated."
|
|
26
|
+
new_command = map_legacy_command()
|
|
27
|
+
if new_command is not None:
|
|
28
|
+
warning = f"{base_warning}\nPlease replace your command with `rucio {' '.join(new_command)}`.\n"
|
|
29
|
+
else:
|
|
30
|
+
warning = base_warning + "\nPlease view rucio -h for an updated help menu.\n"
|
|
31
|
+
|
|
32
|
+
return warning
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def map_legacy_command() -> Optional[list[str]]:
|
|
36
|
+
try:
|
|
37
|
+
command = [arg for arg in sys.argv if arg[0] != "-" or arg in ("-h", "--version")][1]
|
|
38
|
+
except IndexError:
|
|
39
|
+
command = None
|
|
40
|
+
|
|
41
|
+
new_command = None
|
|
42
|
+
if command not in ("-h", "--version", None):
|
|
43
|
+
command_map = {
|
|
44
|
+
"list-file-replicas": ["replica", "list"],
|
|
45
|
+
"list-dataset-replicas": ["replica", "dataset"],
|
|
46
|
+
"add-dataset": ["did", "add", "--type dataset"],
|
|
47
|
+
"add-container": ["did", "add", "--type container"],
|
|
48
|
+
"attach": ["did", "content", "add"],
|
|
49
|
+
"detach": ["did", "content", "remove"],
|
|
50
|
+
"ls": ["did", "list"],
|
|
51
|
+
"list-dids": ["did", "list"],
|
|
52
|
+
"list-parent-dids": ["did", "show", "--parent"],
|
|
53
|
+
"list-scopes": ["scope", "list"],
|
|
54
|
+
"close": ["did", "update", "--close"],
|
|
55
|
+
"reopen": ["did", "update", "--open"],
|
|
56
|
+
"stat": ["did", "show"],
|
|
57
|
+
"erase": ["did", "remove"],
|
|
58
|
+
"list-content": ["did", "content", "list"],
|
|
59
|
+
"list-content-history": ["did", "content", "history"],
|
|
60
|
+
"upload": ["upload"],
|
|
61
|
+
"get": ["download"],
|
|
62
|
+
"download": ["download"],
|
|
63
|
+
"get-metadata": ["did", "metadata", "list"],
|
|
64
|
+
"set-metadata": ["did", "metadata", "add"],
|
|
65
|
+
"delete-metadata": ["did", "metadata", "remove"],
|
|
66
|
+
"list-rse-usage": ["rse", "show"],
|
|
67
|
+
"list-account-usage": ["account", "usage"],
|
|
68
|
+
"list-account-limits": ["account", "limit", "list"],
|
|
69
|
+
"add-rule": ["rule", "add"],
|
|
70
|
+
"delete-rule": ["rule", "remove"],
|
|
71
|
+
"rule-info": ["rule", "info"],
|
|
72
|
+
"list-rules": ["rule", "list"],
|
|
73
|
+
"list-rules-history": ["rule", "history"],
|
|
74
|
+
"update-rule": ["rule", "update"],
|
|
75
|
+
"move-rule": ["rule", "update", "--move"],
|
|
76
|
+
"list-rses": ["rse", "list"],
|
|
77
|
+
"list-suspicious-replicas": ["replica", "state", "suspicious"],
|
|
78
|
+
"list-rse-attributes": ["rse", "attribute", "list"],
|
|
79
|
+
"touch": ["did", "update", "--touch"],
|
|
80
|
+
"add-lifetime-exception": ["lifetime-exception", "add"],
|
|
81
|
+
}
|
|
82
|
+
try:
|
|
83
|
+
new_command = command_map[command]
|
|
84
|
+
except KeyError:
|
|
85
|
+
pass
|
|
86
|
+
|
|
87
|
+
return new_command
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
if __name__ == "__main__":
|
|
91
|
+
commands = ("-h", "--version", "account", "config", "did", "replica", "rse", "rule", "scope", "subscription", "ping", "whoami", "test-server", "lifetime-exception", "upload", "download")
|
|
92
|
+
first_command = [arg for arg in sys.argv if arg[0] != "-" or arg in ("-h", "--help", "--version")][1]
|
|
93
|
+
is_legacy = '--legacy' in sys.argv
|
|
94
|
+
|
|
95
|
+
if (first_command in commands) and not is_legacy:
|
|
96
|
+
main()
|
|
97
|
+
|
|
98
|
+
elif is_legacy:
|
|
99
|
+
warning = make_warning()
|
|
100
|
+
print(warning)
|
|
101
|
+
sys.argv.pop(sys.argv.index('--legacy'))
|
|
102
|
+
main_legacy()
|
|
103
|
+
|
|
104
|
+
else:
|
|
105
|
+
warning = make_warning()
|
|
106
|
+
print(warning)
|
|
107
|
+
try:
|
|
108
|
+
main_legacy()
|
|
109
|
+
# Make a custom warning - show the new help menu when invalid commands are called.
|
|
110
|
+
except argparse.ArgumentError:
|
|
111
|
+
print("Invalid argument(s) - %s " % sys.argv[1:])
|
|
112
|
+
command = map_legacy_command()
|
|
113
|
+
if command is not None:
|
|
114
|
+
sys.argv = ["rucio"] + command + ["-h"]
|
|
115
|
+
else:
|
|
116
|
+
sys.argv = ["rucio", "-h"]
|
|
117
|
+
|
|
118
|
+
main()
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
# Copyright European Organization for Nuclear Research (CERN) since 2012
|
|
3
|
+
#
|
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
# you may not use this file except in compliance with the License.
|
|
6
|
+
# You may obtain a copy of the License at
|
|
7
|
+
#
|
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
#
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
# See the License for the specific language governing permissions and
|
|
14
|
+
# limitations under the License.
|
|
15
|
+
import sys
|
|
16
|
+
|
|
17
|
+
from rucio.client.commands.bin_legacy.rucio_admin import main as main_legacy
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def make_warning():
|
|
21
|
+
base_warning = "\nWARNING: This method is being deprecated."
|
|
22
|
+
args = [arg for arg in sys.argv if arg[0] != "-" or arg in ("-h", "--help", "--version")]
|
|
23
|
+
first_command = args[1]
|
|
24
|
+
try:
|
|
25
|
+
second_command = args[2]
|
|
26
|
+
except IndexError:
|
|
27
|
+
second_command = "-h"
|
|
28
|
+
|
|
29
|
+
if first_command not in ("-h", "--version", "--help"):
|
|
30
|
+
command_map = {
|
|
31
|
+
"data": {"-h": "did -h", "import": "did upload", "export": "did download"},
|
|
32
|
+
"account": {
|
|
33
|
+
"-h": "account -h",
|
|
34
|
+
"add": "account add",
|
|
35
|
+
"delete": "account remove",
|
|
36
|
+
"info": "account show",
|
|
37
|
+
"update": "account update",
|
|
38
|
+
"set-limits": "account limit add",
|
|
39
|
+
"get-limits": "account limit list",
|
|
40
|
+
"delete-limits": "account limit remove",
|
|
41
|
+
"ban": "account update --ban True",
|
|
42
|
+
"unban": "account update --ban False",
|
|
43
|
+
"list-attributes": "account attribute list",
|
|
44
|
+
"add-attribute": "account attribute add",
|
|
45
|
+
"delete-attribute": "account attribute remove",
|
|
46
|
+
},
|
|
47
|
+
"identity": {"-h": "account identity -h", "add": "account identity add", "delete": "account identity remove"},
|
|
48
|
+
"rse": {
|
|
49
|
+
"-h": "rse -h",
|
|
50
|
+
"add": "rse add",
|
|
51
|
+
"list": "rse",
|
|
52
|
+
"update": "rse update",
|
|
53
|
+
"info": "rse info",
|
|
54
|
+
"set-attribute": "rse attribute add",
|
|
55
|
+
"delete-attribute": "rse attribute remove",
|
|
56
|
+
"delete-distance": "rse distance remove",
|
|
57
|
+
"get-distance": "rse distance list",
|
|
58
|
+
"get-attribute": "rse attribute list",
|
|
59
|
+
"add-protocol": "rse protocol add",
|
|
60
|
+
"delete-protocol": "rse protocol remove",
|
|
61
|
+
"delete": "rse remove",
|
|
62
|
+
"add-qos-policy": "rse qos add",
|
|
63
|
+
"add-distance": "rse distance add",
|
|
64
|
+
"delete-qos-policy": "rse qos remove",
|
|
65
|
+
"list-qos-policies": "rse qos list",
|
|
66
|
+
"set-limit": "rse limit add",
|
|
67
|
+
"delete-limit": "rse limit remove",
|
|
68
|
+
},
|
|
69
|
+
"scope": {"-h": "scope -h", "add": "scope add", "list": "scope list"},
|
|
70
|
+
"config": {"-h": "config -h", "get": "config list", "set": "config add", "delete": "config remove"},
|
|
71
|
+
"subscription": {"-h": "subscription -h", "add": "subscription add", "list": "subscription", "update": "subscription update", "reevaluate": "subscription touch"},
|
|
72
|
+
"replicas": {"-h": "replica -h", "quarantine": "replica state quarantine", "declare-bad": "replica state bad", "declare-temporary-unavailable": "replica state temp-unavailable", "list-pfns": "replica pfn", "set-tombstone": "replica tombstone"},
|
|
73
|
+
}
|
|
74
|
+
try:
|
|
75
|
+
new_command = command_map[first_command]
|
|
76
|
+
new_command = new_command[second_command]
|
|
77
|
+
except KeyError:
|
|
78
|
+
new_command = "-h"
|
|
79
|
+
|
|
80
|
+
warning = f"{base_warning}\nPlease replace your command with `rucio {new_command}`.\n"
|
|
81
|
+
else:
|
|
82
|
+
warning = base_warning + "\nPlease view rucio -h for an updated help menu.\n"
|
|
83
|
+
|
|
84
|
+
print(warning)
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
if __name__ == "__main__":
|
|
88
|
+
make_warning()
|
|
89
|
+
main_legacy()
|
|
@@ -29,8 +29,9 @@ request_retries = 3
|
|
|
29
29
|
auth_type = x509_proxy
|
|
30
30
|
|
|
31
31
|
[policy]
|
|
32
|
-
|
|
33
|
-
|
|
32
|
+
package = atlas_rucio_policy_package
|
|
33
|
+
#permission = atlas
|
|
34
|
+
#schema = atlas
|
|
34
35
|
lfn2pfn_algorithm_default = hash
|
|
35
36
|
support = hn-atlas-dist-analysis-help@cern.ch
|
|
36
37
|
support_rucio = https://github.com/rucio/rucio/issues/
|
|
@@ -229,9 +229,10 @@ panda_url = http://bigpanda.cern.ch/jobs/?category=analysis&jobstatus=running
|
|
|
229
229
|
window = 604800
|
|
230
230
|
|
|
231
231
|
[policy]
|
|
232
|
-
package =
|
|
232
|
+
package = atlas_rucio_policy_package
|
|
233
233
|
permission = atlas
|
|
234
234
|
schema = atlas
|
|
235
|
+
extract_scope = atlas
|
|
235
236
|
lfn2pfn_algorithm_default = hash
|
|
236
237
|
support = hn-atlas-dist-analysis-help@cern.ch
|
|
237
238
|
support_rucio = https://github.com/rucio/rucio/issues/
|
|
@@ -22,13 +22,11 @@ import os
|
|
|
22
22
|
import secrets
|
|
23
23
|
import sys
|
|
24
24
|
import time
|
|
25
|
-
from collections.abc import Generator
|
|
26
25
|
from configparser import NoOptionError, NoSectionError
|
|
27
|
-
from logging import Logger
|
|
28
26
|
from os import environ, fdopen, geteuid, makedirs, path
|
|
29
27
|
from shutil import move
|
|
30
28
|
from tempfile import mkstemp
|
|
31
|
-
from typing import Any, Optional
|
|
29
|
+
from typing import TYPE_CHECKING, Any, Optional
|
|
32
30
|
from urllib.parse import urlparse
|
|
33
31
|
|
|
34
32
|
import requests
|
|
@@ -44,6 +42,10 @@ from rucio.common.exception import CannotAuthenticate, ClientProtocolNotSupporte
|
|
|
44
42
|
from rucio.common.extra import import_extras
|
|
45
43
|
from rucio.common.utils import build_url, get_tmp_dir, my_key_generator, parse_response, setup_logger, ssh_sign
|
|
46
44
|
|
|
45
|
+
if TYPE_CHECKING:
|
|
46
|
+
from collections.abc import Generator
|
|
47
|
+
from logging import Logger
|
|
48
|
+
|
|
47
49
|
EXTRA_MODULES = import_extras(['requests_kerberos'])
|
|
48
50
|
|
|
49
51
|
if EXTRA_MODULES['requests_kerberos']:
|
|
@@ -90,7 +92,7 @@ class BaseClient:
|
|
|
90
92
|
timeout: Optional[int] = 600,
|
|
91
93
|
user_agent: Optional[str] = 'rucio-clients',
|
|
92
94
|
vo: Optional[str] = None,
|
|
93
|
-
logger: Logger = LOG) -> None:
|
|
95
|
+
logger: 'Logger' = LOG) -> None:
|
|
94
96
|
"""
|
|
95
97
|
Constructor of the BaseClient.
|
|
96
98
|
:param rucio_host: The address of the rucio server, if None it is read from the config file.
|
|
@@ -364,7 +366,7 @@ class BaseClient:
|
|
|
364
366
|
else:
|
|
365
367
|
return exception.RucioException, "%s: %s" % (exc_cls, exc_msg)
|
|
366
368
|
|
|
367
|
-
def _load_json_data(self, response: requests.Response) -> Generator[Any, Any, Any]:
|
|
369
|
+
def _load_json_data(self, response: requests.Response) -> 'Generator[Any, Any, Any]':
|
|
368
370
|
"""
|
|
369
371
|
Helper method to correctly load json data based on the content type of the http response.
|
|
370
372
|
|
|
@@ -29,11 +29,13 @@ from typing import TYPE_CHECKING, Any, Optional
|
|
|
29
29
|
|
|
30
30
|
from rucio import version
|
|
31
31
|
from rucio.client.client import Client
|
|
32
|
+
from rucio.common.checksum import CHECKSUM_ALGO_DICT, GLOBALLY_SUPPORTED_CHECKSUMS, PREFERRED_CHECKSUM, adler32
|
|
33
|
+
from rucio.common.client import detect_client_location
|
|
32
34
|
from rucio.common.config import config_get
|
|
33
35
|
from rucio.common.didtype import DID
|
|
34
36
|
from rucio.common.exception import InputValidationError, NoFilesDownloaded, NotAllFilesDownloaded, RucioException
|
|
35
37
|
from rucio.common.pcache import Pcache
|
|
36
|
-
from rucio.common.utils import
|
|
38
|
+
from rucio.common.utils import execute, extract_scope, generate_uuid, parse_replicas_from_file, parse_replicas_from_string, send_trace, sizefmt
|
|
37
39
|
from rucio.rse import rsemanager as rsemgr
|
|
38
40
|
|
|
39
41
|
if TYPE_CHECKING:
|
|
@@ -0,0 +1,324 @@
|
|
|
1
|
+
# Copyright European Organization for Nuclear Research (CERN) since 2012
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
import logging
|
|
16
|
+
import pydoc
|
|
17
|
+
import re
|
|
18
|
+
import subprocess
|
|
19
|
+
import sys
|
|
20
|
+
from datetime import datetime
|
|
21
|
+
from typing import TYPE_CHECKING, Any, Optional, Union
|
|
22
|
+
|
|
23
|
+
from rich import box
|
|
24
|
+
from rich.console import Console, JustifyMethod, RenderableType
|
|
25
|
+
from rich.logging import RichHandler
|
|
26
|
+
from rich.table import Table
|
|
27
|
+
from rich.text import Text
|
|
28
|
+
|
|
29
|
+
from rucio.common.config import config_get
|
|
30
|
+
|
|
31
|
+
if TYPE_CHECKING:
|
|
32
|
+
from collections.abc import Callable, Sequence
|
|
33
|
+
|
|
34
|
+
from rich.style import StyleType
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
MIN_CONSOLE_WIDTH = 80
|
|
38
|
+
MAX_TRACEBACK_WIDTH = 120 # Slightly higher than default width of rich.traceback (100).
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class CLITheme:
|
|
42
|
+
"""
|
|
43
|
+
Class to define styles for Rich widgets and prints in the CLI.
|
|
44
|
+
"""
|
|
45
|
+
TABLE_FMT = box.SQUARE
|
|
46
|
+
|
|
47
|
+
TEXT_HIGHLIGHT = 'grey50' # Used to highlight prints between tables, e.g. get_metadata or stat.
|
|
48
|
+
SUBHEADER_HIGHLIGHT = 'cyan' # Used to highlight prints between tables for a section, e.g. protocols or usage per account.
|
|
49
|
+
SPINNER = 'dots2'
|
|
50
|
+
SPINNER_STYLE = 'green'
|
|
51
|
+
|
|
52
|
+
JSON_STR = 'green'
|
|
53
|
+
JSON_NUM = 'bold cyan'
|
|
54
|
+
|
|
55
|
+
SUCCESS_ICON = '[bold green]\u2714[/]'
|
|
56
|
+
FAILURE_ICON = '[bold red]\u2717[/]'
|
|
57
|
+
|
|
58
|
+
LOG_THEMES = {
|
|
59
|
+
'logging.level.info': 'default',
|
|
60
|
+
'logging.level.warning': 'bold yellow',
|
|
61
|
+
'logging.level.debug': 'dim',
|
|
62
|
+
'logging.level.critical': 'default on red',
|
|
63
|
+
'repr.bool_true': 'green',
|
|
64
|
+
'repr.bool_false': 'red',
|
|
65
|
+
'log.time': 'turquoise4'
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
DID_TYPE = {
|
|
69
|
+
'CONTAINER': 'bold dodger_blue1',
|
|
70
|
+
'DATASET': 'bold orange3',
|
|
71
|
+
'FILE': 'bold default',
|
|
72
|
+
'COLLECTION': 'bold green',
|
|
73
|
+
'ALL': 'bold magenta',
|
|
74
|
+
'DERIVED': 'bold magenta'
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
BOOLEAN = {
|
|
78
|
+
'True': 'green',
|
|
79
|
+
'False': 'red'
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
RULE_STATE = {
|
|
83
|
+
'OK': 'bold green',
|
|
84
|
+
'REPLICATING': 'bold default',
|
|
85
|
+
'STUCK': 'bold orange3',
|
|
86
|
+
'WAITING APPROVAL': 'bold dodger_blue1',
|
|
87
|
+
'INJECT': 'bold medium_purple3',
|
|
88
|
+
'SUSPENDED': 'bold red'
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
RSE_TYPE = {
|
|
92
|
+
'DISK': 'bold dodger_blue1',
|
|
93
|
+
'TAPE': 'bold orange3',
|
|
94
|
+
'UNKNOWN': 'bold'
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
SUBSCRIPTION_STATE = {
|
|
98
|
+
'ACTIVE': 'bold green',
|
|
99
|
+
'INACTIVE': 'bold',
|
|
100
|
+
'NEW': 'bold dodger_blue1',
|
|
101
|
+
'UPDATED': 'bold green',
|
|
102
|
+
'BROKEN': 'bold red',
|
|
103
|
+
'UNKNOWN': 'bold orange3'
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
AVAILABILITY = {
|
|
107
|
+
'AVAILABLE': 'bold green',
|
|
108
|
+
'DELETED': 'bold',
|
|
109
|
+
'LOST': 'bold red',
|
|
110
|
+
'UNKNOWN': 'bold orange3'
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
ACCOUNT_STATUS = {
|
|
114
|
+
'ACTIVE': 'bold green',
|
|
115
|
+
'SUSPENDED': 'bold red',
|
|
116
|
+
'DELETED': 'bold'
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
REPLICA_STATE = {
|
|
120
|
+
'A': 'bold green',
|
|
121
|
+
'U': 'bold red',
|
|
122
|
+
'C': 'bold default',
|
|
123
|
+
'B': 'bold dodger_blue1',
|
|
124
|
+
'D': 'bold red',
|
|
125
|
+
'T': 'bold orange3'
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
ACCOUNT_TYPE = {
|
|
129
|
+
'USER': 'default',
|
|
130
|
+
'GROUP': 'medium_purple3',
|
|
131
|
+
'SERVICE': 'yellow'
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
def setup_rich_logger(
|
|
136
|
+
module_name: Optional[str] = None,
|
|
137
|
+
logger_name: Optional[str] = None,
|
|
138
|
+
logger_level: Optional[int] = None,
|
|
139
|
+
verbose: bool = False,
|
|
140
|
+
console: Optional[Console] = None
|
|
141
|
+
) -> logging.Logger:
|
|
142
|
+
"""
|
|
143
|
+
Factory method to set logger with RichHandler.
|
|
144
|
+
|
|
145
|
+
The function is a copy of the method in rucio.common.utils setup_logger() with minor changes.
|
|
146
|
+
|
|
147
|
+
:param module_name: __name__ of the module that is calling this method
|
|
148
|
+
:param logger_name: name of the logger, typically name of the module.
|
|
149
|
+
:param logger_level: if not given, fetched from config.
|
|
150
|
+
:param verbose: verbose option set in bin/rucio
|
|
151
|
+
:param console: Rich console object
|
|
152
|
+
:returns: logger with RichHandler
|
|
153
|
+
"""
|
|
154
|
+
# Helper method for cfg check.
|
|
155
|
+
def _force_cfg_log_level(cfg_option: str) -> bool:
|
|
156
|
+
cfg_forced_modules = config_get('logging', cfg_option, raise_exception=False, default=None, clean_cached=True, check_config_table=False)
|
|
157
|
+
if cfg_forced_modules and module_name is not None:
|
|
158
|
+
if re.match(str(cfg_forced_modules), module_name):
|
|
159
|
+
return True
|
|
160
|
+
return False
|
|
161
|
+
|
|
162
|
+
if not logger_name:
|
|
163
|
+
if not module_name:
|
|
164
|
+
logger_name = 'user'
|
|
165
|
+
else:
|
|
166
|
+
logger_name = module_name.split('.')[-1]
|
|
167
|
+
logger = logging.getLogger(logger_name)
|
|
168
|
+
|
|
169
|
+
# Extracting the log level.
|
|
170
|
+
if not logger_level:
|
|
171
|
+
logger_level = logging.INFO
|
|
172
|
+
if verbose:
|
|
173
|
+
logger_level = logging.DEBUG
|
|
174
|
+
|
|
175
|
+
# Overriding by the config.
|
|
176
|
+
cfg_levels = (logging.DEBUG, logging.INFO, logging.WARNING, logging.ERROR)
|
|
177
|
+
for level in cfg_levels:
|
|
178
|
+
cfg_opt = 'forceloglevel' + logging.getLevelName(level)
|
|
179
|
+
if _force_cfg_log_level(cfg_opt):
|
|
180
|
+
logger_level = level
|
|
181
|
+
|
|
182
|
+
logger.setLevel(logger_level)
|
|
183
|
+
|
|
184
|
+
def add_handler(logger: logging.Logger,
|
|
185
|
+
console: Optional[Console] = None,
|
|
186
|
+
verbose: bool = False) -> None:
|
|
187
|
+
|
|
188
|
+
def time_formatter(timestamp: datetime) -> Text:
|
|
189
|
+
return Text(f"[{timestamp.isoformat(sep=' ', timespec='milliseconds')}]")
|
|
190
|
+
|
|
191
|
+
console = console or Console()
|
|
192
|
+
handler = RichHandler(rich_tracebacks=True, markup=True, show_path=verbose, show_time=verbose, console=console, tracebacks_width=min(console.width, MAX_TRACEBACK_WIDTH),
|
|
193
|
+
tracebacks_word_wrap=True, log_time_format=time_formatter)
|
|
194
|
+
logger.addHandler(handler)
|
|
195
|
+
|
|
196
|
+
# Setting handler and formatter.
|
|
197
|
+
if not logger.handlers:
|
|
198
|
+
add_handler(logger, console, verbose)
|
|
199
|
+
|
|
200
|
+
return logger
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
def _format_value(value: Optional[Union[RenderableType, int, float, bool, datetime]] = None) -> RenderableType:
|
|
204
|
+
"""
|
|
205
|
+
Formats the value based on its type for Rich Table.
|
|
206
|
+
|
|
207
|
+
A helper function to format the value to Rich RenderableType.
|
|
208
|
+
|
|
209
|
+
:param value: value to format
|
|
210
|
+
:returns: formatted value
|
|
211
|
+
"""
|
|
212
|
+
if value is None or str(value) == 'None':
|
|
213
|
+
return ''
|
|
214
|
+
if isinstance(value, bool):
|
|
215
|
+
return CLITheme.BOOLEAN[str(value)]
|
|
216
|
+
if isinstance(value, (int, float, datetime)):
|
|
217
|
+
return str(value)
|
|
218
|
+
return value
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
def generate_table(
|
|
222
|
+
rows: 'Sequence[Sequence[Union[RenderableType, int, float, bool, datetime]]]',
|
|
223
|
+
headers: Optional['Sequence[RenderableType]'] = None,
|
|
224
|
+
row_styles: Optional['Sequence[StyleType]'] = None,
|
|
225
|
+
col_alignments: Optional[list[JustifyMethod]] = None,
|
|
226
|
+
table_format: box.Box = CLITheme.TABLE_FMT,
|
|
227
|
+
) -> Table:
|
|
228
|
+
"""
|
|
229
|
+
Generates a Rich Table object from given input rows.
|
|
230
|
+
|
|
231
|
+
The elements in each row can be either plain strings or Rich renderable objects.
|
|
232
|
+
Passing strings will display them as simple text, while using Rich objects
|
|
233
|
+
allows you to introduce additional structure, styling, and widgets (e.g. Text, Trees) into
|
|
234
|
+
the table. Strings with style markup will be rendered as styled text.
|
|
235
|
+
|
|
236
|
+
:param table_format: style of the table
|
|
237
|
+
:param headers: list of headers
|
|
238
|
+
:param rows: list of rows
|
|
239
|
+
:param col_alignments: list of column alignments
|
|
240
|
+
:param row_styles: list of row styles
|
|
241
|
+
:returns: a Rich Table object
|
|
242
|
+
"""
|
|
243
|
+
table = Table(box=table_format, show_header=headers is not None and len(headers) > 0)
|
|
244
|
+
table.row_styles = row_styles or ['none', 'dim']
|
|
245
|
+
|
|
246
|
+
if len(rows) == 0:
|
|
247
|
+
if headers:
|
|
248
|
+
for header in headers:
|
|
249
|
+
table.add_column(header)
|
|
250
|
+
return table
|
|
251
|
+
|
|
252
|
+
# Auto-detect on first row, numerical values on the right.
|
|
253
|
+
col_alignments = col_alignments or ['right' if str(col).isnumeric() else 'left' for col in rows[0]]
|
|
254
|
+
headers = headers or [''] * len(rows[0])
|
|
255
|
+
while len(headers) > len(col_alignments):
|
|
256
|
+
col_alignments.append('left')
|
|
257
|
+
|
|
258
|
+
for header, alignment in zip(headers, col_alignments):
|
|
259
|
+
table.add_column(header, overflow='fold', justify=alignment)
|
|
260
|
+
|
|
261
|
+
for row in rows:
|
|
262
|
+
row = [_format_value(col) for col in row]
|
|
263
|
+
table.add_row(*row)
|
|
264
|
+
return table
|
|
265
|
+
|
|
266
|
+
|
|
267
|
+
def print_output(
|
|
268
|
+
*output: Any,
|
|
269
|
+
console: Console,
|
|
270
|
+
no_pager: bool = False
|
|
271
|
+
) -> None:
|
|
272
|
+
"""
|
|
273
|
+
Prints the objects using the specified Rich console object. Optionally disables the pager if specified.
|
|
274
|
+
|
|
275
|
+
The function works similarly to Rich's `console.print()` method but provides additional control over the pager feature.
|
|
276
|
+
|
|
277
|
+
:param output: objects to print to the terminal
|
|
278
|
+
:param console: Rich console object
|
|
279
|
+
:param no_pager: flag to disable the pager
|
|
280
|
+
"""
|
|
281
|
+
if console.is_terminal:
|
|
282
|
+
if no_pager:
|
|
283
|
+
console.print(*output)
|
|
284
|
+
else:
|
|
285
|
+
console.width = sys.maxsize # Overwrite auto-detected console width.
|
|
286
|
+
console.begin_capture()
|
|
287
|
+
console.print(*output)
|
|
288
|
+
else:
|
|
289
|
+
console.width = sys.maxsize
|
|
290
|
+
console.print(*output)
|
|
291
|
+
|
|
292
|
+
|
|
293
|
+
def get_cli_config() -> str:
|
|
294
|
+
"""
|
|
295
|
+
Returns the CLI type from the config file.
|
|
296
|
+
|
|
297
|
+
:returns: CLI type (Rich or tabulate)
|
|
298
|
+
"""
|
|
299
|
+
cli_type = config_get('experimental', 'cli', raise_exception=False, default='tabulate').lower()
|
|
300
|
+
if cli_type not in ['rich', 'tabulate']:
|
|
301
|
+
cli_type = 'tabulate'
|
|
302
|
+
return cli_type
|
|
303
|
+
|
|
304
|
+
|
|
305
|
+
def get_pager() -> 'Callable[[str], None]':
|
|
306
|
+
"""
|
|
307
|
+
Returns the pager function based on the terminal availability.
|
|
308
|
+
|
|
309
|
+
:returns: pager
|
|
310
|
+
"""
|
|
311
|
+
default_pager = 'less'
|
|
312
|
+
try:
|
|
313
|
+
result = subprocess.run([default_pager], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
|
314
|
+
less_available = result.returncode == 0
|
|
315
|
+
except Exception:
|
|
316
|
+
less_available = False
|
|
317
|
+
|
|
318
|
+
def less_pager_function(text: str) -> None:
|
|
319
|
+
"""Use the 'less' pager with -FRSXKM options."""
|
|
320
|
+
pydoc.pipepager(text, f'{default_pager} -FRSXKM')
|
|
321
|
+
|
|
322
|
+
if less_available:
|
|
323
|
+
return less_pager_function
|
|
324
|
+
return pydoc.pager
|
|
@@ -24,7 +24,7 @@ from rucio.common.utils import build_url
|
|
|
24
24
|
if TYPE_CHECKING:
|
|
25
25
|
from collections.abc import Iterable, Iterator
|
|
26
26
|
|
|
27
|
-
from rucio.common.constants import
|
|
27
|
+
from rucio.common.constants import RSE_ALL_SUPPORTED_PROTOCOL_OPERATIONS_LITERAL, RSE_SUPPORTED_PROTOCOL_DOMAINS_LITERAL, SUPPORTED_PROTOCOLS_LITERAL
|
|
28
28
|
|
|
29
29
|
|
|
30
30
|
class RSEClient(BaseClient):
|
|
@@ -238,7 +238,7 @@ class RSEClient(BaseClient):
|
|
|
238
238
|
self,
|
|
239
239
|
rse: str,
|
|
240
240
|
protocol_domain: "RSE_SUPPORTED_PROTOCOL_DOMAINS_LITERAL" = 'ALL',
|
|
241
|
-
operation: Optional["
|
|
241
|
+
operation: Optional["RSE_ALL_SUPPORTED_PROTOCOL_OPERATIONS_LITERAL"] = None,
|
|
242
242
|
default: bool = False,
|
|
243
243
|
scheme: Optional['SUPPORTED_PROTOCOLS_LITERAL'] = None
|
|
244
244
|
) -> Any:
|
|
@@ -287,7 +287,7 @@ class RSEClient(BaseClient):
|
|
|
287
287
|
rse: str,
|
|
288
288
|
lfns: 'Iterable[str]',
|
|
289
289
|
protocol_domain: 'RSE_SUPPORTED_PROTOCOL_DOMAINS_LITERAL' = 'ALL',
|
|
290
|
-
operation: Optional['
|
|
290
|
+
operation: Optional['RSE_ALL_SUPPORTED_PROTOCOL_OPERATIONS_LITERAL'] = None,
|
|
291
291
|
scheme: Optional['SUPPORTED_PROTOCOLS_LITERAL'] = None
|
|
292
292
|
) -> dict[str, str]:
|
|
293
293
|
"""
|
|
@@ -409,7 +409,7 @@ class RSEClient(BaseClient):
|
|
|
409
409
|
self,
|
|
410
410
|
rse: str,
|
|
411
411
|
domain: 'RSE_SUPPORTED_PROTOCOL_DOMAINS_LITERAL',
|
|
412
|
-
operation: '
|
|
412
|
+
operation: 'RSE_ALL_SUPPORTED_PROTOCOL_OPERATIONS_LITERAL',
|
|
413
413
|
scheme_a: 'SUPPORTED_PROTOCOLS_LITERAL',
|
|
414
414
|
scheme_b: 'SUPPORTED_PROTOCOLS_LITERAL'
|
|
415
415
|
) -> bool:
|