rucio-clients 35.5.0__tar.gz → 35.6.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of rucio-clients might be problematic. Click here for more details.
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/PKG-INFO +1 -1
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/bin/rucio +20 -19
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/lib/rucio/common/exception.py +47 -12
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/lib/rucio/common/schema/__init__.py +4 -4
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/lib/rucio/vcsversion.py +3 -3
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/tests/test_replica_sorting.py +22 -1
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/tests/test_transfer_plugins.py +88 -75
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/AUTHORS.rst +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/ChangeLog +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/LICENSE +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/MANIFEST.in +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/README.md +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/bin/rucio-admin +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/etc/rse-accounts.cfg.template +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/etc/rucio.cfg.atlas.client.template +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/etc/rucio.cfg.template +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/lib/rucio/__init__.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/lib/rucio/alembicrevision.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/lib/rucio/client/__init__.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/lib/rucio/client/accountclient.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/lib/rucio/client/accountlimitclient.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/lib/rucio/client/baseclient.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/lib/rucio/client/client.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/lib/rucio/client/configclient.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/lib/rucio/client/credentialclient.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/lib/rucio/client/didclient.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/lib/rucio/client/diracclient.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/lib/rucio/client/downloadclient.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/lib/rucio/client/exportclient.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/lib/rucio/client/fileclient.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/lib/rucio/client/importclient.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/lib/rucio/client/lifetimeclient.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/lib/rucio/client/lockclient.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/lib/rucio/client/metaconventionsclient.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/lib/rucio/client/pingclient.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/lib/rucio/client/replicaclient.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/lib/rucio/client/requestclient.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/lib/rucio/client/rseclient.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/lib/rucio/client/ruleclient.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/lib/rucio/client/scopeclient.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/lib/rucio/client/subscriptionclient.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/lib/rucio/client/touchclient.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/lib/rucio/client/uploadclient.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/lib/rucio/common/__init__.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/lib/rucio/common/cache.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/lib/rucio/common/config.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/lib/rucio/common/constants.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/lib/rucio/common/constraints.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/lib/rucio/common/didtype.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/lib/rucio/common/extra.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/lib/rucio/common/logging.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/lib/rucio/common/pcache.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/lib/rucio/common/plugins.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/lib/rucio/common/policy.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/lib/rucio/common/schema/atlas.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/lib/rucio/common/schema/belleii.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/lib/rucio/common/schema/domatpc.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/lib/rucio/common/schema/escape.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/lib/rucio/common/schema/generic.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/lib/rucio/common/schema/generic_multi_vo.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/lib/rucio/common/schema/icecube.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/lib/rucio/common/stomp_utils.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/lib/rucio/common/stopwatch.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/lib/rucio/common/test_rucio_server.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/lib/rucio/common/types.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/lib/rucio/common/utils.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/lib/rucio/rse/__init__.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/lib/rucio/rse/protocols/__init__.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/lib/rucio/rse/protocols/bittorrent.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/lib/rucio/rse/protocols/cache.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/lib/rucio/rse/protocols/dummy.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/lib/rucio/rse/protocols/gfal.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/lib/rucio/rse/protocols/globus.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/lib/rucio/rse/protocols/gsiftp.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/lib/rucio/rse/protocols/http_cache.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/lib/rucio/rse/protocols/mock.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/lib/rucio/rse/protocols/ngarc.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/lib/rucio/rse/protocols/posix.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/lib/rucio/rse/protocols/protocol.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/lib/rucio/rse/protocols/rclone.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/lib/rucio/rse/protocols/rfio.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/lib/rucio/rse/protocols/srm.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/lib/rucio/rse/protocols/ssh.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/lib/rucio/rse/protocols/storm.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/lib/rucio/rse/protocols/webdav.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/lib/rucio/rse/protocols/xrootd.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/lib/rucio/rse/rsemanager.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/lib/rucio/version.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/lib/rucio_clients.egg-info/SOURCES.txt +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/pylintrc +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/pyproject.toml +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/requirements/requirements.client.txt +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/setup.cfg +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/setup.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/setuputil.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/tests/test_abacus_account.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/tests/test_abacus_collection_replica.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/tests/test_abacus_rse.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/tests/test_account.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/tests/test_account_limits.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/tests/test_archive.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/tests/test_auditor.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/tests/test_auditor_hdfs.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/tests/test_auditor_srmdumps.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/tests/test_authentication.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/tests/test_automatix.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/tests/test_bad_replica.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/tests/test_bb8.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/tests/test_belleii.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/tests/test_bin_rucio.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/tests/test_boolean.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/tests/test_clients.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/tests/test_common_types.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/tests/test_config.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/tests/test_conveyor.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/tests/test_conveyor_submitter.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/tests/test_counter.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/tests/test_credential.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/tests/test_curl.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/tests/test_daemons.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/tests/test_dataset_replicas.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/tests/test_db.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/tests/test_did.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/tests/test_did_meta_plugins.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/tests/test_didtype.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/tests/test_download.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/tests/test_dumper.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/tests/test_dumper_consistency.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/tests/test_dumper_data_model.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/tests/test_dumper_path_parsing.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/tests/test_filter_engine.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/tests/test_gateway_external_representation.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/tests/test_heartbeat.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/tests/test_hermes.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/tests/test_identity.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/tests/test_impl_upload_download.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/tests/test_import_export.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/tests/test_judge_cleaner.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/tests/test_judge_evaluator.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/tests/test_judge_injector.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/tests/test_judge_repairer.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/tests/test_lifetime.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/tests/test_message.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/tests/test_meta_conventions.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/tests/test_meta_did.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/tests/test_module_import.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/tests/test_monitor.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/tests/test_multi_vo.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/tests/test_naming_convention.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/tests/test_oauthmanager.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/tests/test_oidc.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/tests/test_permission.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/tests/test_pfns.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/tests/test_ping.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/tests/test_preparer.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/tests/test_qos.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/tests/test_quarantined_replica.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/tests/test_reaper.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/tests/test_redirect.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/tests/test_replica.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/tests/test_replica_recoverer.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/tests/test_request.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/tests/test_root_proxy.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/tests/test_rse.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/tests/test_rse_expression_parser.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/tests/test_rse_lfn2path.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/tests/test_rse_protocol_gfal2.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/tests/test_rse_protocol_gfal2_impl.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/tests/test_rse_protocol_posix.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/tests/test_rse_protocol_rclone.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/tests/test_rse_protocol_rsync.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/tests/test_rse_protocol_srm.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/tests/test_rse_protocol_ssh.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/tests/test_rse_protocol_webdav.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/tests/test_rse_protocol_xrootd.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/tests/test_rse_selector.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/tests/test_rucio_server.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/tests/test_rule.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/tests/test_scope.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/tests/test_subscription.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/tests/test_throttler.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/tests/test_tpc.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/tests/test_trace.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/tests/test_transfer.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/tests/test_undertaker.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/tests/test_upload.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/tests/test_utils.py +0 -0
- {rucio_clients-35.5.0 → rucio_clients-35.6.0}/tools/merge_rucio_configs.py +0 -0
|
@@ -412,7 +412,7 @@ def list_file_replicas(args):
|
|
|
412
412
|
pfn_dir, dst_dir = args.link.split(':')
|
|
413
413
|
if args.rses:
|
|
414
414
|
for replica, rse in itertools.product(replicas, rses):
|
|
415
|
-
if
|
|
415
|
+
if replica['rses'].get(rse):
|
|
416
416
|
for pfn in replica['rses'][rse]:
|
|
417
417
|
os.symlink(dst_dir + pfn.rsplit(pfn_dir)[-1], replica['name'])
|
|
418
418
|
else:
|
|
@@ -423,16 +423,17 @@ def list_file_replicas(args):
|
|
|
423
423
|
os.symlink(dst_dir + pfn.rsplit(pfn_dir)[-1], replica['name'])
|
|
424
424
|
elif args.pfns:
|
|
425
425
|
if args.rses:
|
|
426
|
-
for replica
|
|
427
|
-
|
|
428
|
-
|
|
426
|
+
for replica in replicas:
|
|
427
|
+
for pfn in replica['pfns']:
|
|
428
|
+
rse = replica['pfns'][pfn]['rse']
|
|
429
|
+
if replica['rses'].get(rse):
|
|
429
430
|
print(pfn)
|
|
430
431
|
else:
|
|
431
432
|
for replica in replicas:
|
|
432
|
-
for
|
|
433
|
+
for pfn in replica['pfns']:
|
|
434
|
+
rse = replica['pfns'][pfn]['rse']
|
|
433
435
|
if replica['rses'][rse]:
|
|
434
|
-
|
|
435
|
-
print(pfn)
|
|
436
|
+
print(pfn)
|
|
436
437
|
else:
|
|
437
438
|
if args.all_states:
|
|
438
439
|
header = ['SCOPE', 'NAME', 'FILESIZE', 'ADLER32', '(STATE) RSE: REPLICA']
|
|
@@ -440,18 +441,18 @@ def list_file_replicas(args):
|
|
|
440
441
|
header = ['SCOPE', 'NAME', 'FILESIZE', 'ADLER32', 'RSE: REPLICA']
|
|
441
442
|
for replica in replicas:
|
|
442
443
|
if 'bytes' in replica:
|
|
443
|
-
for
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
444
|
+
for pfn in replica['pfns']:
|
|
445
|
+
rse = replica['pfns'][pfn]['rse']
|
|
446
|
+
if args.all_states:
|
|
447
|
+
rse_string = '({2}) {0}: {1}'.format(rse, pfn, ReplicaState[replica['states'][rse]].value)
|
|
448
|
+
else:
|
|
449
|
+
rse_string = '{0}: {1}'.format(rse, pfn)
|
|
450
|
+
if args.rses:
|
|
451
|
+
for selected_rse in rses:
|
|
452
|
+
if rse == selected_rse:
|
|
453
|
+
table.append([replica['scope'], replica['name'], sizefmt(replica['bytes'], args.human), replica['adler32'], rse_string])
|
|
454
|
+
else:
|
|
455
|
+
table.append([replica['scope'], replica['name'], sizefmt(replica['bytes'], args.human), replica['adler32'], rse_string])
|
|
455
456
|
print(tabulate(table, tablefmt=tablefmt, headers=header, disable_numparse=True))
|
|
456
457
|
return SUCCESS
|
|
457
458
|
|
|
@@ -955,13 +955,22 @@ class NoDistance(RucioException):
|
|
|
955
955
|
self.error_code = 92
|
|
956
956
|
|
|
957
957
|
|
|
958
|
-
class
|
|
958
|
+
class PolicyPackageBaseException(RucioException):
|
|
959
|
+
"""
|
|
960
|
+
Base exception for policy package errors.
|
|
961
|
+
"""
|
|
962
|
+
def __init__(self, package: str, *args):
|
|
963
|
+
super(PolicyPackageBaseException, self).__init__(*args)
|
|
964
|
+
self.package = package
|
|
965
|
+
|
|
966
|
+
|
|
967
|
+
class PolicyPackageNotFound(PolicyPackageBaseException):
|
|
959
968
|
"""
|
|
960
969
|
The policy package specified in the config file was not found
|
|
961
970
|
"""
|
|
962
|
-
def __init__(self, *args):
|
|
963
|
-
super(PolicyPackageNotFound, self).__init__(*args)
|
|
964
|
-
self._message = 'The specified policy package was not found'
|
|
971
|
+
def __init__(self, package: str, *args):
|
|
972
|
+
super(PolicyPackageNotFound, self).__init__(package, *args)
|
|
973
|
+
self._message = 'The specified policy package %s was not found' % self.package
|
|
965
974
|
self.error_code = 93
|
|
966
975
|
|
|
967
976
|
|
|
@@ -1055,13 +1064,19 @@ class MetadataSchemaMismatchError(RucioException):
|
|
|
1055
1064
|
self.error_code = 102
|
|
1056
1065
|
|
|
1057
1066
|
|
|
1058
|
-
class PolicyPackageVersionError(
|
|
1067
|
+
class PolicyPackageVersionError(PolicyPackageBaseException):
|
|
1059
1068
|
"""
|
|
1060
1069
|
Policy package is not compatible with this version of Rucio.
|
|
1061
1070
|
"""
|
|
1062
|
-
def __init__(self, package, *args):
|
|
1063
|
-
super(PolicyPackageVersionError, self).__init__(*args)
|
|
1064
|
-
self.
|
|
1071
|
+
def __init__(self, package: str, rucio_version: str, supported_versions: list[str], *args):
|
|
1072
|
+
super(PolicyPackageVersionError, self).__init__(package, *args)
|
|
1073
|
+
self.rucio_version = rucio_version
|
|
1074
|
+
self.supported_versions = supported_versions
|
|
1075
|
+
self._message = 'Policy package %s is not compatible with this Rucio version.\nRucio version: %s\nVersions supported by the package: %s' % (
|
|
1076
|
+
self.package,
|
|
1077
|
+
self.rucio_version,
|
|
1078
|
+
self.supported_versions
|
|
1079
|
+
)
|
|
1065
1080
|
self.error_code = 103
|
|
1066
1081
|
|
|
1067
1082
|
|
|
@@ -1096,13 +1111,13 @@ class SortingAlgorithmNotSupported(RucioException):
|
|
|
1096
1111
|
self.error_code = 106
|
|
1097
1112
|
|
|
1098
1113
|
|
|
1099
|
-
class ErrorLoadingPolicyPackage(
|
|
1114
|
+
class ErrorLoadingPolicyPackage(PolicyPackageBaseException):
|
|
1100
1115
|
"""
|
|
1101
1116
|
An error occurred while loading the policy package.
|
|
1102
1117
|
"""
|
|
1103
|
-
def __init__(self, *args):
|
|
1104
|
-
super(ErrorLoadingPolicyPackage, self).__init__(*args)
|
|
1105
|
-
self._message = 'An error occurred while loading the
|
|
1118
|
+
def __init__(self, package: str, *args):
|
|
1119
|
+
super(ErrorLoadingPolicyPackage, self).__init__(package, *args)
|
|
1120
|
+
self._message = 'An error occurred while loading the policy package %s' % self.package
|
|
1106
1121
|
self.error_code = 107
|
|
1107
1122
|
|
|
1108
1123
|
|
|
@@ -1114,3 +1129,23 @@ class TraceValidationSchemaNotFound(RucioException):
|
|
|
1114
1129
|
super(TraceValidationSchemaNotFound, self).__init__(*args, **kwargs)
|
|
1115
1130
|
self._message = 'Trace validation schema not found.'
|
|
1116
1131
|
self.error_code = 108
|
|
1132
|
+
|
|
1133
|
+
|
|
1134
|
+
class PolicyPackageIsNotVersioned(PolicyPackageBaseException):
|
|
1135
|
+
"""
|
|
1136
|
+
Policy package does not contain version information.
|
|
1137
|
+
"""
|
|
1138
|
+
def __init__(self, package: str, *args):
|
|
1139
|
+
super(PolicyPackageIsNotVersioned, self).__init__(package, *args)
|
|
1140
|
+
self._message = 'Policy package %s does not include information about which Rucio versions it supports.' % self.package
|
|
1141
|
+
self.error_code = 109
|
|
1142
|
+
|
|
1143
|
+
|
|
1144
|
+
class UnsupportedMetadataPlugin(RucioException):
|
|
1145
|
+
"""
|
|
1146
|
+
Raised when attempting to use a metadata plugin that is not enabled on the server.
|
|
1147
|
+
"""
|
|
1148
|
+
def __init__(self, *args):
|
|
1149
|
+
super(UnsupportedMetadataPlugin, self).__init__(*args)
|
|
1150
|
+
self._message = "The requested metadata plugin is not enabled on the server."
|
|
1151
|
+
self.error_code = 110
|
|
@@ -61,9 +61,9 @@ if not multivo:
|
|
|
61
61
|
try:
|
|
62
62
|
module = importlib.import_module(POLICY)
|
|
63
63
|
except ModuleNotFoundError:
|
|
64
|
-
raise exception.PolicyPackageNotFound(
|
|
64
|
+
raise exception.PolicyPackageNotFound(POLICY)
|
|
65
65
|
except ImportError:
|
|
66
|
-
raise exception.ErrorLoadingPolicyPackage(
|
|
66
|
+
raise exception.ErrorLoadingPolicyPackage(POLICY)
|
|
67
67
|
|
|
68
68
|
schema_modules["def"] = module
|
|
69
69
|
scope_name_regexps.append(module.SCOPE_NAME_REGEXP)
|
|
@@ -93,9 +93,9 @@ def load_schema_for_vo(vo: str) -> None:
|
|
|
93
93
|
try:
|
|
94
94
|
module = importlib.import_module(POLICY)
|
|
95
95
|
except ModuleNotFoundError:
|
|
96
|
-
raise exception.PolicyPackageNotFound(
|
|
96
|
+
raise exception.PolicyPackageNotFound(POLICY)
|
|
97
97
|
except ImportError:
|
|
98
|
-
raise exception.ErrorLoadingPolicyPackage(
|
|
98
|
+
raise exception.ErrorLoadingPolicyPackage(POLICY)
|
|
99
99
|
|
|
100
100
|
schema_modules[vo] = module
|
|
101
101
|
|
|
@@ -4,8 +4,8 @@ This file is automatically generated; Do not edit it. :)
|
|
|
4
4
|
'''
|
|
5
5
|
VERSION_INFO = {
|
|
6
6
|
'final': True,
|
|
7
|
-
'version': '35.
|
|
7
|
+
'version': '35.6.0',
|
|
8
8
|
'branch_nick': 'release-35-LTS',
|
|
9
|
-
'revision_id': '
|
|
10
|
-
'revno':
|
|
9
|
+
'revision_id': '76a17347408868f403f602b5bf626c9744620829',
|
|
10
|
+
'revno': 13190
|
|
11
11
|
}
|
|
@@ -22,6 +22,7 @@ from urllib.parse import urlparse
|
|
|
22
22
|
import geoip2.database
|
|
23
23
|
import pytest
|
|
24
24
|
|
|
25
|
+
import rucio.core.config as core_config
|
|
25
26
|
from rucio.common.config import config_get
|
|
26
27
|
from rucio.common.constants import RseAttr
|
|
27
28
|
from rucio.common.utils import parse_replicas_from_string
|
|
@@ -448,7 +449,7 @@ def test_not_sorting_lan_replicas(vo, rest_client, auth_token, protocols_setup,
|
|
|
448
449
|
@pytest.mark.noparallel(reason='fails when run in parallel')
|
|
449
450
|
@pytest.mark.parametrize("content_type", [Mime.METALINK, Mime.JSON_STREAM])
|
|
450
451
|
def test_sort_geoip_address_not_found_error(vo, rest_client, auth_token, protocols_setup, content_type):
|
|
451
|
-
"""Replicas: test sorting via geoip with ignoring geoip errors."""
|
|
452
|
+
"""Replicas: test sorting via geoip with ignoring geoip errors (and without)."""
|
|
452
453
|
|
|
453
454
|
class MockedGeoIPError(Exception):
|
|
454
455
|
def __init__(self, *args):
|
|
@@ -479,6 +480,26 @@ def test_sort_geoip_address_not_found_error(vo, rest_client, auth_token, protoco
|
|
|
479
480
|
|
|
480
481
|
get_geoip_db_mock.assert_called()
|
|
481
482
|
|
|
483
|
+
# now set config to not ignore errors
|
|
484
|
+
core_config.set("core", "geoip_ignore_error", False)
|
|
485
|
+
|
|
486
|
+
# invalidate cache for __get_distance so that __get_geoip_db is called
|
|
487
|
+
replica_sorter.REGION.invalidate()
|
|
488
|
+
|
|
489
|
+
with mock.patch('rucio.core.replica_sorter.__geoip_db', side_effect=fake_get_geoip_db) as get_geoip_db_mock:
|
|
490
|
+
response = rest_client.post(
|
|
491
|
+
'/replicas/list',
|
|
492
|
+
headers=headers(auth(auth_token), vohdr(vo), accept(content_type)),
|
|
493
|
+
json=data
|
|
494
|
+
)
|
|
495
|
+
# this time the call should fail
|
|
496
|
+
assert response.status_code != 200
|
|
497
|
+
|
|
498
|
+
get_geoip_db_mock.assert_called()
|
|
499
|
+
|
|
500
|
+
# reset to ignore errors for other tests
|
|
501
|
+
core_config.set("core", "geoip_ignore_error", True)
|
|
502
|
+
|
|
482
503
|
|
|
483
504
|
@pytest.mark.noparallel(reason='fails when run in parallel, replicas should not be changed')
|
|
484
505
|
def test_get_sorted_list_replicas_no_metalink(vo, rest_client, auth_token, protocols_setup, mock_scope):
|
|
@@ -25,6 +25,7 @@ from rucio.core.topology import Topology
|
|
|
25
25
|
from rucio.core.transfer import ProtocolFactory, build_transfer_paths
|
|
26
26
|
from rucio.db.sqla.session import get_session
|
|
27
27
|
from rucio.transfertool.fts3 import FTS3Transfertool, build_job_params
|
|
28
|
+
from rucio.transfertool.fts3_plugins import FTS3TapeMetadataPlugin
|
|
28
29
|
|
|
29
30
|
mock_session = get_session()
|
|
30
31
|
|
|
@@ -108,7 +109,7 @@ def test_scheduling_hints(file_config_mock, did_factory, rse_factory, root_accou
|
|
|
108
109
|
assert len(job_params["archive_metadata"].keys()) == 1
|
|
109
110
|
generated_scheduling_hints = job_params["archive_metadata"]["scheduling_hints"]
|
|
110
111
|
|
|
111
|
-
expected_scheduling_hints = {"priority":
|
|
112
|
+
expected_scheduling_hints = {"priority": 100}
|
|
112
113
|
assert expected_scheduling_hints == generated_scheduling_hints
|
|
113
114
|
|
|
114
115
|
|
|
@@ -150,93 +151,105 @@ def test_activity_missing(file_config_mock, did_factory, rse_factory, root_accou
|
|
|
150
151
|
assert "archive_metadata" in job_params
|
|
151
152
|
generated_scheduling_hints = job_params["archive_metadata"]["scheduling_hints"]
|
|
152
153
|
|
|
153
|
-
expected_scheduling_hints = {"priority":
|
|
154
|
+
expected_scheduling_hints = {"priority": 20}
|
|
154
155
|
assert expected_scheduling_hints == generated_scheduling_hints
|
|
155
156
|
|
|
156
157
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
(
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
def test_collocation_hints(file_config_mock, did_factory, rse_factory, root_account):
|
|
165
|
-
"""For a mock collocation algorithm, it can produce the 4 levels of hints required for each did"""
|
|
158
|
+
class TestCollocationHints:
|
|
159
|
+
class TestCollocationPlugin(FTS3TapeMetadataPlugin):
|
|
160
|
+
def __init__(self) -> None:
|
|
161
|
+
self.register(
|
|
162
|
+
'test',
|
|
163
|
+
func=lambda x: self._test_collocation(x))
|
|
164
|
+
super().__init__('test')
|
|
166
165
|
|
|
167
|
-
|
|
168
|
-
|
|
166
|
+
def _test_collocation(self, hints: dict[str, str]) -> dict[str, dict]:
|
|
167
|
+
return {"collocation_hints": {"0": "", "1": "", "2": "", "3": ""}}
|
|
169
168
|
|
|
170
|
-
|
|
171
|
-
fts3_tool = FTS3Transfertool(TEST_FTS_HOST)
|
|
169
|
+
TestCollocationPlugin()
|
|
172
170
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
max_time_in_queue=None,
|
|
179
|
-
logger=logging.log,
|
|
180
|
-
)
|
|
181
|
-
|
|
182
|
-
# Get the job params used for each transfer
|
|
183
|
-
job_params = fts3_tool._file_from_transfer(transfer_path[0], job_params)
|
|
184
|
-
|
|
185
|
-
expected_collocation_hints = {
|
|
186
|
-
"collocation_hints": {
|
|
187
|
-
"0": "",
|
|
188
|
-
"1": "",
|
|
189
|
-
"2": "",
|
|
190
|
-
"3": "",
|
|
171
|
+
@pytest.mark.parametrize("file_config_mock", [
|
|
172
|
+
{
|
|
173
|
+
"overrides": [
|
|
174
|
+
("transfers", "fts3tape_metadata_plugins", "test")
|
|
175
|
+
]
|
|
191
176
|
}
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
177
|
+
], indirect=True)
|
|
178
|
+
def test_collocation_hints(self, file_config_mock, did_factory, rse_factory, root_account):
|
|
179
|
+
"""For a mock collocation algorithm, it can produce the 4 levels of hints required for each did"""
|
|
180
|
+
|
|
181
|
+
mock_did = did_factory.random_file_did()
|
|
182
|
+
transfer_path = _make_transfer_path(mock_did, rse_factory, root_account)
|
|
183
|
+
|
|
184
|
+
# Mock Transfer Tool
|
|
185
|
+
fts3_tool = FTS3Transfertool(TEST_FTS_HOST)
|
|
186
|
+
|
|
187
|
+
job_params = build_job_params(
|
|
188
|
+
transfer_path=transfer_path,
|
|
189
|
+
bring_online=None,
|
|
190
|
+
default_lifetime=None,
|
|
191
|
+
archive_timeout_override=None,
|
|
192
|
+
max_time_in_queue=None,
|
|
193
|
+
logger=logging.log,
|
|
194
|
+
)
|
|
195
|
+
|
|
196
|
+
# Get the job params used for each transfer
|
|
197
|
+
job_params = fts3_tool._file_from_transfer(transfer_path[0], job_params)
|
|
211
198
|
|
|
212
|
-
|
|
213
|
-
|
|
199
|
+
expected_collocation_hints = {
|
|
200
|
+
"collocation_hints": {
|
|
201
|
+
"0": "",
|
|
202
|
+
"1": "",
|
|
203
|
+
"2": "",
|
|
204
|
+
"3": "",
|
|
205
|
+
}
|
|
206
|
+
}
|
|
214
207
|
|
|
215
|
-
|
|
216
|
-
|
|
208
|
+
assert "archive_metadata" in job_params
|
|
209
|
+
generated_collocation_hints = job_params["archive_metadata"]["collocation_hints"]
|
|
217
210
|
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
default_lifetime=None,
|
|
222
|
-
archive_timeout_override=None,
|
|
223
|
-
max_time_in_queue=None,
|
|
224
|
-
logger=logging.log,
|
|
225
|
-
)
|
|
211
|
+
assert (
|
|
212
|
+
expected_collocation_hints["collocation_hints"] == generated_collocation_hints
|
|
213
|
+
)
|
|
226
214
|
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
215
|
+
@pytest.mark.parametrize("file_config_mock", [
|
|
216
|
+
{
|
|
217
|
+
"overrides": [
|
|
218
|
+
("transfers", "fts3tape_metadata_plugins", "activity, test")
|
|
219
|
+
]
|
|
220
|
+
}
|
|
221
|
+
], indirect=True)
|
|
222
|
+
def test_multiple_plugin_concat(self, file_config_mock, did_factory, rse_factory, root_account):
|
|
223
|
+
"""When multiple plugins are used (like priority and collocation), both logics are applied"""
|
|
224
|
+
|
|
225
|
+
mock_did = did_factory.random_file_did()
|
|
226
|
+
transfer_path = _make_transfer_path(mock_did, rse_factory, root_account)
|
|
227
|
+
|
|
228
|
+
# Mock Transfer Tool
|
|
229
|
+
fts3_tool = FTS3Transfertool(TEST_FTS_HOST)
|
|
230
|
+
|
|
231
|
+
job_params = build_job_params(
|
|
232
|
+
transfer_path=transfer_path,
|
|
233
|
+
bring_online=None,
|
|
234
|
+
default_lifetime=None,
|
|
235
|
+
archive_timeout_override=None,
|
|
236
|
+
max_time_in_queue=None,
|
|
237
|
+
logger=logging.log,
|
|
238
|
+
)
|
|
239
|
+
|
|
240
|
+
# Get the job params used for each transfer
|
|
241
|
+
job_params = fts3_tool._file_from_transfer(transfer_path[0], job_params)
|
|
242
|
+
expected_hints = {
|
|
243
|
+
"scheduling_hints": {"priority": 20},
|
|
244
|
+
"collocation_hints": {"0": "", "1": "", "2": "", "3": ""},
|
|
245
|
+
}
|
|
246
|
+
assert "archive_metadata" in job_params
|
|
234
247
|
|
|
235
|
-
|
|
236
|
-
|
|
248
|
+
generated_collocation_hints = job_params["archive_metadata"]["collocation_hints"]
|
|
249
|
+
assert expected_hints["collocation_hints"] == generated_collocation_hints
|
|
237
250
|
|
|
238
|
-
|
|
239
|
-
|
|
251
|
+
generated_scheduling_hints = job_params["archive_metadata"]["scheduling_hints"]
|
|
252
|
+
assert expected_hints["scheduling_hints"] == generated_scheduling_hints
|
|
240
253
|
|
|
241
254
|
|
|
242
255
|
@pytest.mark.parametrize("file_config_mock", [
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|