rucio-clients 37.6.0__tar.gz → 37.7.1__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-37.6.0 → rucio_clients-37.7.1}/PKG-INFO +1 -1
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/lib/rucio/cli/bin_legacy/rucio.py +40 -21
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/lib/rucio/cli/rule.py +9 -5
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/lib/rucio/client/baseclient.py +4 -3
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/lib/rucio/client/downloadclient.py +2 -1
- rucio_clients-37.7.1/lib/rucio/client/exportclient.py +91 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/lib/rucio/client/pingclient.py +35 -4
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/lib/rucio/client/touchclient.py +2 -1
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/lib/rucio/client/uploadclient.py +3 -2
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/lib/rucio/common/cache.py +1 -2
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/lib/rucio/common/client.py +4 -30
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/lib/rucio/common/config.py +26 -1
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/lib/rucio/common/constants.py +3 -1
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/lib/rucio/common/plugins.py +2 -2
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/lib/rucio/common/policy.py +3 -2
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/lib/rucio/common/schema/__init__.py +4 -3
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/lib/rucio/common/types.py +7 -5
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/lib/rucio/rse/__init__.py +7 -6
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/lib/rucio/rse/rsemanager.py +5 -4
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/lib/rucio/rse/translation.py +2 -2
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/lib/rucio/vcsversion.py +3 -3
- rucio_clients-37.7.1/tests/test_bin_rucio.py +1243 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/tests/test_cli_client_structure.py +25 -2
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/tests/test_conveyor.py +69 -70
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/tests/test_conveyor_submitter.py +13 -12
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/tests/test_download.py +84 -8
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/tests/test_heartbeat.py +14 -12
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/tests/test_hermes.py +36 -2
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/tests/test_import_export.py +3 -3
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/tests/test_judge_evaluator.py +5 -5
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/tests/test_judge_injector.py +6 -5
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/tests/test_multi_vo.py +22 -22
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/tests/test_replica.py +5 -5
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/tests/test_rule.py +13 -11
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/tests/test_subscription.py +51 -6
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/tests/test_throttler.py +22 -21
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/tests/test_trace.py +1 -1
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/tests/test_upload.py +279 -65
- rucio_clients-37.6.0/lib/rucio/client/exportclient.py +0 -50
- rucio_clients-37.6.0/tests/test_bin_rucio.py +0 -2433
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/AUTHORS.rst +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/ChangeLog +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/LICENSE +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/MANIFEST.in +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/README.md +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/bin/rucio +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/bin/rucio-admin +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/etc/rse-accounts.cfg.template +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/etc/rucio.cfg.atlas.client.template +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/etc/rucio.cfg.template +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/lib/rucio/__init__.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/lib/rucio/alembicrevision.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/lib/rucio/cli/__init__.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/lib/rucio/cli/account.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/lib/rucio/cli/bin_legacy/__init__.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/lib/rucio/cli/bin_legacy/rucio_admin.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/lib/rucio/cli/command.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/lib/rucio/cli/config.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/lib/rucio/cli/did.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/lib/rucio/cli/download.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/lib/rucio/cli/lifetime_exception.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/lib/rucio/cli/replica.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/lib/rucio/cli/rse.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/lib/rucio/cli/scope.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/lib/rucio/cli/subscription.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/lib/rucio/cli/upload.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/lib/rucio/cli/utils.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/lib/rucio/client/__init__.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/lib/rucio/client/accountclient.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/lib/rucio/client/accountlimitclient.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/lib/rucio/client/client.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/lib/rucio/client/configclient.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/lib/rucio/client/credentialclient.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/lib/rucio/client/didclient.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/lib/rucio/client/diracclient.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/lib/rucio/client/fileclient.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/lib/rucio/client/importclient.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/lib/rucio/client/lifetimeclient.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/lib/rucio/client/lockclient.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/lib/rucio/client/metaconventionsclient.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/lib/rucio/client/replicaclient.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/lib/rucio/client/requestclient.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/lib/rucio/client/richclient.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/lib/rucio/client/rseclient.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/lib/rucio/client/ruleclient.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/lib/rucio/client/scopeclient.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/lib/rucio/client/subscriptionclient.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/lib/rucio/common/__init__.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/lib/rucio/common/bittorrent.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/lib/rucio/common/checksum.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/lib/rucio/common/constraints.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/lib/rucio/common/didtype.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/lib/rucio/common/exception.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/lib/rucio/common/extra.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/lib/rucio/common/logging.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/lib/rucio/common/pcache.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/lib/rucio/common/schema/generic.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/lib/rucio/common/schema/generic_multi_vo.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/lib/rucio/common/stomp_utils.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/lib/rucio/common/stopwatch.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/lib/rucio/common/test_rucio_server.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/lib/rucio/common/utils.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/lib/rucio/rse/protocols/__init__.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/lib/rucio/rse/protocols/bittorrent.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/lib/rucio/rse/protocols/cache.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/lib/rucio/rse/protocols/dummy.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/lib/rucio/rse/protocols/gfal.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/lib/rucio/rse/protocols/globus.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/lib/rucio/rse/protocols/http_cache.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/lib/rucio/rse/protocols/mock.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/lib/rucio/rse/protocols/ngarc.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/lib/rucio/rse/protocols/posix.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/lib/rucio/rse/protocols/protocol.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/lib/rucio/rse/protocols/rclone.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/lib/rucio/rse/protocols/rfio.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/lib/rucio/rse/protocols/srm.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/lib/rucio/rse/protocols/ssh.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/lib/rucio/rse/protocols/storm.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/lib/rucio/rse/protocols/webdav.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/lib/rucio/rse/protocols/xrootd.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/lib/rucio/version.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/lib/rucio_clients.egg-info/SOURCES.txt +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/pyproject.toml +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/requirements/requirements.client.txt +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/setup.cfg +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/setup.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/setuputil.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/tests/test_abacus_account.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/tests/test_abacus_collection_replica.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/tests/test_abacus_rse.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/tests/test_account.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/tests/test_account_limits.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/tests/test_archive.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/tests/test_auditor.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/tests/test_auditor_hdfs.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/tests/test_auditor_srmdumps.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/tests/test_authentication.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/tests/test_automatix.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/tests/test_bad_replica.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/tests/test_bb8.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/tests/test_belleii.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/tests/test_boolean.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/tests/test_clients.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/tests/test_config.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/tests/test_counter.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/tests/test_credential.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/tests/test_curl.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/tests/test_daemons.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/tests/test_dataset_replicas.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/tests/test_db.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/tests/test_did.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/tests/test_did_meta_plugins.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/tests/test_dumper.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/tests/test_filter_engine.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/tests/test_gateway_external_representation.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/tests/test_identity.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/tests/test_impl_upload_download.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/tests/test_judge_cleaner.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/tests/test_judge_repairer.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/tests/test_lifetime.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/tests/test_message.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/tests/test_meta_conventions.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/tests/test_meta_did.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/tests/test_module_import.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/tests/test_monitor.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/tests/test_naming_convention.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/tests/test_oauthmanager.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/tests/test_oidc.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/tests/test_permission.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/tests/test_pfns.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/tests/test_ping.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/tests/test_policy_package.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/tests/test_preparer.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/tests/test_qos.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/tests/test_quarantined_replica.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/tests/test_reaper.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/tests/test_redirect.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/tests/test_replica_recoverer.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/tests/test_replica_sorting.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/tests/test_request.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/tests/test_root_proxy.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/tests/test_rse.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/tests/test_rse_expression_parser.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/tests/test_rse_lfn2path.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/tests/test_rse_protocol_gfal2.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/tests/test_rse_protocol_gfal2_impl.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/tests/test_rse_protocol_posix.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/tests/test_rse_protocol_rclone.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/tests/test_rse_protocol_rsync.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/tests/test_rse_protocol_srm.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/tests/test_rse_protocol_ssh.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/tests/test_rse_protocol_webdav.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/tests/test_rse_protocol_xrootd.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/tests/test_rse_selector.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/tests/test_rucio_server.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/tests/test_scope.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/tests/test_tpc.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/tests/test_transfer.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/tests/test_transfer_plugins.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/tests/test_undertaker.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/tests/test_utils.py +0 -0
- {rucio_clients-37.6.0 → rucio_clients-37.7.1}/tools/merge_rucio_configs.py +0 -0
|
@@ -26,7 +26,7 @@ import uuid
|
|
|
26
26
|
from copy import deepcopy
|
|
27
27
|
from datetime import datetime
|
|
28
28
|
from logging import DEBUG
|
|
29
|
-
from typing import Optional
|
|
29
|
+
from typing import TYPE_CHECKING, Optional
|
|
30
30
|
|
|
31
31
|
from rich.console import Console
|
|
32
32
|
from rich.padding import Padding
|
|
@@ -58,6 +58,9 @@ from rucio.common.extra import import_extras
|
|
|
58
58
|
from rucio.common.test_rucio_server import TestRucioServer
|
|
59
59
|
from rucio.common.utils import Color, StoreAndDeprecateWarningAction, chunks, extract_scope, parse_did_filter_from_string, parse_did_filter_from_string_fe, setup_logger, sizefmt
|
|
60
60
|
|
|
61
|
+
if TYPE_CHECKING:
|
|
62
|
+
from rucio.common.types import FileToUploadDict
|
|
63
|
+
|
|
61
64
|
EXTRA_MODULES = import_extras(['argcomplete'])
|
|
62
65
|
|
|
63
66
|
if EXTRA_MODULES['argcomplete']:
|
|
@@ -947,29 +950,44 @@ def upload(args, client, logger, console, spinner):
|
|
|
947
950
|
elif len(did) == 2:
|
|
948
951
|
logger.warning('Ignoring input {} because dataset DID is already set {}:{}'.format(arg, dsscope, dsname))
|
|
949
952
|
|
|
950
|
-
items = []
|
|
953
|
+
items: list[FileToUploadDict] = []
|
|
951
954
|
for arg in args.args:
|
|
952
955
|
if arg.count(':') > 0:
|
|
953
956
|
continue
|
|
957
|
+
if args.pfn and args.impl:
|
|
958
|
+
logger.warning('Ignoring --impl option because --pfn option given')
|
|
959
|
+
args.impl = None
|
|
960
|
+
|
|
961
|
+
item: FileToUploadDict = {'path': arg, 'rse': args.rse}
|
|
962
|
+
|
|
963
|
+
if args.scope:
|
|
964
|
+
item['did_scope'] = args.scope
|
|
965
|
+
if args.name:
|
|
966
|
+
item['did_name'] = args.name
|
|
967
|
+
if dsscope:
|
|
968
|
+
item['dataset_scope'] = dsscope
|
|
969
|
+
if dsname:
|
|
970
|
+
item['dataset_name'] = dsname
|
|
971
|
+
if args.impl:
|
|
972
|
+
item['impl'] = args.impl
|
|
973
|
+
if args.protocol:
|
|
974
|
+
item['force_scheme'] = args.protocol
|
|
954
975
|
if args.pfn:
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
'transfer_timeout': args.transfer_timeout,
|
|
971
|
-
'guid': args.guid,
|
|
972
|
-
'recursive': args.recursive})
|
|
976
|
+
item['pfn'] = args.pfn
|
|
977
|
+
if args.no_register:
|
|
978
|
+
item['no_register'] = True
|
|
979
|
+
if args.register_after_upload:
|
|
980
|
+
item['register_after_upload'] = True
|
|
981
|
+
if args.lifetime is not None:
|
|
982
|
+
item['lifetime'] = int(args.lifetime)
|
|
983
|
+
if args.transfer_timeout is not None:
|
|
984
|
+
item['transfer_timeout'] = int(args.transfer_timeout)
|
|
985
|
+
if args.guid:
|
|
986
|
+
item['guid'] = args.guid
|
|
987
|
+
if args.recursive:
|
|
988
|
+
item['recursive'] = True
|
|
989
|
+
|
|
990
|
+
items.append(item)
|
|
973
991
|
|
|
974
992
|
if len(items) < 1:
|
|
975
993
|
raise InputValidationError('No files could be extracted from the given arguments')
|
|
@@ -978,6 +996,7 @@ def upload(args, client, logger, console, spinner):
|
|
|
978
996
|
logger.error("A single GUID was specified on the command line, but there are multiple files to upload.")
|
|
979
997
|
logger.error("If GUID auto-detection is not used, only one file may be uploaded at a time")
|
|
980
998
|
raise InputValidationError('Invalid input argument composition')
|
|
999
|
+
|
|
981
1000
|
if len(items) > 1 and args.name:
|
|
982
1001
|
logger.error("A single LFN was specified on the command line, but there are multiple files to upload.")
|
|
983
1002
|
logger.error("If LFN auto-detection is not used, only one file may be uploaded at a time")
|
|
@@ -991,7 +1010,7 @@ def upload(args, client, logger, console, spinner):
|
|
|
991
1010
|
from rucio.client.uploadclient import UploadClient
|
|
992
1011
|
upload_client = UploadClient(client, logger=logger)
|
|
993
1012
|
summary_file_path = 'rucio_upload.json' if args.summary else None
|
|
994
|
-
upload_client.upload(items, summary_file_path)
|
|
1013
|
+
upload_client.upload(items=items, summary_file_path=summary_file_path)
|
|
995
1014
|
return SUCCESS
|
|
996
1015
|
|
|
997
1016
|
|
|
@@ -116,13 +116,17 @@ def move(ctx, rule_id, rses, activity, source_rses):
|
|
|
116
116
|
@click.option("--comment", help="Comment about the replication rule")
|
|
117
117
|
@click.option("--account", help="The account owning the rule")
|
|
118
118
|
@click.option("--stuck", is_flag=True, default=False, help="Set state to STUCK.")
|
|
119
|
+
@click.option('--suspend', is_flag=True, default=None, help='Set state to SUSPENDED.')
|
|
119
120
|
@click.option("--activity", help="Activity of the rule.")
|
|
120
121
|
@click.option("--cancel-requests", is_flag=True, default=False, help="Cancel requests when setting rules to stuck.")
|
|
121
122
|
@click.option("--priority", help="Priority of the requests of the rule.")
|
|
122
123
|
@click.option("--child-rule-id", help='Child rule id of the rule. Use "None" to remove an existing parent/child relationship.')
|
|
123
124
|
@click.option("--boost-rule", is_flag=True, default=False, help="Quickens the transition of a rule from STUCK to REPLICATING.")
|
|
124
125
|
@click.pass_context
|
|
125
|
-
def update(
|
|
126
|
+
def update(
|
|
127
|
+
ctx, rule_id: str, lifetime: str, locked: bool, source_rses: str, activity: str, comment: str,
|
|
128
|
+
account: str, stuck: bool, suspend: bool, cancel_requests: bool, priority: str, child_rule_id: str, boost_rule: bool
|
|
129
|
+
):
|
|
126
130
|
"""Update an existing rule"""
|
|
127
131
|
args = Arguments(
|
|
128
132
|
{
|
|
@@ -134,6 +138,7 @@ def update(ctx, rule_id, lifetime, locked, source_rses, activity, comment, accou
|
|
|
134
138
|
"rule_account": account,
|
|
135
139
|
"source_replica_expression": source_rses,
|
|
136
140
|
"state_stuck": stuck,
|
|
141
|
+
"state_suspended": suspend,
|
|
137
142
|
"cancel_requests": cancel_requests,
|
|
138
143
|
"priority": priority,
|
|
139
144
|
"child_rule_id": child_rule_id,
|
|
@@ -144,15 +149,14 @@ def update(ctx, rule_id, lifetime, locked, source_rses, activity, comment, accou
|
|
|
144
149
|
|
|
145
150
|
|
|
146
151
|
@rule.command("list")
|
|
147
|
-
@click.
|
|
148
|
-
@click.option("--id", "rule_id", help="List by rule id", hidden=True) # TODO: Remove. This doesn't work and does the same thing as show
|
|
152
|
+
@click.argument("did")
|
|
149
153
|
@click.option("--traverse", is_flag=True, default=False, help="Traverse the did tree and search for rules affecting this did")
|
|
150
154
|
@click.option("--csv", is_flag=True, default=False, help="Comma Separated Value output")
|
|
151
155
|
@click.option("--file", help="Filter by file")
|
|
152
156
|
@click.option("--account", help="Filter by account")
|
|
153
157
|
@click.option("--subscription", help="Filter by subscription name")
|
|
154
158
|
@click.pass_context
|
|
155
|
-
def list_(ctx, did,
|
|
159
|
+
def list_(ctx, did, traverse, csv, file, account, subscription):
|
|
156
160
|
"""List all rules impacting a given DID"""
|
|
157
|
-
args = Arguments({"no_pager": ctx.obj.no_pager, "did": did, "rule_id":
|
|
161
|
+
args = Arguments({"no_pager": ctx.obj.no_pager, "did": did, "rule_id": None, "traverse": traverse, "csv": csv, "file": file, "subscription": (account if account is not None else ctx.obj.client.account, subscription)})
|
|
158
162
|
list_rules(args, ctx.obj.client, ctx.obj.logger, ctx.obj.console, ctx.obj.spinner)
|
|
@@ -38,6 +38,7 @@ from requests.status_codes import codes
|
|
|
38
38
|
from rucio import version
|
|
39
39
|
from rucio.common import exception
|
|
40
40
|
from rucio.common.config import config_get, config_get_bool, config_get_int, config_has_section
|
|
41
|
+
from rucio.common.constants import DEFAULT_VO
|
|
41
42
|
from rucio.common.exception import CannotAuthenticate, ClientProtocolNotFound, ClientProtocolNotSupported, ConfigNotFound, MissingClientParameter, MissingModuleException, NoAuthInformation, ServerConnectionException
|
|
42
43
|
from rucio.common.extra import import_extras
|
|
43
44
|
from rucio.common.utils import build_url, get_tmp_dir, my_key_generator, parse_response, setup_logger, ssh_sign
|
|
@@ -225,10 +226,10 @@ class BaseClient:
|
|
|
225
226
|
self.vo = config_get('client', 'vo')
|
|
226
227
|
except (NoOptionError, NoSectionError):
|
|
227
228
|
self.logger.debug('No VO found. Using default VO.')
|
|
228
|
-
self.vo =
|
|
229
|
+
self.vo = DEFAULT_VO
|
|
229
230
|
except ConfigNotFound:
|
|
230
231
|
self.logger.debug('No configuration found. Using default VO.')
|
|
231
|
-
self.vo =
|
|
232
|
+
self.vo = DEFAULT_VO
|
|
232
233
|
|
|
233
234
|
self.auth_token_file_path, self.token_exp_epoch_file, self.token_file, self.token_path = self._get_auth_tokens()
|
|
234
235
|
self.__authenticate()
|
|
@@ -251,7 +252,7 @@ class BaseClient:
|
|
|
251
252
|
|
|
252
253
|
else:
|
|
253
254
|
token_path = self.TOKEN_PATH_PREFIX + getpass.getuser()
|
|
254
|
-
if self.vo !=
|
|
255
|
+
if self.vo != DEFAULT_VO:
|
|
255
256
|
token_path += '@%s' % self.vo
|
|
256
257
|
|
|
257
258
|
token_file = token_path + '/' + self.TOKEN_PREFIX + token_filename_suffix
|
|
@@ -32,6 +32,7 @@ from rucio.client.client import Client
|
|
|
32
32
|
from rucio.common.checksum import CHECKSUM_ALGO_DICT, GLOBALLY_SUPPORTED_CHECKSUMS, PREFERRED_CHECKSUM, adler32
|
|
33
33
|
from rucio.common.client import detect_client_location
|
|
34
34
|
from rucio.common.config import config_get
|
|
35
|
+
from rucio.common.constants import DEFAULT_VO
|
|
35
36
|
from rucio.common.didtype import DID
|
|
36
37
|
from rucio.common.exception import InputValidationError, NoFilesDownloaded, NotAllFilesDownloaded, RucioException
|
|
37
38
|
from rucio.common.pcache import Pcache
|
|
@@ -213,7 +214,7 @@ class DownloadClient:
|
|
|
213
214
|
self.trace_tpl['hostname'] = self.client_location['fqdn']
|
|
214
215
|
self.trace_tpl['localSite'] = self.client_location['site']
|
|
215
216
|
self.trace_tpl['account'] = self.client.account
|
|
216
|
-
if self.client.vo !=
|
|
217
|
+
if self.client.vo != DEFAULT_VO:
|
|
217
218
|
self.trace_tpl['vo'] = self.client.vo
|
|
218
219
|
self.trace_tpl['eventType'] = 'download'
|
|
219
220
|
self.trace_tpl['eventVersion'] = 'api_%s' % version.RUCIO_VERSION[0]
|
|
@@ -0,0 +1,91 @@
|
|
|
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
|
+
from typing import Any
|
|
16
|
+
|
|
17
|
+
from requests.status_codes import codes
|
|
18
|
+
|
|
19
|
+
from rucio.client.baseclient import BaseClient, choice
|
|
20
|
+
from rucio.common.utils import build_url, parse_response
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class ExportClient(BaseClient):
|
|
24
|
+
"""RSE client class for exporting data from Rucio"""
|
|
25
|
+
|
|
26
|
+
EXPORT_BASEURL = 'export'
|
|
27
|
+
|
|
28
|
+
def export_data(self, distance: bool = True) -> dict[str, Any]:
|
|
29
|
+
"""
|
|
30
|
+
Retrieve a detailed snapshot of the current RSE configuration.
|
|
31
|
+
|
|
32
|
+
The exported information includes all registered RSEs with their settings and
|
|
33
|
+
attributes. When `distance` is `True`, the RSE distance matrix is included as well.
|
|
34
|
+
The snapshot is intended for use cases such as configuration back‑ups, migrations
|
|
35
|
+
between instances, and monitoring (e.g. generating monitoring dashboards).
|
|
36
|
+
|
|
37
|
+
Parameters
|
|
38
|
+
----------
|
|
39
|
+
distance
|
|
40
|
+
If *True* (default), the server also returns the inter‑RSE distance matrix in
|
|
41
|
+
the payload.
|
|
42
|
+
|
|
43
|
+
_**Note:**_ Omitting the distance information can significantly reduce the
|
|
44
|
+
response size and improve transfer times.
|
|
45
|
+
|
|
46
|
+
Returns
|
|
47
|
+
-------
|
|
48
|
+
dict[str, Any]
|
|
49
|
+
A nested dictionary that mirrors the server‑side JSON structure.
|
|
50
|
+
The top‑level keys are:
|
|
51
|
+
|
|
52
|
+
**`rses`**:
|
|
53
|
+
Per‑RSE settings (name, deterministic flag, QoS class, supported protocol, etc.).
|
|
54
|
+
|
|
55
|
+
**`distances`**:
|
|
56
|
+
Pairwise RSE‑to‑RSE distance values (only present when `distance=True`).
|
|
57
|
+
|
|
58
|
+
Raises
|
|
59
|
+
------
|
|
60
|
+
RucioException
|
|
61
|
+
Raised if the HTTP status code is not *200 OK*.
|
|
62
|
+
|
|
63
|
+
Examples
|
|
64
|
+
--------
|
|
65
|
+
??? Example
|
|
66
|
+
|
|
67
|
+
Retrieve a full export of all configured RSEs, including their attributes and
|
|
68
|
+
inter-RSE distances:
|
|
69
|
+
|
|
70
|
+
```python
|
|
71
|
+
from rucio.client.exportclient import ExportClient
|
|
72
|
+
|
|
73
|
+
export_client = ExportClient()
|
|
74
|
+
|
|
75
|
+
try:
|
|
76
|
+
rse_data = export_client.export_data() # distance=True by default
|
|
77
|
+
print(f"Full RSE properties: {rse_data}")
|
|
78
|
+
except Exception as err:
|
|
79
|
+
print(f"Action failed: {err}")
|
|
80
|
+
```
|
|
81
|
+
"""
|
|
82
|
+
payload = {'distance': distance}
|
|
83
|
+
path = '/'.join([self.EXPORT_BASEURL])
|
|
84
|
+
url = build_url(choice(self.list_hosts), path=path, params=payload)
|
|
85
|
+
|
|
86
|
+
r = self._send_request(url, type_='GET')
|
|
87
|
+
if r.status_code == codes.ok:
|
|
88
|
+
return parse_response(r.text)
|
|
89
|
+
else:
|
|
90
|
+
exc_cls, exc_msg = self._get_exception(headers=r.headers, status_code=r.status_code, data=r.content)
|
|
91
|
+
raise exc_cls(exc_msg)
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
15
|
from json import loads
|
|
16
|
+
from typing import Any
|
|
16
17
|
|
|
17
18
|
from requests.status_codes import codes
|
|
18
19
|
|
|
@@ -21,16 +22,46 @@ from rucio.common.utils import build_url
|
|
|
21
22
|
|
|
22
23
|
|
|
23
24
|
class PingClient(BaseClient):
|
|
24
|
-
|
|
25
25
|
"""Ping client class"""
|
|
26
26
|
|
|
27
|
-
def ping(self):
|
|
27
|
+
def ping(self) -> dict[str, Any]:
|
|
28
28
|
"""
|
|
29
|
-
|
|
29
|
+
This is a light‑weight “are you alive?” call (*ping* request) to the configured Rucio.
|
|
30
|
+
|
|
31
|
+
A quick way to verify (without any required authentication):
|
|
32
|
+
|
|
33
|
+
- Network connectivity between the client and the server.
|
|
34
|
+
|
|
35
|
+
- Whether the server process is running and able to respond.
|
|
36
|
+
|
|
37
|
+
- The server’s build / version.
|
|
30
38
|
|
|
31
39
|
Returns
|
|
40
|
+
-------
|
|
41
|
+
dict[str, Any]
|
|
42
|
+
A dictionary with a single key: the server version (e.g. {'version': '37.0.0'})
|
|
43
|
+
|
|
44
|
+
Raises
|
|
45
|
+
------
|
|
46
|
+
rucio.common.exception.RucioException
|
|
47
|
+
If the HTTP status code is not *200 OK*.
|
|
48
|
+
|
|
49
|
+
Examples
|
|
32
50
|
--------
|
|
33
|
-
|
|
51
|
+
??? Example
|
|
52
|
+
|
|
53
|
+
Basic connectivity check:
|
|
54
|
+
|
|
55
|
+
```python
|
|
56
|
+
from rucio.client.pingclient import PingClient
|
|
57
|
+
ping_client = PingClient()
|
|
58
|
+
|
|
59
|
+
try:
|
|
60
|
+
info = ping_client.ping()
|
|
61
|
+
print(f"Connected to Rucio {info['version']}")
|
|
62
|
+
except Exception as err:
|
|
63
|
+
print(f"Ping failed: {err}")
|
|
64
|
+
```
|
|
34
65
|
"""
|
|
35
66
|
|
|
36
67
|
headers = None
|
|
@@ -18,6 +18,7 @@ from typing import Optional
|
|
|
18
18
|
from requests import post
|
|
19
19
|
|
|
20
20
|
from rucio.client.baseclient import BaseClient, choice
|
|
21
|
+
from rucio.common.constants import DEFAULT_VO
|
|
21
22
|
from rucio.common.exception import RucioException, UnsupportedDIDType
|
|
22
23
|
|
|
23
24
|
|
|
@@ -63,7 +64,7 @@ class TouchClient(BaseClient):
|
|
|
63
64
|
trace['eventType'] = 'touch'
|
|
64
65
|
trace['clientState'] = 'DONE'
|
|
65
66
|
trace['account'] = self.account
|
|
66
|
-
if self.vo !=
|
|
67
|
+
if self.vo != DEFAULT_VO:
|
|
67
68
|
trace['vo'] = self.vo
|
|
68
69
|
|
|
69
70
|
if rse:
|
|
@@ -29,7 +29,7 @@ from rucio.common.bittorrent import bittorrent_v2_merkle_sha256
|
|
|
29
29
|
from rucio.common.checksum import GLOBALLY_SUPPORTED_CHECKSUMS, adler32, md5
|
|
30
30
|
from rucio.common.client import detect_client_location
|
|
31
31
|
from rucio.common.config import config_get, config_get_bool, config_get_int
|
|
32
|
-
from rucio.common.constants import RseAttr
|
|
32
|
+
from rucio.common.constants import DEFAULT_VO, RseAttr
|
|
33
33
|
from rucio.common.exception import (
|
|
34
34
|
DataIdentifierAlreadyExists,
|
|
35
35
|
DataIdentifierNotFound,
|
|
@@ -120,7 +120,7 @@ class UploadClient:
|
|
|
120
120
|
'account': self.client.account,
|
|
121
121
|
'eventType': 'upload',
|
|
122
122
|
'eventVersion': version.RUCIO_VERSION[0],
|
|
123
|
-
'vo': self.client.vo if self.client.vo !=
|
|
123
|
+
'vo': self.client.vo if self.client.vo != DEFAULT_VO else None
|
|
124
124
|
}
|
|
125
125
|
|
|
126
126
|
def upload(
|
|
@@ -135,6 +135,7 @@ class UploadClient:
|
|
|
135
135
|
Uploads one or more files to an RSE (Rucio Storage Element) and optionally registers them.
|
|
136
136
|
|
|
137
137
|
An overview of this method's performed actions:
|
|
138
|
+
|
|
138
139
|
1. Collects and validates file info from the passed `items` (directories may be
|
|
139
140
|
also included), ensuring valid paths exist on the local filesystem. If an RSE
|
|
140
141
|
expression is provided, a single RSE is picked at random from it.
|
|
@@ -16,8 +16,7 @@ from typing import TYPE_CHECKING, Optional
|
|
|
16
16
|
|
|
17
17
|
from dogpile.cache.region import CacheRegion
|
|
18
18
|
|
|
19
|
-
from rucio.common.
|
|
20
|
-
from rucio.common.config import config_get
|
|
19
|
+
from rucio.common.config import config_get, is_client
|
|
21
20
|
|
|
22
21
|
if TYPE_CHECKING:
|
|
23
22
|
from collections.abc import Callable
|
|
@@ -17,44 +17,18 @@ import socket
|
|
|
17
17
|
from configparser import NoOptionError, NoSectionError
|
|
18
18
|
from typing import TYPE_CHECKING
|
|
19
19
|
|
|
20
|
-
from rucio.common.config import config_get
|
|
21
|
-
from rucio.common.
|
|
20
|
+
from rucio.common.config import config_get
|
|
21
|
+
from rucio.common.constants import DEFAULT_VO
|
|
22
22
|
|
|
23
23
|
if TYPE_CHECKING:
|
|
24
24
|
from rucio.common.types import IPWithLocationDict
|
|
25
25
|
|
|
26
26
|
|
|
27
|
-
def is_client() -> bool:
|
|
28
|
-
""""
|
|
29
|
-
Checks if the function is called from a client or from a server/daemon
|
|
30
|
-
|
|
31
|
-
:returns client_mode: True if is called from a client, False if it is called from a server/daemon
|
|
32
|
-
"""
|
|
33
|
-
if 'RUCIO_CLIENT_MODE' not in os.environ:
|
|
34
|
-
try:
|
|
35
|
-
if config_has_section('database'):
|
|
36
|
-
client_mode = False
|
|
37
|
-
elif config_has_section('client'):
|
|
38
|
-
client_mode = True
|
|
39
|
-
else:
|
|
40
|
-
client_mode = False
|
|
41
|
-
except (RuntimeError, ConfigNotFound):
|
|
42
|
-
# If no configuration file is found the default value should be True
|
|
43
|
-
client_mode = True
|
|
44
|
-
else:
|
|
45
|
-
if os.environ['RUCIO_CLIENT_MODE']:
|
|
46
|
-
client_mode = True
|
|
47
|
-
else:
|
|
48
|
-
client_mode = False
|
|
49
|
-
|
|
50
|
-
return client_mode
|
|
51
|
-
|
|
52
|
-
|
|
53
27
|
def get_client_vo() -> str:
|
|
54
28
|
"""
|
|
55
29
|
Get the client VO from the environment or the configuration file.
|
|
56
30
|
|
|
57
|
-
:returns vo: The client VO as a string; default =
|
|
31
|
+
:returns vo: The client VO as a string; default = DEFAULT_VO.
|
|
58
32
|
"""
|
|
59
33
|
if 'RUCIO_VO' in os.environ:
|
|
60
34
|
vo = os.environ['RUCIO_VO']
|
|
@@ -62,7 +36,7 @@ def get_client_vo() -> str:
|
|
|
62
36
|
try:
|
|
63
37
|
vo = str(config_get('client', 'vo'))
|
|
64
38
|
except (NoOptionError, NoSectionError):
|
|
65
|
-
vo =
|
|
39
|
+
vo = DEFAULT_VO
|
|
66
40
|
return vo
|
|
67
41
|
|
|
68
42
|
|
|
@@ -57,6 +57,32 @@ def _convert_to_boolean(value: Union[str, bool]) -> bool:
|
|
|
57
57
|
raise ValueError('Not a boolean: %s' % value)
|
|
58
58
|
|
|
59
59
|
|
|
60
|
+
def is_client() -> bool:
|
|
61
|
+
""""
|
|
62
|
+
Checks if the function is called from a client or from a server/daemon
|
|
63
|
+
|
|
64
|
+
:returns client_mode: True if is called from a client, False if it is called from a server/daemon
|
|
65
|
+
"""
|
|
66
|
+
if 'RUCIO_CLIENT_MODE' not in os.environ:
|
|
67
|
+
try:
|
|
68
|
+
if config_has_section('database'):
|
|
69
|
+
client_mode = False
|
|
70
|
+
elif config_has_section('client'):
|
|
71
|
+
client_mode = True
|
|
72
|
+
else:
|
|
73
|
+
client_mode = False
|
|
74
|
+
except (RuntimeError, ConfigNotFound):
|
|
75
|
+
# If no configuration file is found the default value should be True
|
|
76
|
+
client_mode = True
|
|
77
|
+
else:
|
|
78
|
+
if os.environ['RUCIO_CLIENT_MODE']:
|
|
79
|
+
client_mode = True
|
|
80
|
+
else:
|
|
81
|
+
client_mode = False
|
|
82
|
+
|
|
83
|
+
return client_mode
|
|
84
|
+
|
|
85
|
+
|
|
60
86
|
@overload
|
|
61
87
|
def config_get(
|
|
62
88
|
section: str,
|
|
@@ -192,7 +218,6 @@ def config_get(
|
|
|
192
218
|
return convert_type_fnc(get_config().get(section, option))
|
|
193
219
|
except (configparser.NoOptionError, configparser.NoSectionError, ConfigNotFound) as err:
|
|
194
220
|
|
|
195
|
-
from rucio.common.client import is_client
|
|
196
221
|
client_mode = is_client()
|
|
197
222
|
|
|
198
223
|
if not client_mode and check_config_table:
|
|
@@ -27,6 +27,8 @@ RESERVED_KEYS = ['scope', 'name', 'account', 'did_type', 'is_open', 'monotonic',
|
|
|
27
27
|
# collection_keys =
|
|
28
28
|
# file_keys =
|
|
29
29
|
|
|
30
|
+
DEFAULT_VO = 'def'
|
|
31
|
+
|
|
30
32
|
KEY_TYPES = ['ALL', 'COLLECTION', 'FILE', 'DERIVED']
|
|
31
33
|
# all(container, dataset, file), collection(dataset or container), file, derived(compute from file for collection)
|
|
32
34
|
|
|
@@ -213,4 +215,4 @@ RSE_ATTRS_BOOL = Literal[
|
|
|
213
215
|
]
|
|
214
216
|
|
|
215
217
|
SUPPORTED_SIGN_URL_SERVICES_LITERAL = Literal['gcs', 's3', 'swift']
|
|
216
|
-
SUPPORTED_SIGN_URL_SERVICES = list(get_args(SUPPORTED_SIGN_URL_SERVICES_LITERAL))
|
|
218
|
+
SUPPORTED_SIGN_URL_SERVICES = list(get_args(SUPPORTED_SIGN_URL_SERVICES_LITERAL))
|
|
@@ -21,7 +21,7 @@ from typing import TYPE_CHECKING, Any, TypeVar
|
|
|
21
21
|
from packaging.specifiers import SpecifierSet
|
|
22
22
|
|
|
23
23
|
from rucio.common import config
|
|
24
|
-
from rucio.common.client import get_client_vo
|
|
24
|
+
from rucio.common.client import get_client_vo
|
|
25
25
|
from rucio.common.exception import InvalidAlgorithmName, PolicyPackageIsNotVersioned, PolicyPackageVersionError
|
|
26
26
|
from rucio.version import current_version
|
|
27
27
|
|
|
@@ -132,7 +132,7 @@ class PolicyPackageAlgorithms:
|
|
|
132
132
|
cls._try_importing_policy()
|
|
133
133
|
else:
|
|
134
134
|
# on client, only register algorithms for selected VO
|
|
135
|
-
if is_client():
|
|
135
|
+
if config.is_client():
|
|
136
136
|
vo = get_client_vo()
|
|
137
137
|
cls._try_importing_policy(vo)
|
|
138
138
|
# on server, list all VOs and register their algorithms
|
|
@@ -23,6 +23,7 @@ from dogpile.cache import make_region
|
|
|
23
23
|
from dogpile.cache.api import NoValue
|
|
24
24
|
|
|
25
25
|
from rucio.common.config import config_get
|
|
26
|
+
from rucio.common.constants import DEFAULT_VO
|
|
26
27
|
from rucio.common.exception import UndefinedPolicy
|
|
27
28
|
|
|
28
29
|
if TYPE_CHECKING:
|
|
@@ -41,8 +42,8 @@ def get_policy(logger: 'LoggerFunction' = logging.log) -> str:
|
|
|
41
42
|
try:
|
|
42
43
|
policy = config_get('permission', 'policy')
|
|
43
44
|
except (NoOptionError, NoSectionError):
|
|
44
|
-
policy =
|
|
45
|
-
logger(logging.WARNING, "Policy not specified, falling back to
|
|
45
|
+
policy = DEFAULT_VO
|
|
46
|
+
logger(logging.WARNING, "Policy not specified, falling back to DEFAULT_VO")
|
|
46
47
|
policy = os.environ.get('POLICY', policy)
|
|
47
48
|
REGION.set('policy', policy)
|
|
48
49
|
return policy
|
|
@@ -22,6 +22,7 @@ from typing import TYPE_CHECKING, Any
|
|
|
22
22
|
from jsonschema import ValidationError, validate
|
|
23
23
|
|
|
24
24
|
from rucio.common import config, exception
|
|
25
|
+
from rucio.common.constants import DEFAULT_VO
|
|
25
26
|
from rucio.common.plugins import check_policy_module_version
|
|
26
27
|
|
|
27
28
|
if TYPE_CHECKING:
|
|
@@ -94,7 +95,7 @@ if not _is_multivo():
|
|
|
94
95
|
except ImportError:
|
|
95
96
|
raise exception.ErrorLoadingPolicyPackage(policy)
|
|
96
97
|
|
|
97
|
-
schema_modules[
|
|
98
|
+
schema_modules[DEFAULT_VO] = module
|
|
98
99
|
if hasattr(module, 'SCOPE_NAME_REGEXP'):
|
|
99
100
|
scope_name_regexps.append(module.SCOPE_NAME_REGEXP)
|
|
100
101
|
|
|
@@ -141,7 +142,7 @@ def load_schema_for_vo(vo: str) -> None:
|
|
|
141
142
|
schema_modules[vo] = module
|
|
142
143
|
|
|
143
144
|
|
|
144
|
-
def validate_schema(name: str, obj: Any, vo: str =
|
|
145
|
+
def validate_schema(name: str, obj: Any, vo: str = DEFAULT_VO) -> None:
|
|
145
146
|
if obj:
|
|
146
147
|
if vo not in schema_modules:
|
|
147
148
|
load_schema_for_vo(vo)
|
|
@@ -156,7 +157,7 @@ def validate_schema(name: str, obj: Any, vo: str = 'def') -> None:
|
|
|
156
157
|
raise exception.InvalidObject(f'Problem validating {name}: {error}')
|
|
157
158
|
|
|
158
159
|
|
|
159
|
-
def get_schema_value(key: str, vo: str =
|
|
160
|
+
def get_schema_value(key: str, vo: str = DEFAULT_VO) -> Any:
|
|
160
161
|
if vo not in schema_modules:
|
|
161
162
|
load_schema_for_vo(vo)
|
|
162
163
|
if not hasattr(schema_modules[vo], key):
|
|
@@ -16,6 +16,8 @@ import sys
|
|
|
16
16
|
from collections.abc import Callable
|
|
17
17
|
from os import PathLike
|
|
18
18
|
|
|
19
|
+
from rucio.common.constants import DEFAULT_VO
|
|
20
|
+
|
|
19
21
|
if sys.version_info < (3, 11): # pragma: no cover
|
|
20
22
|
from typing_extensions import TYPE_CHECKING, Any, Literal, NotRequired, Optional, TypedDict, TypeGuard, Union # noqa: UP035
|
|
21
23
|
PathTypeAlias = Union[PathLike, str]
|
|
@@ -35,7 +37,7 @@ class InternalType:
|
|
|
35
37
|
'''
|
|
36
38
|
Base for Internal representations of string types
|
|
37
39
|
'''
|
|
38
|
-
def __init__(self, value: Optional[str], vo: str =
|
|
40
|
+
def __init__(self, value: Optional[str], vo: str = DEFAULT_VO, from_external: bool = True):
|
|
39
41
|
if value is None:
|
|
40
42
|
self.external = None
|
|
41
43
|
self.internal = None
|
|
@@ -87,7 +89,7 @@ class _RepresentationCalculator:
|
|
|
87
89
|
"""
|
|
88
90
|
split = internal.split('@', 1)
|
|
89
91
|
if len(split) == 1: # if cannot convert, vo is '' and this is single vo
|
|
90
|
-
vo =
|
|
92
|
+
vo = DEFAULT_VO
|
|
91
93
|
external = split[0]
|
|
92
94
|
else:
|
|
93
95
|
vo = split[1]
|
|
@@ -104,7 +106,7 @@ class _RepresentationCalculator:
|
|
|
104
106
|
|
|
105
107
|
:returns: internal representation
|
|
106
108
|
"""
|
|
107
|
-
if vo ==
|
|
109
|
+
if vo == DEFAULT_VO:
|
|
108
110
|
return external
|
|
109
111
|
internal = '{}@{}'.format(external, vo)
|
|
110
112
|
return internal
|
|
@@ -114,7 +116,7 @@ class InternalAccount(InternalType):
|
|
|
114
116
|
'''
|
|
115
117
|
Internal representation of an account
|
|
116
118
|
'''
|
|
117
|
-
def __init__(self, account: Optional[str], vo: str =
|
|
119
|
+
def __init__(self, account: Optional[str], vo: str = DEFAULT_VO, from_external: bool = True):
|
|
118
120
|
super(InternalAccount, self).__init__(value=account, vo=vo, from_external=from_external)
|
|
119
121
|
|
|
120
122
|
|
|
@@ -122,7 +124,7 @@ class InternalScope(InternalType):
|
|
|
122
124
|
'''
|
|
123
125
|
Internal representation of a scope
|
|
124
126
|
'''
|
|
125
|
-
def __init__(self, scope: Optional[str], vo: str =
|
|
127
|
+
def __init__(self, scope: Optional[str], vo: str = DEFAULT_VO, from_external: bool = True):
|
|
126
128
|
super(InternalScope, self).__init__(value=scope, vo=vo, from_external=from_external)
|
|
127
129
|
|
|
128
130
|
|