rucio-clients 34.2.0__tar.gz → 34.4.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-34.2.0 → rucio_clients-34.4.0}/PKG-INFO +1 -1
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/bin/rucio +2 -2
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/bin/rucio-admin +11 -10
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/lib/rucio/client/accountclient.py +1 -1
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/lib/rucio/client/baseclient.py +7 -6
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/lib/rucio/client/didclient.py +1 -1
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/lib/rucio/client/downloadclient.py +67 -18
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/lib/rucio/client/replicaclient.py +13 -1
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/lib/rucio/client/rseclient.py +5 -5
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/lib/rucio/client/ruleclient.py +2 -1
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/lib/rucio/client/uploadclient.py +6 -5
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/lib/rucio/common/cache.py +3 -1
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/lib/rucio/common/config.py +37 -37
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/lib/rucio/common/constants.py +61 -1
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/lib/rucio/common/didtype.py +23 -20
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/lib/rucio/common/pcache.py +5 -5
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/lib/rucio/common/plugins.py +10 -9
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/lib/rucio/common/policy.py +4 -3
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/lib/rucio/common/schema/__init__.py +11 -7
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/lib/rucio/common/types.py +28 -1
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/lib/rucio/common/utils.py +21 -22
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/lib/rucio/rse/protocols/bittorrent.py +1 -1
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/lib/rucio/rse/protocols/cache.py +1 -1
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/lib/rucio/rse/protocols/dummy.py +1 -1
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/lib/rucio/rse/protocols/gfal.py +7 -7
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/lib/rucio/rse/protocols/globus.py +6 -5
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/lib/rucio/rse/protocols/gsiftp.py +2 -2
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/lib/rucio/rse/protocols/http_cache.py +1 -1
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/lib/rucio/rse/protocols/mock.py +1 -1
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/lib/rucio/rse/protocols/ngarc.py +1 -1
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/lib/rucio/rse/protocols/posix.py +8 -8
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/lib/rucio/rse/protocols/protocol.py +13 -34
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/lib/rucio/rse/protocols/rclone.py +4 -4
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/lib/rucio/rse/protocols/rfio.py +4 -4
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/lib/rucio/rse/protocols/srm.py +8 -8
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/lib/rucio/rse/protocols/ssh.py +6 -6
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/lib/rucio/rse/protocols/storm.py +2 -2
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/lib/rucio/rse/protocols/webdav.py +12 -8
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/lib/rucio/rse/protocols/xrootd.py +4 -4
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/lib/rucio/vcsversion.py +3 -3
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/lib/rucio_clients.egg-info/SOURCES.txt +0 -3
- rucio_clients-34.4.0/pyproject.toml +132 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/requirements.txt +1 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/tests/test_account.py +3 -3
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/tests/test_authentication.py +3 -5
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/tests/test_bad_replica.py +1 -1
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/tests/test_bin_rucio.py +41 -41
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/tests/test_config.py +2 -2
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/tests/test_conveyor.py +26 -25
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/tests/test_conveyor_submitter.py +6 -5
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/tests/test_credential.py +2 -1
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/tests/test_dataset_replicas.py +1 -1
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/tests/test_dumper_data_model.py +2 -2
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/tests/test_identity.py +2 -2
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/tests/test_import_export.py +6 -5
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/tests/test_judge_repairer.py +1 -1
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/tests/test_multi_vo.py +6 -5
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/tests/test_oidc.py +9 -9
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/tests/test_preparer.py +7 -6
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/tests/test_reaper.py +1 -1
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/tests/test_replica.py +7 -6
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/tests/test_replica_recoverer.py +77 -4
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/tests/test_replica_sorting.py +3 -2
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/tests/test_request.py +6 -5
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/tests/test_root_proxy.py +3 -2
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/tests/test_rse.py +4 -3
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/tests/test_rse_expression_parser.py +2 -2
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/tests/test_rse_lfn2path.py +1 -1
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/tests/test_rule.py +8 -7
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/tests/test_scope.py +2 -2
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/tests/test_subscription.py +4 -3
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/tests/test_transfer_plugins.py +1 -1
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/tests/test_upload.py +2 -1
- rucio_clients-34.2.0/lib/rucio/common/schema/cms.py +0 -477
- rucio_clients-34.2.0/lib/rucio/common/schema/lsst.py +0 -422
- rucio_clients-34.2.0/pyproject.toml +0 -61
- rucio_clients-34.2.0/tests/test_schema_cms.py +0 -229
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/AUTHORS.rst +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/ChangeLog +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/LICENSE +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/MANIFEST.in +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/README.rst +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/etc/rse-accounts.cfg.template +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/etc/rucio.cfg.atlas.client.template +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/etc/rucio.cfg.template +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/lib/rucio/__init__.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/lib/rucio/alembicrevision.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/lib/rucio/client/__init__.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/lib/rucio/client/accountlimitclient.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/lib/rucio/client/client.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/lib/rucio/client/configclient.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/lib/rucio/client/credentialclient.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/lib/rucio/client/diracclient.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/lib/rucio/client/exportclient.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/lib/rucio/client/fileclient.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/lib/rucio/client/importclient.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/lib/rucio/client/lifetimeclient.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/lib/rucio/client/lockclient.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/lib/rucio/client/metaconventionsclient.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/lib/rucio/client/pingclient.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/lib/rucio/client/requestclient.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/lib/rucio/client/scopeclient.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/lib/rucio/client/subscriptionclient.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/lib/rucio/client/touchclient.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/lib/rucio/common/__init__.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/lib/rucio/common/constraints.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/lib/rucio/common/exception.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/lib/rucio/common/extra.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/lib/rucio/common/logging.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/lib/rucio/common/schema/atlas.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/lib/rucio/common/schema/belleii.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/lib/rucio/common/schema/domatpc.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/lib/rucio/common/schema/escape.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/lib/rucio/common/schema/generic.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/lib/rucio/common/schema/generic_multi_vo.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/lib/rucio/common/schema/icecube.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/lib/rucio/common/stomp_utils.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/lib/rucio/common/stopwatch.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/lib/rucio/common/test_rucio_server.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/lib/rucio/rse/__init__.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/lib/rucio/rse/protocols/__init__.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/lib/rucio/rse/rsemanager.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/lib/rucio/version.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/pylintrc +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/setup.cfg +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/setup.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/setuputil.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/tests/test_abacus_account.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/tests/test_abacus_collection_replica.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/tests/test_abacus_rse.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/tests/test_account_limits.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/tests/test_api_external_representation.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/tests/test_archive.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/tests/test_auditor.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/tests/test_auditor_hdfs.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/tests/test_auditor_srmdumps.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/tests/test_automatix.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/tests/test_bb8.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/tests/test_belleii.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/tests/test_boolean.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/tests/test_clients.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/tests/test_common_types.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/tests/test_counter.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/tests/test_curl.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/tests/test_daemons.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/tests/test_db.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/tests/test_did.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/tests/test_did_meta_plugins.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/tests/test_didtype.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/tests/test_download.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/tests/test_dumper.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/tests/test_dumper_consistency.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/tests/test_dumper_path_parsing.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/tests/test_filter_engine.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/tests/test_heartbeat.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/tests/test_hermes.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/tests/test_impl_upload_download.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/tests/test_judge_cleaner.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/tests/test_judge_evaluator.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/tests/test_judge_injector.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/tests/test_lifetime.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/tests/test_message.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/tests/test_meta_conventions.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/tests/test_meta_did.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/tests/test_module_import.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/tests/test_monitor.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/tests/test_naming_convention.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/tests/test_oauthmanager.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/tests/test_permission.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/tests/test_pfns.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/tests/test_ping.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/tests/test_qos.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/tests/test_quarantined_replica.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/tests/test_redirect.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/tests/test_rse_protocol_gfal2.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/tests/test_rse_protocol_gfal2_impl.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/tests/test_rse_protocol_posix.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/tests/test_rse_protocol_rclone.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/tests/test_rse_protocol_rsync.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/tests/test_rse_protocol_srm.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/tests/test_rse_protocol_ssh.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/tests/test_rse_protocol_webdav.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/tests/test_rse_protocol_xrootd.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/tests/test_rse_selector.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/tests/test_rucio_server.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/tests/test_throttler.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/tests/test_tpc.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/tests/test_trace.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/tests/test_transfer.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/tests/test_undertaker.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/tests/test_utils.py +0 -0
- {rucio_clients-34.2.0 → rucio_clients-34.4.0}/tools/merge_rucio_configs.py +0 -0
|
@@ -166,7 +166,7 @@ def exception_handler(function):
|
|
|
166
166
|
used_account = '%s (from rucio.cfg)' % config_get('client', 'account')
|
|
167
167
|
except:
|
|
168
168
|
pass
|
|
169
|
-
try: # are we
|
|
169
|
+
try: # are we overridden by the environment?
|
|
170
170
|
used_account = '%s (from RUCIO_ACCOUNT)' % os.environ['RUCIO_ACCOUNT']
|
|
171
171
|
except:
|
|
172
172
|
pass
|
|
@@ -1550,7 +1550,7 @@ def list_rse_attributes(args):
|
|
|
1550
1550
|
"""
|
|
1551
1551
|
client = get_client(args)
|
|
1552
1552
|
attributes = client.list_rse_attributes(rse=args.rse)
|
|
1553
|
-
table = [(k + ':', str(v)) for (k, v) in sorted(attributes.items())] # columns
|
|
1553
|
+
table = [(k + ':', str(v)) for (k, v) in sorted(attributes.items())] # columns have mixed datatypes
|
|
1554
1554
|
print(tabulate(table, tablefmt='plain', disable_numparse=True)) # disabling number parsing
|
|
1555
1555
|
return SUCCESS
|
|
1556
1556
|
|
|
@@ -33,6 +33,7 @@ from tabulate import tabulate
|
|
|
33
33
|
from rucio import version
|
|
34
34
|
from rucio.client import Client
|
|
35
35
|
from rucio.common.config import config_get
|
|
36
|
+
from rucio.common.constants import RseAttr
|
|
36
37
|
from rucio.common.exception import (
|
|
37
38
|
AccessDenied,
|
|
38
39
|
AccountNotFound,
|
|
@@ -385,7 +386,7 @@ def set_limits(args):
|
|
|
385
386
|
try:
|
|
386
387
|
byte_limit = int(limit_input)
|
|
387
388
|
except ValueError:
|
|
388
|
-
logger.error('The limit could not be set. Either you misspelled infinity or your input could not be converted to integer or you used a wrong pattern. Please use a format like 10GB with B,KB,MB,GB,TB,PB as units (not case
|
|
389
|
+
logger.error('The limit could not be set. Either you misspelled infinity or your input could not be converted to integer or you used a wrong pattern. Please use a format like 10GB with B,KB,MB,GB,TB,PB as units (not case sensitive)')
|
|
389
390
|
return FAILURE
|
|
390
391
|
|
|
391
392
|
client.set_account_limit(account=args.account, rse=args.rse, bytes_=byte_limit, locality=locality)
|
|
@@ -1244,7 +1245,7 @@ def list_pfns(args):
|
|
|
1244
1245
|
if not rse_info['deterministic']:
|
|
1245
1246
|
logger.warning('This is a non-deterministic site, so the real PFN might be different from the on suggested')
|
|
1246
1247
|
rse_attr = client.list_rse_attributes(rse)
|
|
1247
|
-
naming_convention = rse_attr.get(
|
|
1248
|
+
naming_convention = rse_attr.get(RseAttr.NAMING_CONVENTION, None)
|
|
1248
1249
|
parents = [did for did in client.list_parent_dids(scope, name)]
|
|
1249
1250
|
if len(parents) > 1:
|
|
1250
1251
|
logger.warning('The file has multiple parents')
|
|
@@ -1383,7 +1384,7 @@ def get_parser():
|
|
|
1383
1384
|
oparser.add_argument('--oidc-refresh-lifetime', dest='oidc_refresh_lifetime', default=None, help='Max lifetime in hours for this an access token will be refreshed by asynchronous Rucio daemon. '
|
|
1384
1385
|
+ 'If not specified, refresh will be stopped after 4 days. This option is effective only if --oidc-scope includes offline_access scope for a refresh token to be granted to Rucio.') # NOQA: W503
|
|
1385
1386
|
oparser.add_argument('--oidc-issuer', dest='oidc_issuer', default=None,
|
|
1386
|
-
help='Defines which Identity Provider is
|
|
1387
|
+
help='Defines which Identity Provider is going to be used. The issuer string must correspond '
|
|
1387
1388
|
+ 'to the keys configured in the /etc/idpsecrets.json auth server configuration file.') # NOQA: W503
|
|
1388
1389
|
|
|
1389
1390
|
# Options for the x509 auth_strategy
|
|
@@ -1432,7 +1433,7 @@ def get_parser():
|
|
|
1432
1433
|
'"""""""""""""\n'
|
|
1433
1434
|
'::\n'
|
|
1434
1435
|
'\n'
|
|
1435
|
-
' $ rucio-admin account list --type \
|
|
1436
|
+
' $ rucio-admin account list --type USER\n'
|
|
1436
1437
|
'\n')
|
|
1437
1438
|
list_account_parser.add_argument('--type', dest='account_type', action='store', help='Account Type (USER, GROUP, SERVICE)')
|
|
1438
1439
|
list_account_parser.add_argument('--id', dest='identity', action='store', help='Identity (e.g. DN)')
|
|
@@ -1708,7 +1709,7 @@ def get_parser():
|
|
|
1708
1709
|
' $ rucio-admin identity delete --account jdoe --type X509 --id \'CN=Joe Doe,CN=707658,CN=jdoe,OU=Users,OU=Organic Units,DC=cern,DC=ch\'\n'
|
|
1709
1710
|
' Deleted identity: CN=Joe Doe,CN=707658,CN=jdoe,OU=Users,OU=Organic Units,DC=cern,DC=ch\n'
|
|
1710
1711
|
'\n'
|
|
1711
|
-
'Note: if the identity was
|
|
1712
|
+
'Note: if the identity was accidentally deleted, use add option.\n'
|
|
1712
1713
|
'\n')
|
|
1713
1714
|
identity_delete_parser.set_defaults(which='identity_delete')
|
|
1714
1715
|
identity_delete_parser.add_argument('--account', dest='account', action='store', help='Account name', required=True)
|
|
@@ -1956,7 +1957,7 @@ def get_parser():
|
|
|
1956
1957
|
' $ rucio-admin rse add-protocol --hostname jdoes.test.org --scheme gsiftp --prefix \'/atlasdatadisk/rucio/\' --port 8443 JDOE_DATADISK\n'
|
|
1957
1958
|
'\n'
|
|
1958
1959
|
'Note: no printed stdout.\n'
|
|
1959
|
-
'Note: examples of optional
|
|
1960
|
+
'Note: examples of optional parameters::\n'
|
|
1960
1961
|
'\n'
|
|
1961
1962
|
' --space-token DATADISK\n'
|
|
1962
1963
|
' --web-service-path \'/srm/managerv2?SFN=\'\n'
|
|
@@ -2110,7 +2111,7 @@ def get_parser():
|
|
|
2110
2111
|
|
|
2111
2112
|
# The config subparser
|
|
2112
2113
|
config_parser = subparsers.add_parser('config',
|
|
2113
|
-
help='Configuration methods. The global configuration of data
|
|
2114
|
+
help='Configuration methods. The global configuration of data management system can by modified.',
|
|
2114
2115
|
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
2115
2116
|
epilog='''e.g. quotas, daemons, rses''')
|
|
2116
2117
|
config_subparser = config_parser.add_subparsers(dest='config_subcommand', **required_arg)
|
|
@@ -2311,9 +2312,9 @@ def get_parser():
|
|
|
2311
2312
|
declare_bad_file_replicas_parser.add_argument('--inputfile', dest='inputfile', nargs='?', action='store', help='File containing list of bad items')
|
|
2312
2313
|
declare_bad_file_replicas_parser.add_argument('--allow-collection', dest='allow_collection', action='store_true', help='Allow passing a collection DID as bad item')
|
|
2313
2314
|
|
|
2314
|
-
declare_bad_file_replicas_parser.add_argument('--lfns', dest='lfns', nargs='?', action='store', help='File
|
|
2315
|
-
declare_bad_file_replicas_parser.add_argument('--scope', dest='scope', nargs='?', action='store', help='Common scope for bad replicas
|
|
2316
|
-
declare_bad_file_replicas_parser.add_argument('--rse', dest='rse', nargs='?', action='store', help='Common RSE for bad replicas
|
|
2315
|
+
declare_bad_file_replicas_parser.add_argument('--lfns', dest='lfns', nargs='?', action='store', help='File containing list of LFNs for bad replicas. Requires --rse and --scope')
|
|
2316
|
+
declare_bad_file_replicas_parser.add_argument('--scope', dest='scope', nargs='?', action='store', help='Common scope for bad replicas specified with LFN list, ignored without --lfns')
|
|
2317
|
+
declare_bad_file_replicas_parser.add_argument('--rse', dest='rse', nargs='?', action='store', help='Common RSE for bad replicas specified with LFN list, ignored without --lfns')
|
|
2317
2318
|
|
|
2318
2319
|
# The declare-temporary-unavailable command
|
|
2319
2320
|
declare_temporary_unavailable_replicas_parser = rep_subparser.add_parser('declare-temporary-unavailable',
|
|
@@ -112,7 +112,7 @@ class AccountClient(BaseClient):
|
|
|
112
112
|
|
|
113
113
|
:param type: The account type
|
|
114
114
|
:param identity: The identity key name. For example x509 DN, or a username.
|
|
115
|
-
:param filters: A
|
|
115
|
+
:param filters: A dictionary key:account attribute to use for the filtering
|
|
116
116
|
|
|
117
117
|
:return: a list containing account info dictionary for all rucio accounts.
|
|
118
118
|
:raises AccountNotFound: if account doesn't exist.
|
|
@@ -22,12 +22,13 @@ import os
|
|
|
22
22
|
import secrets
|
|
23
23
|
import sys
|
|
24
24
|
import time
|
|
25
|
+
from collections.abc import Generator
|
|
25
26
|
from configparser import NoOptionError, NoSectionError
|
|
26
27
|
from logging import Logger
|
|
27
28
|
from os import environ, fdopen, geteuid, makedirs, path
|
|
28
29
|
from shutil import move
|
|
29
30
|
from tempfile import mkstemp
|
|
30
|
-
from typing import Any,
|
|
31
|
+
from typing import Any, Optional
|
|
31
32
|
from urllib.parse import urlparse
|
|
32
33
|
|
|
33
34
|
import requests
|
|
@@ -76,8 +77,8 @@ class BaseClient:
|
|
|
76
77
|
|
|
77
78
|
AUTH_RETRIES, REQUEST_RETRIES = 2, 3
|
|
78
79
|
TOKEN_PATH_PREFIX = get_tmp_dir() + '/.rucio_'
|
|
79
|
-
TOKEN_PREFIX = 'auth_token_'
|
|
80
|
-
TOKEN_EXP_PREFIX = 'auth_token_exp_'
|
|
80
|
+
TOKEN_PREFIX = 'auth_token_' # noqa: S105
|
|
81
|
+
TOKEN_EXP_PREFIX = 'auth_token_exp_' # noqa: S105
|
|
81
82
|
|
|
82
83
|
def __init__(self,
|
|
83
84
|
rucio_host: Optional[str] = None,
|
|
@@ -235,7 +236,7 @@ class BaseClient:
|
|
|
235
236
|
if self.auth_type == 'oidc':
|
|
236
237
|
if not creds:
|
|
237
238
|
creds = {}
|
|
238
|
-
# if there are
|
|
239
|
+
# if there are default values, check if rucio.cfg does not specify them, otherwise put default
|
|
239
240
|
if 'oidc_refresh_lifetime' not in creds or creds['oidc_refresh_lifetime'] is None:
|
|
240
241
|
creds['oidc_refresh_lifetime'] = config_get('client', 'oidc_refresh_lifetime', False, None)
|
|
241
242
|
if 'oidc_issuer' not in creds or creds['oidc_issuer'] is None:
|
|
@@ -615,7 +616,7 @@ class BaseClient:
|
|
|
615
616
|
|
|
616
617
|
else:
|
|
617
618
|
print("\nAccording to the OAuth2/OIDC standard you should NOT be sharing \n"
|
|
618
|
-
+ "your password with any 3rd party
|
|
619
|
+
+ "your password with any 3rd party application, therefore, \n" # NOQA: W503
|
|
619
620
|
+ "we strongly discourage you from following this --oidc-auto approach.") # NOQA: W503
|
|
620
621
|
print("-------------------------------------------------------------------------")
|
|
621
622
|
auth_res = self._send_request(auth_url, get_token=True)
|
|
@@ -658,7 +659,7 @@ class BaseClient:
|
|
|
658
659
|
|
|
659
660
|
self.auth_token = result.headers['x-rucio-auth-token']
|
|
660
661
|
if self.auth_oidc_refresh_active:
|
|
661
|
-
self.logger.debug("
|
|
662
|
+
self.logger.debug("Resetting the token expiration epoch file content.")
|
|
662
663
|
# reset the token expiration epoch file content
|
|
663
664
|
# at new CLI OIDC authentication
|
|
664
665
|
self.token_exp_epoch = None
|
|
@@ -47,7 +47,7 @@ class DIDClient(BaseClient):
|
|
|
47
47
|
path = '/'.join([self.DIDS_BASEURL, quote_plus(scope), 'dids', 'search'])
|
|
48
48
|
|
|
49
49
|
# stringify dates.
|
|
50
|
-
if isinstance(filters, dict): # backwards
|
|
50
|
+
if isinstance(filters, dict): # backwards compatibility for filters as single {}
|
|
51
51
|
filters = [filters]
|
|
52
52
|
for or_group in filters:
|
|
53
53
|
for key, value in or_group.items():
|
|
@@ -25,6 +25,7 @@ import subprocess
|
|
|
25
25
|
import time
|
|
26
26
|
from queue import Empty, Queue, deque
|
|
27
27
|
from threading import Thread
|
|
28
|
+
from typing import Any, Optional
|
|
28
29
|
|
|
29
30
|
from rucio import version
|
|
30
31
|
from rucio.client.client import Client
|
|
@@ -174,7 +175,14 @@ class DownloadClient:
|
|
|
174
175
|
self.extraction_tools.append(BaseExtractionTool('tar', '--version', extract_args, logger=self.logger))
|
|
175
176
|
self.extract_scope_convention = config_get('common', 'extract_scope', False, None)
|
|
176
177
|
|
|
177
|
-
def download_pfns(
|
|
178
|
+
def download_pfns(
|
|
179
|
+
self,
|
|
180
|
+
items: list[dict[str, Any]],
|
|
181
|
+
num_threads: int = 2,
|
|
182
|
+
trace_custom_fields: Optional[dict[str, Any]] = None,
|
|
183
|
+
traces_copy_out: Optional[list[dict[str, Any]]] = None,
|
|
184
|
+
deactivate_file_download_exceptions: bool = False
|
|
185
|
+
) -> list[dict[str, Any]]:
|
|
178
186
|
"""
|
|
179
187
|
Download items with a given PFN. This function can only download files, no datasets.
|
|
180
188
|
|
|
@@ -202,6 +210,7 @@ class DownloadClient:
|
|
|
202
210
|
:raises NotAllFilesDownloaded: if not all files could be downloaded
|
|
203
211
|
:raises RucioException: if something unexpected went wrong during the download
|
|
204
212
|
"""
|
|
213
|
+
trace_custom_fields = trace_custom_fields or {}
|
|
205
214
|
logger = self.logger
|
|
206
215
|
trace_custom_fields['uuid'] = generate_uuid()
|
|
207
216
|
|
|
@@ -250,8 +259,15 @@ class DownloadClient:
|
|
|
250
259
|
|
|
251
260
|
return self._check_output(output_items, deactivate_file_download_exceptions=deactivate_file_download_exceptions)
|
|
252
261
|
|
|
253
|
-
def download_dids(
|
|
254
|
-
|
|
262
|
+
def download_dids(
|
|
263
|
+
self,
|
|
264
|
+
items: list[dict[str, Any]],
|
|
265
|
+
num_threads: int = 2,
|
|
266
|
+
trace_custom_fields: Optional[dict[str, Any]] = None,
|
|
267
|
+
traces_copy_out: Optional[list[dict[str, Any]]] = None,
|
|
268
|
+
deactivate_file_download_exceptions: bool = False,
|
|
269
|
+
sort: Optional[str] = None
|
|
270
|
+
) -> list[dict[str, Any]]:
|
|
255
271
|
"""
|
|
256
272
|
Download items with given DIDs. This function can also download datasets and wildcarded DIDs.
|
|
257
273
|
|
|
@@ -265,7 +281,7 @@ class DownloadClient:
|
|
|
265
281
|
force_scheme - Optional: force a specific scheme to download this item. (Default: None)
|
|
266
282
|
base_dir - Optional: base directory where the downloaded files will be stored. (Default: '.')
|
|
267
283
|
no_subdir - Optional: If true, files are written directly into base_dir. (Default: False)
|
|
268
|
-
nrandom - Optional: if the DID addresses a dataset, nrandom files will be randomly
|
|
284
|
+
nrandom - Optional: if the DID addresses a dataset, nrandom files will be randomly chosen for download from the dataset
|
|
269
285
|
ignore_checksum - Optional: If true, skips the checksum validation between the downloaded file and the rucio catalouge. (Default: False)
|
|
270
286
|
transfer_timeout - Optional: Timeout time for the download protocols. (Default: None)
|
|
271
287
|
transfer_speed_timeout - Optional: Minimum allowed transfer speed (in KBps). Ignored if transfer_timeout set. Otherwise, used to compute default timeout (Default: 500)
|
|
@@ -286,6 +302,7 @@ class DownloadClient:
|
|
|
286
302
|
:raises NotAllFilesDownloaded: if not all files could be downloaded
|
|
287
303
|
:raises RucioException: if something unexpected went wrong during the download
|
|
288
304
|
"""
|
|
305
|
+
trace_custom_fields = trace_custom_fields or {}
|
|
289
306
|
logger = self.logger
|
|
290
307
|
trace_custom_fields['uuid'] = generate_uuid()
|
|
291
308
|
|
|
@@ -304,7 +321,15 @@ class DownloadClient:
|
|
|
304
321
|
|
|
305
322
|
return self._check_output(output_items, deactivate_file_download_exceptions=deactivate_file_download_exceptions)
|
|
306
323
|
|
|
307
|
-
def download_from_metalink_file(
|
|
324
|
+
def download_from_metalink_file(
|
|
325
|
+
self,
|
|
326
|
+
item: dict[str, Any],
|
|
327
|
+
metalink_file_path: str,
|
|
328
|
+
num_threads: int = 2,
|
|
329
|
+
trace_custom_fields: Optional[dict[str, Any]] = None,
|
|
330
|
+
traces_copy_out: Optional[list[dict[str, Any]]] = None,
|
|
331
|
+
deactivate_file_download_exceptions: bool = False
|
|
332
|
+
) -> list[dict[str, Any]]:
|
|
308
333
|
"""
|
|
309
334
|
Download items using a given metalink file.
|
|
310
335
|
|
|
@@ -327,6 +352,7 @@ class DownloadClient:
|
|
|
327
352
|
:raises NotAllFilesDownloaded: if not all files could be downloaded
|
|
328
353
|
:raises RucioException: if something unexpected went wrong during the download
|
|
329
354
|
"""
|
|
355
|
+
trace_custom_fields = trace_custom_fields or {}
|
|
330
356
|
logger = self.logger
|
|
331
357
|
|
|
332
358
|
logger(logging.INFO, 'Getting sources from metalink file')
|
|
@@ -351,7 +377,13 @@ class DownloadClient:
|
|
|
351
377
|
|
|
352
378
|
return self._check_output(output_items, deactivate_file_download_exceptions=deactivate_file_download_exceptions)
|
|
353
379
|
|
|
354
|
-
def _download_multithreaded(
|
|
380
|
+
def _download_multithreaded(
|
|
381
|
+
self,
|
|
382
|
+
input_items: list[dict[str, Any]],
|
|
383
|
+
num_threads: int,
|
|
384
|
+
trace_custom_fields: Optional[dict[str, Any]] = None,
|
|
385
|
+
traces_copy_out: Optional[list[dict[str, Any]]] = None
|
|
386
|
+
) -> list[dict[str, Any]]:
|
|
355
387
|
"""
|
|
356
388
|
Starts an appropriate number of threads to download items from the input list.
|
|
357
389
|
(This function is meant to be used as class internal only)
|
|
@@ -363,6 +395,7 @@ class DownloadClient:
|
|
|
363
395
|
|
|
364
396
|
:returns: list with output items as dictionaries
|
|
365
397
|
"""
|
|
398
|
+
trace_custom_fields = trace_custom_fields or {}
|
|
366
399
|
logger = self.logger
|
|
367
400
|
|
|
368
401
|
num_files = len(input_items)
|
|
@@ -671,10 +704,10 @@ class DownloadClient:
|
|
|
671
704
|
|
|
672
705
|
# if the file was downloaded with success, it can be linked to pcache
|
|
673
706
|
if pcache:
|
|
674
|
-
logger(logging.INFO, 'File %s is going to be
|
|
707
|
+
logger(logging.INFO, 'File %s is going to be registered into pcache.' % dest_file_path)
|
|
675
708
|
try:
|
|
676
709
|
pcache_state, hardlink_state = pcache.check_and_link(src=pfn, storage_root=storage_prefix, local_src=first_dest_file_path)
|
|
677
|
-
logger(logging.INFO, 'File %s is now
|
|
710
|
+
logger(logging.INFO, 'File %s is now registered into pcache.' % first_dest_file_path)
|
|
678
711
|
except Exception as e:
|
|
679
712
|
logger(logging.WARNING, 'Failed to load file to pcache: %s' % str(e))
|
|
680
713
|
|
|
@@ -730,7 +763,14 @@ class DownloadClient:
|
|
|
730
763
|
|
|
731
764
|
return item
|
|
732
765
|
|
|
733
|
-
def download_aria2c(
|
|
766
|
+
def download_aria2c(
|
|
767
|
+
self,
|
|
768
|
+
items: list[dict[str, Any]],
|
|
769
|
+
trace_custom_fields: Optional[dict[str, Any]] = None,
|
|
770
|
+
filters: Optional[dict[str, Any]] = None,
|
|
771
|
+
deactivate_file_download_exceptions: bool = False,
|
|
772
|
+
sort: Optional[str] = None
|
|
773
|
+
) -> list[dict[str, Any]]:
|
|
734
774
|
"""
|
|
735
775
|
Uses aria2c to download the items with given DIDs. This function can also download datasets and wildcarded DIDs.
|
|
736
776
|
It only can download files that are available via https/davs.
|
|
@@ -741,7 +781,7 @@ class DownloadClient:
|
|
|
741
781
|
rse - Optional: rse name (e.g. 'CERN-PROD_DATADISK') or rse expression from where to download
|
|
742
782
|
base_dir - Optional: base directory where the downloaded files will be stored. (Default: '.')
|
|
743
783
|
no_subdir - Optional: If true, files are written directly into base_dir. (Default: False)
|
|
744
|
-
nrandom - Optional: if the DID addresses a dataset, nrandom files will be randomly
|
|
784
|
+
nrandom - Optional: if the DID addresses a dataset, nrandom files will be randomly chosen for download from the dataset
|
|
745
785
|
ignore_checksum - Optional: If true, skips the checksum validation between the downloaded file and the rucio catalouge. (Default: False)
|
|
746
786
|
check_local_with_filesize_only - Optional: If true, already downloaded files will not be validated by checksum.
|
|
747
787
|
|
|
@@ -760,6 +800,8 @@ class DownloadClient:
|
|
|
760
800
|
:raises NotAllFilesDownloaded: if not all files could be downloaded
|
|
761
801
|
:raises RucioException: if something went wrong during the download (e.g. aria2c could not be started)
|
|
762
802
|
"""
|
|
803
|
+
trace_custom_fields = trace_custom_fields or {}
|
|
804
|
+
filters = filters or {}
|
|
763
805
|
logger = self.logger
|
|
764
806
|
trace_custom_fields['uuid'] = generate_uuid()
|
|
765
807
|
|
|
@@ -798,7 +840,7 @@ class DownloadClient:
|
|
|
798
840
|
|
|
799
841
|
:param rpc_secret: the secret for the RPC proxy
|
|
800
842
|
|
|
801
|
-
:returns: a
|
|
843
|
+
:returns: a tuple with the process and the rpc proxy objects
|
|
802
844
|
|
|
803
845
|
:raises RucioException: if the process or the proxy could not be created
|
|
804
846
|
"""
|
|
@@ -860,7 +902,13 @@ class DownloadClient:
|
|
|
860
902
|
raise RucioException('Failed to initialise rpc proxy!', error)
|
|
861
903
|
return (rpcproc, aria_rpc)
|
|
862
904
|
|
|
863
|
-
def _download_items_aria2c(
|
|
905
|
+
def _download_items_aria2c(
|
|
906
|
+
self,
|
|
907
|
+
items: list[dict[str, Any]],
|
|
908
|
+
aria_rpc: Any,
|
|
909
|
+
rpc_auth: str,
|
|
910
|
+
trace_custom_fields: Optional[dict[str, Any]] = None
|
|
911
|
+
) -> list[dict[str, Any]]:
|
|
864
912
|
"""
|
|
865
913
|
Uses aria2c to download the given items. Aria2c needs to be started
|
|
866
914
|
as RPC background process first and a RPC proxy is needed.
|
|
@@ -873,6 +921,7 @@ class DownloadClient:
|
|
|
873
921
|
|
|
874
922
|
:returns: a list of dictionaries with an entry for each file, containing the input options, the did, and the clientState
|
|
875
923
|
"""
|
|
924
|
+
trace_custom_fields = trace_custom_fields or {}
|
|
876
925
|
logger = self.logger
|
|
877
926
|
|
|
878
927
|
gid_to_item = {} # maps an aria2c download id (gid) to the download item
|
|
@@ -958,7 +1007,7 @@ class DownloadClient:
|
|
|
958
1007
|
# workaround: only consider first dest file path for aria2c download
|
|
959
1008
|
dest_file_path = next(iter(item['dest_file_paths']))
|
|
960
1009
|
|
|
961
|
-
# ensure we
|
|
1010
|
+
# ensure we didn't miss the active state (e.g. a very fast download)
|
|
962
1011
|
start_time = item.setdefault('transferStart', time.time())
|
|
963
1012
|
end_time = item.setdefault('transferEnd', time.time())
|
|
964
1013
|
|
|
@@ -1093,7 +1142,7 @@ class DownloadClient:
|
|
|
1093
1142
|
self.extraction_tools = [tool for tool in self.extraction_tools if tool.is_useable()]
|
|
1094
1143
|
if len(self.extraction_tools) < 1:
|
|
1095
1144
|
logger(logging.WARNING, 'Archive resolution is enabled but no extraction tool is available. '
|
|
1096
|
-
'Sources whose protocol
|
|
1145
|
+
'Sources whose protocol does not support extraction will not be considered for download.')
|
|
1097
1146
|
|
|
1098
1147
|
# if excluding tapes, we need to list them first
|
|
1099
1148
|
tape_rses = []
|
|
@@ -1110,7 +1159,7 @@ class DownloadClient:
|
|
|
1110
1159
|
for item in input_items:
|
|
1111
1160
|
resolved_dids = list(self._resolve_one_item_dids(item))
|
|
1112
1161
|
if not resolved_dids:
|
|
1113
|
-
logger(logging.WARNING, 'An item
|
|
1162
|
+
logger(logging.WARNING, 'An item did not have any DIDs after resolving the input: %s.' % item.get('did', item))
|
|
1114
1163
|
item['dids'] = resolved_dids
|
|
1115
1164
|
for did in resolved_dids:
|
|
1116
1165
|
did_to_input_items.setdefault(DID(did), []).append(item)
|
|
@@ -1342,7 +1391,7 @@ class DownloadClient:
|
|
|
1342
1391
|
file_item['dest_file_paths'] = list(dest_file_paths)
|
|
1343
1392
|
file_item['temp_file_path'] = '%s.part' % file_item['dest_file_paths'][0]
|
|
1344
1393
|
|
|
1345
|
-
# the file did str
|
|
1394
|
+
# the file did str is not an unique key for this dict because multiple calls of list_replicas
|
|
1346
1395
|
# could result in the same DID multiple times. So we're using the id of the dictionary objects
|
|
1347
1396
|
fiid = id(file_item)
|
|
1348
1397
|
fiid_to_file_item[fiid] = file_item
|
|
@@ -1500,7 +1549,7 @@ class DownloadClient:
|
|
|
1500
1549
|
Splits a given DID string (e.g. 'scope1:name.file') into its scope and name part
|
|
1501
1550
|
(This function is meant to be used as class internal only)
|
|
1502
1551
|
|
|
1503
|
-
:param did_str: the DID string that will be
|
|
1552
|
+
:param did_str: the DID string that will be split
|
|
1504
1553
|
|
|
1505
1554
|
:returns: the scope- and name part of the given DID
|
|
1506
1555
|
|
|
@@ -1538,7 +1587,7 @@ class DownloadClient:
|
|
|
1538
1587
|
:param dest_dir_name: name of the destination directory
|
|
1539
1588
|
:param no_subdir: if no subdirectory should be created
|
|
1540
1589
|
|
|
1541
|
-
:returns: the
|
|
1590
|
+
:returns: the absolute path of the destination directory
|
|
1542
1591
|
"""
|
|
1543
1592
|
# append dest_dir_name, if subdir should be used
|
|
1544
1593
|
if dest_dir_name.startswith('/'):
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
from datetime import datetime
|
|
16
16
|
from json import dumps, loads
|
|
17
|
+
from typing import Any, Optional
|
|
17
18
|
from urllib.parse import quote_plus
|
|
18
19
|
|
|
19
20
|
from requests.status_codes import codes
|
|
@@ -233,7 +234,17 @@ class ReplicaClient(BaseClient):
|
|
|
233
234
|
exc_cls, exc_msg = self._get_exception(headers=r.headers, status_code=r.status_code, data=r.content)
|
|
234
235
|
raise exc_cls(exc_msg)
|
|
235
236
|
|
|
236
|
-
def add_replica(
|
|
237
|
+
def add_replica(
|
|
238
|
+
self,
|
|
239
|
+
rse: str,
|
|
240
|
+
scope: str,
|
|
241
|
+
name: str,
|
|
242
|
+
bytes_: int,
|
|
243
|
+
adler32: str,
|
|
244
|
+
pfn: Optional[str] = None,
|
|
245
|
+
md5: Optional[str] = None,
|
|
246
|
+
meta: Optional[dict[str, Any]] = None
|
|
247
|
+
) -> bool:
|
|
237
248
|
"""
|
|
238
249
|
Add file replicas to a RSE.
|
|
239
250
|
|
|
@@ -249,6 +260,7 @@ class ReplicaClient(BaseClient):
|
|
|
249
260
|
:return: True if files were created successfully.
|
|
250
261
|
|
|
251
262
|
"""
|
|
263
|
+
meta = meta or {}
|
|
252
264
|
dict_ = {'scope': scope, 'name': name, 'bytes': bytes_, 'meta': meta, 'adler32': adler32}
|
|
253
265
|
if md5:
|
|
254
266
|
dict_['md5'] = md5
|
|
@@ -83,7 +83,7 @@ class RSEClient(BaseClient):
|
|
|
83
83
|
Update RSE properties like availability or name.
|
|
84
84
|
|
|
85
85
|
:param rse: the name of the new rse.
|
|
86
|
-
:param parameters: A
|
|
86
|
+
:param parameters: A dictionary with property (name, read, write, delete as keys).
|
|
87
87
|
"""
|
|
88
88
|
path = 'rses/' + rse
|
|
89
89
|
url = build_url(choice(self.list_hosts), path=path)
|
|
@@ -341,7 +341,7 @@ class RSEClient(BaseClient):
|
|
|
341
341
|
|
|
342
342
|
:param rse: the RSE name.
|
|
343
343
|
:param scheme: identifier of the protocol.
|
|
344
|
-
:param data: A dict providing the new values of the protocol
|
|
344
|
+
:param data: A dict providing the new values of the protocol attributes.
|
|
345
345
|
Keys must match column names in database.
|
|
346
346
|
:param hostname: hostname of the protocol.
|
|
347
347
|
:param port: port of the protocol.
|
|
@@ -512,7 +512,7 @@ class RSEClient(BaseClient):
|
|
|
512
512
|
:param rse: The RSE name.
|
|
513
513
|
:param filters: dictionary of attributes by which the results should be filtered.
|
|
514
514
|
|
|
515
|
-
:returns: list of
|
|
515
|
+
:returns: list of dictionaries.
|
|
516
516
|
"""
|
|
517
517
|
path = [self.RSE_BASEURL, rse, 'usage', 'history']
|
|
518
518
|
path = '/'.join(path)
|
|
@@ -593,7 +593,7 @@ class RSEClient(BaseClient):
|
|
|
593
593
|
|
|
594
594
|
:param source: The source.
|
|
595
595
|
:param destination: The destination.
|
|
596
|
-
:param parameters: A
|
|
596
|
+
:param parameters: A dictionary with property.
|
|
597
597
|
"""
|
|
598
598
|
path = [self.RSE_BASEURL, source, 'distances', destination]
|
|
599
599
|
path = '/'.join(path)
|
|
@@ -612,7 +612,7 @@ class RSEClient(BaseClient):
|
|
|
612
612
|
|
|
613
613
|
:param source: The source.
|
|
614
614
|
:param destination: The destination.
|
|
615
|
-
:param parameters: A
|
|
615
|
+
:param parameters: A dictionary with property.
|
|
616
616
|
"""
|
|
617
617
|
path = [self.RSE_BASEURL, source, 'distances', destination]
|
|
618
618
|
path = '/'.join(path)
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
|
+
from collections.abc import Sequence
|
|
15
16
|
from json import dumps, loads
|
|
16
17
|
from typing import Any, Optional, Union
|
|
17
18
|
from urllib.parse import quote_plus
|
|
@@ -30,7 +31,7 @@ class RuleClient(BaseClient):
|
|
|
30
31
|
|
|
31
32
|
def add_replication_rule(
|
|
32
33
|
self,
|
|
33
|
-
dids:
|
|
34
|
+
dids: Sequence[dict[str, str]],
|
|
34
35
|
copies: int,
|
|
35
36
|
rse_expression: str,
|
|
36
37
|
priority: int = 3,
|
|
@@ -25,6 +25,7 @@ import time
|
|
|
25
25
|
from rucio import version
|
|
26
26
|
from rucio.client.client import Client
|
|
27
27
|
from rucio.common.config import config_get, config_get_bool, config_get_int
|
|
28
|
+
from rucio.common.constants import RseAttr
|
|
28
29
|
from rucio.common.exception import (
|
|
29
30
|
DataIdentifierAlreadyExists,
|
|
30
31
|
DataIdentifierNotFound,
|
|
@@ -195,8 +196,8 @@ class UploadClient:
|
|
|
195
196
|
rse_attributes = self.client.list_rse_attributes(rse)
|
|
196
197
|
except:
|
|
197
198
|
logger(logging.WARNING, 'Attributes of the RSE: %s not available.' % rse)
|
|
198
|
-
if (self.client_location and 'lan' in rse_settings['domain'] and
|
|
199
|
-
if self.client_location['site'] == rse_attributes[
|
|
199
|
+
if (self.client_location and 'lan' in rse_settings['domain'] and RseAttr.SITE in rse_attributes):
|
|
200
|
+
if self.client_location['site'] == rse_attributes[RseAttr.SITE]:
|
|
200
201
|
domain = 'lan'
|
|
201
202
|
logger(logging.DEBUG, '{} domain is used for the upload'.format(domain))
|
|
202
203
|
|
|
@@ -458,7 +459,7 @@ class UploadClient:
|
|
|
458
459
|
try:
|
|
459
460
|
guid = output.splitlines()[-1].split()[0].replace('-', '').lower()
|
|
460
461
|
except Exception:
|
|
461
|
-
raise RucioException('Error extracting GUID from
|
|
462
|
+
raise RucioException('Error extracting GUID from output of pool_extractFileIdentifier')
|
|
462
463
|
elif guid:
|
|
463
464
|
guid = guid.replace('-', '')
|
|
464
465
|
else:
|
|
@@ -674,7 +675,7 @@ class UploadClient:
|
|
|
674
675
|
raise RSEOperationNotSupported(str(error))
|
|
675
676
|
|
|
676
677
|
# Is stat after that upload allowed?
|
|
677
|
-
skip_upload_stat = rse_attributes.get(
|
|
678
|
+
skip_upload_stat = rse_attributes.get(RseAttr.SKIP_UPLOAD_STAT, False)
|
|
678
679
|
self.logger(logging.DEBUG, 'skip_upload_stat=%s', skip_upload_stat)
|
|
679
680
|
|
|
680
681
|
# Checksum verification, obsolete, see Gabriele changes.
|
|
@@ -740,7 +741,7 @@ class UploadClient:
|
|
|
740
741
|
|
|
741
742
|
def _create_protocol(self, rse_settings, operation, impl=None, force_scheme=None, domain='wan'):
|
|
742
743
|
"""
|
|
743
|
-
|
|
744
|
+
Protocol construction.
|
|
744
745
|
:param rse_settings: rse_settings
|
|
745
746
|
:param operation: activity, e.g. read, write, delete etc.
|
|
746
747
|
:param force_scheme: custom scheme
|
|
@@ -23,6 +23,8 @@ if TYPE_CHECKING:
|
|
|
23
23
|
from collections.abc import Callable
|
|
24
24
|
from typing import Optional
|
|
25
25
|
|
|
26
|
+
from dogpile.cache.region import CacheRegion
|
|
27
|
+
|
|
26
28
|
CACHE_URL = config_get('cache', 'url', False, '127.0.0.1:11211', check_config_table=False)
|
|
27
29
|
|
|
28
30
|
ENABLE_CACHING = True
|
|
@@ -47,7 +49,7 @@ def make_region_memcached(
|
|
|
47
49
|
expiration_time: int,
|
|
48
50
|
function_key_generator: "Optional[Callable]" = None,
|
|
49
51
|
memcached_expire_time: "Optional[int]" = None
|
|
50
|
-
):
|
|
52
|
+
) -> "CacheRegion":
|
|
51
53
|
"""
|
|
52
54
|
Make and configure a dogpile.cache.pymemcache region
|
|
53
55
|
"""
|