rucio 37.0.0rc1__py3-none-any.whl
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 might be problematic. Click here for more details.
- rucio/__init__.py +17 -0
- rucio/alembicrevision.py +15 -0
- rucio/cli/__init__.py +14 -0
- rucio/cli/account.py +216 -0
- rucio/cli/bin_legacy/__init__.py +13 -0
- rucio/cli/bin_legacy/rucio.py +2825 -0
- rucio/cli/bin_legacy/rucio_admin.py +2500 -0
- rucio/cli/command.py +272 -0
- rucio/cli/config.py +72 -0
- rucio/cli/did.py +191 -0
- rucio/cli/download.py +128 -0
- rucio/cli/lifetime_exception.py +33 -0
- rucio/cli/replica.py +162 -0
- rucio/cli/rse.py +293 -0
- rucio/cli/rule.py +158 -0
- rucio/cli/scope.py +40 -0
- rucio/cli/subscription.py +73 -0
- rucio/cli/upload.py +60 -0
- rucio/cli/utils.py +226 -0
- rucio/client/__init__.py +15 -0
- rucio/client/accountclient.py +432 -0
- rucio/client/accountlimitclient.py +183 -0
- rucio/client/baseclient.py +983 -0
- rucio/client/client.py +120 -0
- rucio/client/configclient.py +126 -0
- rucio/client/credentialclient.py +59 -0
- rucio/client/didclient.py +868 -0
- rucio/client/diracclient.py +56 -0
- rucio/client/downloadclient.py +1783 -0
- rucio/client/exportclient.py +44 -0
- rucio/client/fileclient.py +50 -0
- rucio/client/importclient.py +42 -0
- rucio/client/lifetimeclient.py +90 -0
- rucio/client/lockclient.py +109 -0
- rucio/client/metaconventionsclient.py +140 -0
- rucio/client/pingclient.py +44 -0
- rucio/client/replicaclient.py +452 -0
- rucio/client/requestclient.py +125 -0
- rucio/client/richclient.py +317 -0
- rucio/client/rseclient.py +746 -0
- rucio/client/ruleclient.py +294 -0
- rucio/client/scopeclient.py +90 -0
- rucio/client/subscriptionclient.py +173 -0
- rucio/client/touchclient.py +82 -0
- rucio/client/uploadclient.py +969 -0
- rucio/common/__init__.py +13 -0
- rucio/common/bittorrent.py +234 -0
- rucio/common/cache.py +111 -0
- rucio/common/checksum.py +168 -0
- rucio/common/client.py +122 -0
- rucio/common/config.py +788 -0
- rucio/common/constants.py +217 -0
- rucio/common/constraints.py +17 -0
- rucio/common/didtype.py +237 -0
- rucio/common/dumper/__init__.py +342 -0
- rucio/common/dumper/consistency.py +497 -0
- rucio/common/dumper/data_models.py +362 -0
- rucio/common/dumper/path_parsing.py +75 -0
- rucio/common/exception.py +1208 -0
- rucio/common/extra.py +31 -0
- rucio/common/logging.py +420 -0
- rucio/common/pcache.py +1409 -0
- rucio/common/plugins.py +185 -0
- rucio/common/policy.py +93 -0
- rucio/common/schema/__init__.py +200 -0
- rucio/common/schema/generic.py +416 -0
- rucio/common/schema/generic_multi_vo.py +395 -0
- rucio/common/stomp_utils.py +423 -0
- rucio/common/stopwatch.py +55 -0
- rucio/common/test_rucio_server.py +154 -0
- rucio/common/types.py +483 -0
- rucio/common/utils.py +1688 -0
- rucio/core/__init__.py +13 -0
- rucio/core/account.py +496 -0
- rucio/core/account_counter.py +236 -0
- rucio/core/account_limit.py +425 -0
- rucio/core/authentication.py +620 -0
- rucio/core/config.py +437 -0
- rucio/core/credential.py +224 -0
- rucio/core/did.py +3004 -0
- rucio/core/did_meta_plugins/__init__.py +252 -0
- rucio/core/did_meta_plugins/did_column_meta.py +331 -0
- rucio/core/did_meta_plugins/did_meta_plugin_interface.py +165 -0
- rucio/core/did_meta_plugins/elasticsearch_meta.py +407 -0
- rucio/core/did_meta_plugins/filter_engine.py +672 -0
- rucio/core/did_meta_plugins/json_meta.py +240 -0
- rucio/core/did_meta_plugins/mongo_meta.py +229 -0
- rucio/core/did_meta_plugins/postgres_meta.py +352 -0
- rucio/core/dirac.py +237 -0
- rucio/core/distance.py +187 -0
- rucio/core/exporter.py +59 -0
- rucio/core/heartbeat.py +363 -0
- rucio/core/identity.py +301 -0
- rucio/core/importer.py +260 -0
- rucio/core/lifetime_exception.py +377 -0
- rucio/core/lock.py +577 -0
- rucio/core/message.py +288 -0
- rucio/core/meta_conventions.py +203 -0
- rucio/core/monitor.py +448 -0
- rucio/core/naming_convention.py +195 -0
- rucio/core/nongrid_trace.py +136 -0
- rucio/core/oidc.py +1463 -0
- rucio/core/permission/__init__.py +161 -0
- rucio/core/permission/generic.py +1124 -0
- rucio/core/permission/generic_multi_vo.py +1144 -0
- rucio/core/quarantined_replica.py +224 -0
- rucio/core/replica.py +4483 -0
- rucio/core/replica_sorter.py +362 -0
- rucio/core/request.py +3091 -0
- rucio/core/rse.py +2079 -0
- rucio/core/rse_counter.py +185 -0
- rucio/core/rse_expression_parser.py +459 -0
- rucio/core/rse_selector.py +304 -0
- rucio/core/rule.py +4484 -0
- rucio/core/rule_grouping.py +1620 -0
- rucio/core/scope.py +181 -0
- rucio/core/subscription.py +362 -0
- rucio/core/topology.py +490 -0
- rucio/core/trace.py +375 -0
- rucio/core/transfer.py +1531 -0
- rucio/core/vo.py +169 -0
- rucio/core/volatile_replica.py +151 -0
- rucio/daemons/__init__.py +13 -0
- rucio/daemons/abacus/__init__.py +13 -0
- rucio/daemons/abacus/account.py +116 -0
- rucio/daemons/abacus/collection_replica.py +124 -0
- rucio/daemons/abacus/rse.py +117 -0
- rucio/daemons/atropos/__init__.py +13 -0
- rucio/daemons/atropos/atropos.py +242 -0
- rucio/daemons/auditor/__init__.py +289 -0
- rucio/daemons/auditor/hdfs.py +97 -0
- rucio/daemons/auditor/srmdumps.py +355 -0
- rucio/daemons/automatix/__init__.py +13 -0
- rucio/daemons/automatix/automatix.py +304 -0
- rucio/daemons/badreplicas/__init__.py +13 -0
- rucio/daemons/badreplicas/minos.py +322 -0
- rucio/daemons/badreplicas/minos_temporary_expiration.py +171 -0
- rucio/daemons/badreplicas/necromancer.py +196 -0
- rucio/daemons/bb8/__init__.py +13 -0
- rucio/daemons/bb8/bb8.py +353 -0
- rucio/daemons/bb8/common.py +759 -0
- rucio/daemons/bb8/nuclei_background_rebalance.py +153 -0
- rucio/daemons/bb8/t2_background_rebalance.py +153 -0
- rucio/daemons/cache/__init__.py +13 -0
- rucio/daemons/cache/consumer.py +133 -0
- rucio/daemons/common.py +405 -0
- rucio/daemons/conveyor/__init__.py +13 -0
- rucio/daemons/conveyor/common.py +562 -0
- rucio/daemons/conveyor/finisher.py +529 -0
- rucio/daemons/conveyor/poller.py +394 -0
- rucio/daemons/conveyor/preparer.py +205 -0
- rucio/daemons/conveyor/receiver.py +179 -0
- rucio/daemons/conveyor/stager.py +133 -0
- rucio/daemons/conveyor/submitter.py +403 -0
- rucio/daemons/conveyor/throttler.py +532 -0
- rucio/daemons/follower/__init__.py +13 -0
- rucio/daemons/follower/follower.py +101 -0
- rucio/daemons/hermes/__init__.py +13 -0
- rucio/daemons/hermes/hermes.py +534 -0
- rucio/daemons/judge/__init__.py +13 -0
- rucio/daemons/judge/cleaner.py +159 -0
- rucio/daemons/judge/evaluator.py +185 -0
- rucio/daemons/judge/injector.py +162 -0
- rucio/daemons/judge/repairer.py +154 -0
- rucio/daemons/oauthmanager/__init__.py +13 -0
- rucio/daemons/oauthmanager/oauthmanager.py +198 -0
- rucio/daemons/reaper/__init__.py +13 -0
- rucio/daemons/reaper/dark_reaper.py +282 -0
- rucio/daemons/reaper/reaper.py +739 -0
- rucio/daemons/replicarecoverer/__init__.py +13 -0
- rucio/daemons/replicarecoverer/suspicious_replica_recoverer.py +626 -0
- rucio/daemons/rsedecommissioner/__init__.py +13 -0
- rucio/daemons/rsedecommissioner/config.py +81 -0
- rucio/daemons/rsedecommissioner/profiles/__init__.py +24 -0
- rucio/daemons/rsedecommissioner/profiles/atlas.py +60 -0
- rucio/daemons/rsedecommissioner/profiles/generic.py +452 -0
- rucio/daemons/rsedecommissioner/profiles/types.py +93 -0
- rucio/daemons/rsedecommissioner/rse_decommissioner.py +280 -0
- rucio/daemons/storage/__init__.py +13 -0
- rucio/daemons/storage/consistency/__init__.py +13 -0
- rucio/daemons/storage/consistency/actions.py +848 -0
- rucio/daemons/tracer/__init__.py +13 -0
- rucio/daemons/tracer/kronos.py +511 -0
- rucio/daemons/transmogrifier/__init__.py +13 -0
- rucio/daemons/transmogrifier/transmogrifier.py +762 -0
- rucio/daemons/undertaker/__init__.py +13 -0
- rucio/daemons/undertaker/undertaker.py +137 -0
- rucio/db/__init__.py +13 -0
- rucio/db/sqla/__init__.py +52 -0
- rucio/db/sqla/constants.py +206 -0
- rucio/db/sqla/migrate_repo/__init__.py +13 -0
- rucio/db/sqla/migrate_repo/env.py +110 -0
- rucio/db/sqla/migrate_repo/versions/01eaf73ab656_add_new_rule_notification_state_progress.py +70 -0
- rucio/db/sqla/migrate_repo/versions/0437a40dbfd1_add_eol_at_in_rules.py +47 -0
- rucio/db/sqla/migrate_repo/versions/0f1adb7a599a_create_transfer_hops_table.py +59 -0
- rucio/db/sqla/migrate_repo/versions/102efcf145f4_added_stuck_at_column_to_rules.py +43 -0
- rucio/db/sqla/migrate_repo/versions/13d4f70c66a9_introduce_transfer_limits.py +91 -0
- rucio/db/sqla/migrate_repo/versions/140fef722e91_cleanup_distances_table.py +76 -0
- rucio/db/sqla/migrate_repo/versions/14ec5aeb64cf_add_request_external_host.py +43 -0
- rucio/db/sqla/migrate_repo/versions/156fb5b5a14_add_request_type_to_requests_idx.py +50 -0
- rucio/db/sqla/migrate_repo/versions/1677d4d803c8_split_rse_availability_into_multiple.py +68 -0
- rucio/db/sqla/migrate_repo/versions/16a0aca82e12_create_index_on_table_replicas_path.py +40 -0
- rucio/db/sqla/migrate_repo/versions/1803333ac20f_adding_provenance_and_phys_group.py +45 -0
- rucio/db/sqla/migrate_repo/versions/1a29d6a9504c_add_didtype_chck_to_requests.py +60 -0
- rucio/db/sqla/migrate_repo/versions/1a80adff031a_create_index_on_rules_hist_recent.py +40 -0
- rucio/db/sqla/migrate_repo/versions/1c45d9730ca6_increase_identity_length.py +140 -0
- rucio/db/sqla/migrate_repo/versions/1d1215494e95_add_quarantined_replicas_table.py +73 -0
- rucio/db/sqla/migrate_repo/versions/1d96f484df21_asynchronous_rules_and_rule_approval.py +74 -0
- rucio/db/sqla/migrate_repo/versions/1f46c5f240ac_add_bytes_column_to_bad_replicas.py +43 -0
- rucio/db/sqla/migrate_repo/versions/1fc15ab60d43_add_message_history_table.py +50 -0
- rucio/db/sqla/migrate_repo/versions/2190e703eb6e_move_rse_settings_to_rse_attributes.py +134 -0
- rucio/db/sqla/migrate_repo/versions/21d6b9dc9961_add_mismatch_scheme_state_to_requests.py +64 -0
- rucio/db/sqla/migrate_repo/versions/22cf51430c78_add_availability_column_to_table_rses.py +39 -0
- rucio/db/sqla/migrate_repo/versions/22d887e4ec0a_create_sources_table.py +64 -0
- rucio/db/sqla/migrate_repo/versions/25821a8a45a3_remove_unique_constraint_on_requests.py +51 -0
- rucio/db/sqla/migrate_repo/versions/25fc855625cf_added_unique_constraint_to_rules.py +41 -0
- rucio/db/sqla/migrate_repo/versions/269fee20dee9_add_repair_cnt_to_locks.py +43 -0
- rucio/db/sqla/migrate_repo/versions/271a46ea6244_add_ignore_availability_column_to_rules.py +44 -0
- rucio/db/sqla/migrate_repo/versions/277b5fbb41d3_switch_heartbeats_executable.py +53 -0
- rucio/db/sqla/migrate_repo/versions/27e3a68927fb_remove_replicas_tombstone_and_replicas_.py +38 -0
- rucio/db/sqla/migrate_repo/versions/2854cd9e168_added_rule_id_column.py +47 -0
- rucio/db/sqla/migrate_repo/versions/295289b5a800_processed_by_and__at_in_requests.py +45 -0
- rucio/db/sqla/migrate_repo/versions/2962ece31cf4_add_nbaccesses_column_in_the_did_table.py +45 -0
- rucio/db/sqla/migrate_repo/versions/2af3291ec4c_added_replicas_history_table.py +57 -0
- rucio/db/sqla/migrate_repo/versions/2b69addda658_add_columns_for_third_party_copy_read_.py +45 -0
- rucio/db/sqla/migrate_repo/versions/2b8e7bcb4783_add_config_table.py +69 -0
- rucio/db/sqla/migrate_repo/versions/2ba5229cb54c_add_submitted_at_to_requests_table.py +43 -0
- rucio/db/sqla/migrate_repo/versions/2cbee484dcf9_added_column_volume_to_rse_transfer_.py +42 -0
- rucio/db/sqla/migrate_repo/versions/2edee4a83846_add_source_to_requests_and_requests_.py +47 -0
- rucio/db/sqla/migrate_repo/versions/2eef46be23d4_change_tokens_pk.py +46 -0
- rucio/db/sqla/migrate_repo/versions/2f648fc909f3_index_in_rule_history_on_scope_name.py +40 -0
- rucio/db/sqla/migrate_repo/versions/3082b8cef557_add_naming_convention_table_and_closed_.py +67 -0
- rucio/db/sqla/migrate_repo/versions/30d5206e9cad_increase_oauthrequest_redirect_msg_.py +37 -0
- rucio/db/sqla/migrate_repo/versions/30fa38b6434e_add_index_on_service_column_in_the_message_table.py +44 -0
- rucio/db/sqla/migrate_repo/versions/3152492b110b_added_staging_area_column.py +77 -0
- rucio/db/sqla/migrate_repo/versions/32c7d2783f7e_create_bad_replicas_table.py +60 -0
- rucio/db/sqla/migrate_repo/versions/3345511706b8_replicas_table_pk_definition_is_in_.py +72 -0
- rucio/db/sqla/migrate_repo/versions/35ef10d1e11b_change_index_on_table_requests.py +42 -0
- rucio/db/sqla/migrate_repo/versions/379a19b5332d_create_rse_limits_table.py +65 -0
- rucio/db/sqla/migrate_repo/versions/384b96aa0f60_created_rule_history_tables.py +133 -0
- rucio/db/sqla/migrate_repo/versions/3ac1660a1a72_extend_distance_table.py +55 -0
- rucio/db/sqla/migrate_repo/versions/3ad36e2268b0_create_collection_replicas_updates_table.py +76 -0
- rucio/db/sqla/migrate_repo/versions/3c9df354071b_extend_waiting_request_state.py +60 -0
- rucio/db/sqla/migrate_repo/versions/3d9813fab443_add_a_new_state_lost_in_badfilesstatus.py +44 -0
- rucio/db/sqla/migrate_repo/versions/40ad39ce3160_add_transferred_at_to_requests_table.py +43 -0
- rucio/db/sqla/migrate_repo/versions/4207be2fd914_add_notification_column_to_rules.py +64 -0
- rucio/db/sqla/migrate_repo/versions/42db2617c364_create_index_on_requests_external_id.py +40 -0
- rucio/db/sqla/migrate_repo/versions/436827b13f82_added_column_activity_to_table_requests.py +43 -0
- rucio/db/sqla/migrate_repo/versions/44278720f774_update_requests_typ_sta_upd_idx_index.py +44 -0
- rucio/db/sqla/migrate_repo/versions/45378a1e76a8_create_collection_replica_table.py +78 -0
- rucio/db/sqla/migrate_repo/versions/469d262be19_removing_created_at_index.py +41 -0
- rucio/db/sqla/migrate_repo/versions/4783c1f49cb4_create_distance_table.py +59 -0
- rucio/db/sqla/migrate_repo/versions/49a21b4d4357_create_index_on_table_tokens.py +44 -0
- rucio/db/sqla/migrate_repo/versions/4a2cbedda8b9_add_source_replica_expression_column_to_.py +43 -0
- rucio/db/sqla/migrate_repo/versions/4a7182d9578b_added_bytes_length_accessed_at_columns.py +49 -0
- rucio/db/sqla/migrate_repo/versions/4bab9edd01fc_create_index_on_requests_rule_id.py +40 -0
- rucio/db/sqla/migrate_repo/versions/4c3a4acfe006_new_attr_account_table.py +63 -0
- rucio/db/sqla/migrate_repo/versions/4cf0a2e127d4_adding_transient_metadata.py +43 -0
- rucio/db/sqla/migrate_repo/versions/4df2c5ddabc0_remove_temporary_dids.py +55 -0
- rucio/db/sqla/migrate_repo/versions/50280c53117c_add_qos_class_to_rse.py +45 -0
- rucio/db/sqla/migrate_repo/versions/52153819589c_add_rse_id_to_replicas_table.py +43 -0
- rucio/db/sqla/migrate_repo/versions/52fd9f4916fa_added_activity_to_rules.py +43 -0
- rucio/db/sqla/migrate_repo/versions/53b479c3cb0f_fix_did_meta_table_missing_updated_at_.py +45 -0
- rucio/db/sqla/migrate_repo/versions/5673b4b6e843_add_wfms_metadata_to_rule_tables.py +47 -0
- rucio/db/sqla/migrate_repo/versions/575767d9f89_added_source_history_table.py +58 -0
- rucio/db/sqla/migrate_repo/versions/58bff7008037_add_started_at_to_requests.py +45 -0
- rucio/db/sqla/migrate_repo/versions/58c8b78301ab_rename_callback_to_message.py +106 -0
- rucio/db/sqla/migrate_repo/versions/5f139f77382a_added_child_rule_id_column.py +55 -0
- rucio/db/sqla/migrate_repo/versions/688ef1840840_adding_did_meta_table.py +50 -0
- rucio/db/sqla/migrate_repo/versions/6e572a9bfbf3_add_new_split_container_column_to_rules.py +47 -0
- rucio/db/sqla/migrate_repo/versions/70587619328_add_comment_column_for_subscriptions.py +43 -0
- rucio/db/sqla/migrate_repo/versions/739064d31565_remove_history_table_pks.py +41 -0
- rucio/db/sqla/migrate_repo/versions/7541902bf173_add_didsfollowed_and_followevents_table.py +91 -0
- rucio/db/sqla/migrate_repo/versions/7ec22226cdbf_new_replica_state_for_temporary_.py +72 -0
- rucio/db/sqla/migrate_repo/versions/810a41685bc1_added_columns_rse_transfer_limits.py +49 -0
- rucio/db/sqla/migrate_repo/versions/83f991c63a93_correct_rse_expression_length.py +43 -0
- rucio/db/sqla/migrate_repo/versions/8523998e2e76_increase_size_of_extended_attributes_.py +43 -0
- rucio/db/sqla/migrate_repo/versions/8ea9122275b1_adding_missing_function_based_indices.py +53 -0
- rucio/db/sqla/migrate_repo/versions/90f47792bb76_add_clob_payload_to_messages.py +45 -0
- rucio/db/sqla/migrate_repo/versions/914b8f02df38_new_table_for_lifetime_model_exceptions.py +68 -0
- rucio/db/sqla/migrate_repo/versions/94a5961ddbf2_add_estimator_columns.py +45 -0
- rucio/db/sqla/migrate_repo/versions/9a1b149a2044_add_saml_identity_type.py +94 -0
- rucio/db/sqla/migrate_repo/versions/9a45bc4ea66d_add_vp_table.py +54 -0
- rucio/db/sqla/migrate_repo/versions/9eb936a81eb1_true_is_true.py +72 -0
- rucio/db/sqla/migrate_repo/versions/a08fa8de1545_transfer_stats_table.py +55 -0
- rucio/db/sqla/migrate_repo/versions/a118956323f8_added_vo_table_and_vo_col_to_rse.py +76 -0
- rucio/db/sqla/migrate_repo/versions/a193a275255c_add_status_column_in_messages.py +47 -0
- rucio/db/sqla/migrate_repo/versions/a5f6f6e928a7_1_7_0.py +121 -0
- rucio/db/sqla/migrate_repo/versions/a616581ee47_added_columns_to_table_requests.py +59 -0
- rucio/db/sqla/migrate_repo/versions/a6eb23955c28_state_idx_non_functional.py +52 -0
- rucio/db/sqla/migrate_repo/versions/a74275a1ad30_added_global_quota_table.py +54 -0
- rucio/db/sqla/migrate_repo/versions/a93e4e47bda_heartbeats.py +64 -0
- rucio/db/sqla/migrate_repo/versions/ae2a56fcc89_added_comment_column_to_rules.py +49 -0
- rucio/db/sqla/migrate_repo/versions/b0070f3695c8_add_deletedidmeta_table.py +57 -0
- rucio/db/sqla/migrate_repo/versions/b4293a99f344_added_column_identity_to_table_tokens.py +43 -0
- rucio/db/sqla/migrate_repo/versions/b5493606bbf5_fix_primary_key_for_subscription_history.py +41 -0
- rucio/db/sqla/migrate_repo/versions/b7d287de34fd_removal_of_replicastate_source.py +91 -0
- rucio/db/sqla/migrate_repo/versions/b818052fa670_add_index_to_quarantined_replicas.py +40 -0
- rucio/db/sqla/migrate_repo/versions/b8caac94d7f0_add_comments_column_for_subscriptions_.py +43 -0
- rucio/db/sqla/migrate_repo/versions/b96a1c7e1cc4_new_bad_pfns_table_and_bad_replicas_.py +143 -0
- rucio/db/sqla/migrate_repo/versions/bb695f45c04_extend_request_state.py +76 -0
- rucio/db/sqla/migrate_repo/versions/bc68e9946deb_add_staging_timestamps_to_request.py +50 -0
- rucio/db/sqla/migrate_repo/versions/bf3baa1c1474_correct_pk_and_idx_for_history_tables.py +72 -0
- rucio/db/sqla/migrate_repo/versions/c0937668555f_add_qos_policy_map_table.py +55 -0
- rucio/db/sqla/migrate_repo/versions/c129ccdb2d5_add_lumiblocknr_to_dids.py +43 -0
- rucio/db/sqla/migrate_repo/versions/ccdbcd48206e_add_did_type_column_index_on_did_meta_.py +65 -0
- rucio/db/sqla/migrate_repo/versions/cebad904c4dd_new_payload_column_for_heartbeats.py +47 -0
- rucio/db/sqla/migrate_repo/versions/d1189a09c6e0_oauth2_0_and_jwt_feature_support_adding_.py +146 -0
- rucio/db/sqla/migrate_repo/versions/d23453595260_extend_request_state_for_preparer.py +104 -0
- rucio/db/sqla/migrate_repo/versions/d6dceb1de2d_added_purge_column_to_rules.py +44 -0
- rucio/db/sqla/migrate_repo/versions/d6e2c3b2cf26_remove_third_party_copy_column_from_rse.py +43 -0
- rucio/db/sqla/migrate_repo/versions/d91002c5841_new_account_limits_table.py +103 -0
- rucio/db/sqla/migrate_repo/versions/e138c364ebd0_extending_columns_for_filter_and_.py +49 -0
- rucio/db/sqla/migrate_repo/versions/e59300c8b179_support_for_archive.py +104 -0
- rucio/db/sqla/migrate_repo/versions/f1b14a8c2ac1_postgres_use_check_constraints.py +29 -0
- rucio/db/sqla/migrate_repo/versions/f41ffe206f37_oracle_global_temporary_tables.py +74 -0
- rucio/db/sqla/migrate_repo/versions/f85a2962b021_adding_transfertool_column_to_requests_.py +47 -0
- rucio/db/sqla/migrate_repo/versions/fa7a7d78b602_increase_refresh_token_size.py +43 -0
- rucio/db/sqla/migrate_repo/versions/fb28a95fe288_add_replicas_rse_id_tombstone_idx.py +37 -0
- rucio/db/sqla/migrate_repo/versions/fe1a65b176c9_set_third_party_copy_read_and_write_.py +43 -0
- rucio/db/sqla/migrate_repo/versions/fe8ea2fa9788_added_third_party_copy_column_to_rse_.py +43 -0
- rucio/db/sqla/models.py +1743 -0
- rucio/db/sqla/sautils.py +55 -0
- rucio/db/sqla/session.py +529 -0
- rucio/db/sqla/types.py +206 -0
- rucio/db/sqla/util.py +543 -0
- rucio/gateway/__init__.py +13 -0
- rucio/gateway/account.py +345 -0
- rucio/gateway/account_limit.py +363 -0
- rucio/gateway/authentication.py +381 -0
- rucio/gateway/config.py +227 -0
- rucio/gateway/credential.py +70 -0
- rucio/gateway/did.py +987 -0
- rucio/gateway/dirac.py +83 -0
- rucio/gateway/exporter.py +60 -0
- rucio/gateway/heartbeat.py +76 -0
- rucio/gateway/identity.py +189 -0
- rucio/gateway/importer.py +46 -0
- rucio/gateway/lifetime_exception.py +121 -0
- rucio/gateway/lock.py +153 -0
- rucio/gateway/meta_conventions.py +98 -0
- rucio/gateway/permission.py +74 -0
- rucio/gateway/quarantined_replica.py +79 -0
- rucio/gateway/replica.py +538 -0
- rucio/gateway/request.py +330 -0
- rucio/gateway/rse.py +632 -0
- rucio/gateway/rule.py +437 -0
- rucio/gateway/scope.py +100 -0
- rucio/gateway/subscription.py +280 -0
- rucio/gateway/vo.py +126 -0
- rucio/rse/__init__.py +96 -0
- rucio/rse/protocols/__init__.py +13 -0
- rucio/rse/protocols/bittorrent.py +194 -0
- rucio/rse/protocols/cache.py +111 -0
- rucio/rse/protocols/dummy.py +100 -0
- rucio/rse/protocols/gfal.py +708 -0
- rucio/rse/protocols/globus.py +243 -0
- rucio/rse/protocols/http_cache.py +82 -0
- rucio/rse/protocols/mock.py +123 -0
- rucio/rse/protocols/ngarc.py +209 -0
- rucio/rse/protocols/posix.py +250 -0
- rucio/rse/protocols/protocol.py +361 -0
- rucio/rse/protocols/rclone.py +365 -0
- rucio/rse/protocols/rfio.py +145 -0
- rucio/rse/protocols/srm.py +338 -0
- rucio/rse/protocols/ssh.py +414 -0
- rucio/rse/protocols/storm.py +195 -0
- rucio/rse/protocols/webdav.py +594 -0
- rucio/rse/protocols/xrootd.py +302 -0
- rucio/rse/rsemanager.py +881 -0
- rucio/rse/translation.py +260 -0
- rucio/tests/__init__.py +13 -0
- rucio/tests/common.py +280 -0
- rucio/tests/common_server.py +149 -0
- rucio/transfertool/__init__.py +13 -0
- rucio/transfertool/bittorrent.py +200 -0
- rucio/transfertool/bittorrent_driver.py +50 -0
- rucio/transfertool/bittorrent_driver_qbittorrent.py +134 -0
- rucio/transfertool/fts3.py +1600 -0
- rucio/transfertool/fts3_plugins.py +152 -0
- rucio/transfertool/globus.py +201 -0
- rucio/transfertool/globus_library.py +181 -0
- rucio/transfertool/mock.py +89 -0
- rucio/transfertool/transfertool.py +221 -0
- rucio/vcsversion.py +11 -0
- rucio/version.py +45 -0
- rucio/web/__init__.py +13 -0
- rucio/web/rest/__init__.py +13 -0
- rucio/web/rest/flaskapi/__init__.py +13 -0
- rucio/web/rest/flaskapi/authenticated_bp.py +27 -0
- rucio/web/rest/flaskapi/v1/__init__.py +13 -0
- rucio/web/rest/flaskapi/v1/accountlimits.py +236 -0
- rucio/web/rest/flaskapi/v1/accounts.py +1103 -0
- rucio/web/rest/flaskapi/v1/archives.py +102 -0
- rucio/web/rest/flaskapi/v1/auth.py +1644 -0
- rucio/web/rest/flaskapi/v1/common.py +426 -0
- rucio/web/rest/flaskapi/v1/config.py +304 -0
- rucio/web/rest/flaskapi/v1/credentials.py +213 -0
- rucio/web/rest/flaskapi/v1/dids.py +2340 -0
- rucio/web/rest/flaskapi/v1/dirac.py +116 -0
- rucio/web/rest/flaskapi/v1/export.py +75 -0
- rucio/web/rest/flaskapi/v1/heartbeats.py +127 -0
- rucio/web/rest/flaskapi/v1/identities.py +285 -0
- rucio/web/rest/flaskapi/v1/import.py +132 -0
- rucio/web/rest/flaskapi/v1/lifetime_exceptions.py +312 -0
- rucio/web/rest/flaskapi/v1/locks.py +358 -0
- rucio/web/rest/flaskapi/v1/main.py +91 -0
- rucio/web/rest/flaskapi/v1/meta_conventions.py +241 -0
- rucio/web/rest/flaskapi/v1/metrics.py +36 -0
- rucio/web/rest/flaskapi/v1/nongrid_traces.py +97 -0
- rucio/web/rest/flaskapi/v1/ping.py +88 -0
- rucio/web/rest/flaskapi/v1/redirect.py +366 -0
- rucio/web/rest/flaskapi/v1/replicas.py +1894 -0
- rucio/web/rest/flaskapi/v1/requests.py +998 -0
- rucio/web/rest/flaskapi/v1/rses.py +2250 -0
- rucio/web/rest/flaskapi/v1/rules.py +854 -0
- rucio/web/rest/flaskapi/v1/scopes.py +159 -0
- rucio/web/rest/flaskapi/v1/subscriptions.py +650 -0
- rucio/web/rest/flaskapi/v1/templates/auth_crash.html +80 -0
- rucio/web/rest/flaskapi/v1/templates/auth_granted.html +82 -0
- rucio/web/rest/flaskapi/v1/traces.py +137 -0
- rucio/web/rest/flaskapi/v1/types.py +20 -0
- rucio/web/rest/flaskapi/v1/vos.py +278 -0
- rucio/web/rest/main.py +18 -0
- rucio/web/rest/metrics.py +27 -0
- rucio/web/rest/ping.py +27 -0
- rucio-37.0.0rc1.data/data/rucio/etc/alembic.ini.template +71 -0
- rucio-37.0.0rc1.data/data/rucio/etc/alembic_offline.ini.template +74 -0
- rucio-37.0.0rc1.data/data/rucio/etc/globus-config.yml.template +5 -0
- rucio-37.0.0rc1.data/data/rucio/etc/ldap.cfg.template +30 -0
- rucio-37.0.0rc1.data/data/rucio/etc/mail_templates/rule_approval_request.tmpl +38 -0
- rucio-37.0.0rc1.data/data/rucio/etc/mail_templates/rule_approved_admin.tmpl +4 -0
- rucio-37.0.0rc1.data/data/rucio/etc/mail_templates/rule_approved_user.tmpl +17 -0
- rucio-37.0.0rc1.data/data/rucio/etc/mail_templates/rule_denied_admin.tmpl +6 -0
- rucio-37.0.0rc1.data/data/rucio/etc/mail_templates/rule_denied_user.tmpl +17 -0
- rucio-37.0.0rc1.data/data/rucio/etc/mail_templates/rule_ok_notification.tmpl +19 -0
- rucio-37.0.0rc1.data/data/rucio/etc/rse-accounts.cfg.template +25 -0
- rucio-37.0.0rc1.data/data/rucio/etc/rucio.cfg.atlas.client.template +43 -0
- rucio-37.0.0rc1.data/data/rucio/etc/rucio.cfg.template +241 -0
- rucio-37.0.0rc1.data/data/rucio/etc/rucio_multi_vo.cfg.template +217 -0
- rucio-37.0.0rc1.data/data/rucio/requirements.server.txt +297 -0
- rucio-37.0.0rc1.data/data/rucio/tools/bootstrap.py +34 -0
- rucio-37.0.0rc1.data/data/rucio/tools/merge_rucio_configs.py +144 -0
- rucio-37.0.0rc1.data/data/rucio/tools/reset_database.py +40 -0
- rucio-37.0.0rc1.data/scripts/rucio +133 -0
- rucio-37.0.0rc1.data/scripts/rucio-abacus-account +74 -0
- rucio-37.0.0rc1.data/scripts/rucio-abacus-collection-replica +46 -0
- rucio-37.0.0rc1.data/scripts/rucio-abacus-rse +78 -0
- rucio-37.0.0rc1.data/scripts/rucio-admin +97 -0
- rucio-37.0.0rc1.data/scripts/rucio-atropos +60 -0
- rucio-37.0.0rc1.data/scripts/rucio-auditor +206 -0
- rucio-37.0.0rc1.data/scripts/rucio-automatix +50 -0
- rucio-37.0.0rc1.data/scripts/rucio-bb8 +57 -0
- rucio-37.0.0rc1.data/scripts/rucio-cache-client +141 -0
- rucio-37.0.0rc1.data/scripts/rucio-cache-consumer +42 -0
- rucio-37.0.0rc1.data/scripts/rucio-conveyor-finisher +58 -0
- rucio-37.0.0rc1.data/scripts/rucio-conveyor-poller +66 -0
- rucio-37.0.0rc1.data/scripts/rucio-conveyor-preparer +37 -0
- rucio-37.0.0rc1.data/scripts/rucio-conveyor-receiver +44 -0
- rucio-37.0.0rc1.data/scripts/rucio-conveyor-stager +76 -0
- rucio-37.0.0rc1.data/scripts/rucio-conveyor-submitter +139 -0
- rucio-37.0.0rc1.data/scripts/rucio-conveyor-throttler +104 -0
- rucio-37.0.0rc1.data/scripts/rucio-dark-reaper +53 -0
- rucio-37.0.0rc1.data/scripts/rucio-dumper +160 -0
- rucio-37.0.0rc1.data/scripts/rucio-follower +44 -0
- rucio-37.0.0rc1.data/scripts/rucio-hermes +54 -0
- rucio-37.0.0rc1.data/scripts/rucio-judge-cleaner +89 -0
- rucio-37.0.0rc1.data/scripts/rucio-judge-evaluator +137 -0
- rucio-37.0.0rc1.data/scripts/rucio-judge-injector +44 -0
- rucio-37.0.0rc1.data/scripts/rucio-judge-repairer +44 -0
- rucio-37.0.0rc1.data/scripts/rucio-kronos +44 -0
- rucio-37.0.0rc1.data/scripts/rucio-minos +53 -0
- rucio-37.0.0rc1.data/scripts/rucio-minos-temporary-expiration +50 -0
- rucio-37.0.0rc1.data/scripts/rucio-necromancer +120 -0
- rucio-37.0.0rc1.data/scripts/rucio-oauth-manager +63 -0
- rucio-37.0.0rc1.data/scripts/rucio-reaper +83 -0
- rucio-37.0.0rc1.data/scripts/rucio-replica-recoverer +248 -0
- rucio-37.0.0rc1.data/scripts/rucio-rse-decommissioner +66 -0
- rucio-37.0.0rc1.data/scripts/rucio-storage-consistency-actions +74 -0
- rucio-37.0.0rc1.data/scripts/rucio-transmogrifier +77 -0
- rucio-37.0.0rc1.data/scripts/rucio-undertaker +76 -0
- rucio-37.0.0rc1.dist-info/METADATA +92 -0
- rucio-37.0.0rc1.dist-info/RECORD +487 -0
- rucio-37.0.0rc1.dist-info/WHEEL +5 -0
- rucio-37.0.0rc1.dist-info/licenses/AUTHORS.rst +100 -0
- rucio-37.0.0rc1.dist-info/licenses/LICENSE +201 -0
- rucio-37.0.0rc1.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# Copyright European Organization for Nuclear Research (CERN) since 2012
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
import hashlib
|
|
16
|
+
import logging
|
|
17
|
+
import os
|
|
18
|
+
import re
|
|
19
|
+
import shutil
|
|
20
|
+
import subprocess
|
|
21
|
+
import tempfile
|
|
22
|
+
from typing import TYPE_CHECKING
|
|
23
|
+
|
|
24
|
+
from rucio.common.dumper import DUMPS_CACHE_DIR, temp_file
|
|
25
|
+
from rucio.common.dumper.data_models import Replica
|
|
26
|
+
|
|
27
|
+
if TYPE_CHECKING:
|
|
28
|
+
from datetime import datetime
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def _hdfs_get(
|
|
32
|
+
src_url: str,
|
|
33
|
+
dst_path: str
|
|
34
|
+
) -> None:
|
|
35
|
+
cmd = ['hadoop', 'fs', '-get', src_url, dst_path]
|
|
36
|
+
get = subprocess.Popen(
|
|
37
|
+
cmd,
|
|
38
|
+
stderr=subprocess.PIPE,
|
|
39
|
+
)
|
|
40
|
+
_, stderr = get.communicate()
|
|
41
|
+
if get.returncode != 0:
|
|
42
|
+
raise OSError('_hdfs_get(): "{0}": {1}. Return code {2}'.format(
|
|
43
|
+
' '.join(cmd),
|
|
44
|
+
stderr,
|
|
45
|
+
get.returncode,
|
|
46
|
+
))
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
class ReplicaFromHDFS(Replica):
|
|
50
|
+
BASE_URL = '/user/rucio01/reports/{0}/replicas_per_rse/{1}/*'
|
|
51
|
+
|
|
52
|
+
@classmethod
|
|
53
|
+
def download(
|
|
54
|
+
cls,
|
|
55
|
+
rse: str,
|
|
56
|
+
date: "datetime",
|
|
57
|
+
cache_dir: str = DUMPS_CACHE_DIR,
|
|
58
|
+
buffer_size: int = 65536
|
|
59
|
+
) -> str:
|
|
60
|
+
logger = logging.getLogger('auditor.hdfs')
|
|
61
|
+
|
|
62
|
+
if not os.path.isdir(cache_dir):
|
|
63
|
+
os.mkdir(cache_dir)
|
|
64
|
+
tmp_dir = tempfile.mkdtemp(dir=cache_dir)
|
|
65
|
+
|
|
66
|
+
url = cls.BASE_URL.format(date.strftime('%Y-%m-%d'), rse)
|
|
67
|
+
filename = '{0}_{1}_{2}_{3}'.format(
|
|
68
|
+
cls.__name__.lower(),
|
|
69
|
+
rse,
|
|
70
|
+
date.strftime('%d-%m-%Y'),
|
|
71
|
+
hashlib.sha1(url.encode()).hexdigest()
|
|
72
|
+
)
|
|
73
|
+
filename = re.sub(r'\W', '-', filename)
|
|
74
|
+
path = os.path.join(cache_dir, filename)
|
|
75
|
+
|
|
76
|
+
if os.path.exists(path):
|
|
77
|
+
logger.debug('Taking Rucio Replica Dump %s for %s from cache', path, rse)
|
|
78
|
+
return path
|
|
79
|
+
|
|
80
|
+
try:
|
|
81
|
+
logging.debug('Trying to download: %s for %s', url, rse)
|
|
82
|
+
|
|
83
|
+
_hdfs_get(cls.BASE_URL.format(date.strftime('%Y-%m-%d'), rse), tmp_dir)
|
|
84
|
+
files = (os.path.join(tmp_dir, file_) for file_ in sorted(os.listdir(tmp_dir)))
|
|
85
|
+
|
|
86
|
+
with temp_file(cache_dir, filename, binary=True) as (full_dump, _):
|
|
87
|
+
for chunk_file in files:
|
|
88
|
+
with open(chunk_file, 'rb') as partial_dump:
|
|
89
|
+
while True:
|
|
90
|
+
data_chunk = partial_dump.read(buffer_size)
|
|
91
|
+
if not data_chunk:
|
|
92
|
+
break
|
|
93
|
+
full_dump.write(data_chunk)
|
|
94
|
+
finally:
|
|
95
|
+
shutil.rmtree(tmp_dir)
|
|
96
|
+
|
|
97
|
+
return path
|
|
@@ -0,0 +1,355 @@
|
|
|
1
|
+
# Copyright European Organization for Nuclear Research (CERN) since 2012
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
import datetime
|
|
16
|
+
import glob
|
|
17
|
+
import hashlib
|
|
18
|
+
import logging
|
|
19
|
+
import operator
|
|
20
|
+
import os
|
|
21
|
+
import re
|
|
22
|
+
from configparser import RawConfigParser
|
|
23
|
+
from html.parser import HTMLParser
|
|
24
|
+
from typing import IO, TYPE_CHECKING, Any, Optional
|
|
25
|
+
|
|
26
|
+
import gfal2
|
|
27
|
+
import requests
|
|
28
|
+
|
|
29
|
+
from rucio.common.config import get_config_dirs
|
|
30
|
+
from rucio.common.constants import RseAttr
|
|
31
|
+
from rucio.common.dumper import DUMPS_CACHE_DIR, HTTPDownloadFailed, ddmendpoint_url, gfal_download_to_file, http_download_to_file, temp_file
|
|
32
|
+
from rucio.core.credential import get_signed_url
|
|
33
|
+
from rucio.core.rse import get_rse_id, list_rse_attributes
|
|
34
|
+
|
|
35
|
+
if TYPE_CHECKING:
|
|
36
|
+
from collections.abc import Iterable
|
|
37
|
+
|
|
38
|
+
CHUNK_SIZE = 10485760
|
|
39
|
+
|
|
40
|
+
__DUMPERCONFIGDIRS = list(
|
|
41
|
+
filter(
|
|
42
|
+
os.path.exists,
|
|
43
|
+
(
|
|
44
|
+
os.path.join(confdir, 'auditor') for confdir in get_config_dirs()
|
|
45
|
+
)
|
|
46
|
+
)
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
OBJECTSTORE_NUM_TRIES = 30
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
class Parser(RawConfigParser):
|
|
53
|
+
'''
|
|
54
|
+
RawConfigParser subclass that doesn't modify the the name of the options
|
|
55
|
+
and removes any quotes around the string values.
|
|
56
|
+
'''
|
|
57
|
+
remove_quotes_re = re.compile(r"^'(.+)'$")
|
|
58
|
+
remove_double_quotes_re = re.compile(r'^"(.+)"$')
|
|
59
|
+
|
|
60
|
+
def optionxform(
|
|
61
|
+
self,
|
|
62
|
+
optionstr: str
|
|
63
|
+
) -> str:
|
|
64
|
+
return optionstr
|
|
65
|
+
|
|
66
|
+
def get(
|
|
67
|
+
self,
|
|
68
|
+
section: str,
|
|
69
|
+
option: str
|
|
70
|
+
) -> Any:
|
|
71
|
+
value = super(Parser, self).get(section, option)
|
|
72
|
+
if isinstance(value, str):
|
|
73
|
+
value = self.remove_quotes_re.sub(r'\1', value)
|
|
74
|
+
value = self.remove_double_quotes_re.sub(r'\1', value)
|
|
75
|
+
return value
|
|
76
|
+
|
|
77
|
+
def items(self, section):
|
|
78
|
+
return [(name, self.get(section, name)) for name in self.options(section)]
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def mkdir(dir_: str) -> None:
|
|
82
|
+
'''
|
|
83
|
+
This functions creates the `dir` directory if it doesn't exist. If `dir`
|
|
84
|
+
already exists this function does nothing.
|
|
85
|
+
'''
|
|
86
|
+
try:
|
|
87
|
+
os.mkdir(dir_)
|
|
88
|
+
except OSError as error:
|
|
89
|
+
if error.errno != 17:
|
|
90
|
+
raise error
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def get_newest(
|
|
94
|
+
base_url: str,
|
|
95
|
+
url_pattern: str,
|
|
96
|
+
links: "Iterable[str]"
|
|
97
|
+
) -> tuple[str, datetime.datetime]:
|
|
98
|
+
'''
|
|
99
|
+
Returns a tuple with the newest url in the `links` list matching the
|
|
100
|
+
pattern `url_pattern` and a datetime object representing the creation
|
|
101
|
+
date of the url.
|
|
102
|
+
|
|
103
|
+
The creation date is extracted from the url using datetime.strptime().
|
|
104
|
+
'''
|
|
105
|
+
logger = logging.getLogger('auditor.srmdumps')
|
|
106
|
+
times = []
|
|
107
|
+
|
|
108
|
+
pattern_components = url_pattern.split('/')
|
|
109
|
+
|
|
110
|
+
date_pattern = '{0}/{1}'.format(base_url, pattern_components[0])
|
|
111
|
+
if len(pattern_components) > 1:
|
|
112
|
+
postfix = '/' + '/'.join(pattern_components[1:])
|
|
113
|
+
else:
|
|
114
|
+
postfix = ''
|
|
115
|
+
|
|
116
|
+
for link in links:
|
|
117
|
+
try:
|
|
118
|
+
time = datetime.datetime.strptime(link, date_pattern)
|
|
119
|
+
except ValueError:
|
|
120
|
+
pass
|
|
121
|
+
else:
|
|
122
|
+
times.append((str(link) + postfix, time))
|
|
123
|
+
|
|
124
|
+
if not times:
|
|
125
|
+
msg = 'No links found matching the pattern {0} in {1}'.format(date_pattern, links)
|
|
126
|
+
logger.error(msg)
|
|
127
|
+
raise RuntimeError(msg)
|
|
128
|
+
|
|
129
|
+
return max(times, key=operator.itemgetter(1))
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
def gfal_links(base_url: str) -> list[str]:
|
|
133
|
+
'''
|
|
134
|
+
Returns a list of the urls contained in `base_url`.
|
|
135
|
+
'''
|
|
136
|
+
ctxt = gfal2.creat_context() # pylint: disable=no-member
|
|
137
|
+
return ['/'.join((base_url, f)) for f in ctxt.listdir(str(base_url))]
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
class _LinkCollector(HTMLParser):
|
|
141
|
+
def __init__(self):
|
|
142
|
+
super(_LinkCollector, self).__init__()
|
|
143
|
+
self.links = []
|
|
144
|
+
|
|
145
|
+
def handle_starttag(
|
|
146
|
+
self, tag: str,
|
|
147
|
+
attrs: "Iterable[tuple[str, str]]"
|
|
148
|
+
) -> None:
|
|
149
|
+
if tag == 'a':
|
|
150
|
+
self.links.append(
|
|
151
|
+
next(value for key, value in attrs if key == 'href')
|
|
152
|
+
)
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
def http_links(base_url: str) -> list[str]:
|
|
156
|
+
'''
|
|
157
|
+
Returns a list of the urls contained in `base_url`.
|
|
158
|
+
'''
|
|
159
|
+
html = requests.get(base_url).text
|
|
160
|
+
link_collector = _LinkCollector()
|
|
161
|
+
|
|
162
|
+
link_collector.feed(html)
|
|
163
|
+
links = []
|
|
164
|
+
for link in link_collector.links:
|
|
165
|
+
if not link.startswith('http://') and not link.startswith('https://'):
|
|
166
|
+
links.append('{0}/{1}'.format(base_url, link))
|
|
167
|
+
else:
|
|
168
|
+
links.append(link)
|
|
169
|
+
return links
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
protocol_funcs = {
|
|
173
|
+
'davs': {
|
|
174
|
+
'links': gfal_links,
|
|
175
|
+
'download': gfal_download_to_file,
|
|
176
|
+
},
|
|
177
|
+
'gsiftp': {
|
|
178
|
+
'links': gfal_links,
|
|
179
|
+
'download': gfal_download_to_file,
|
|
180
|
+
},
|
|
181
|
+
'root': {
|
|
182
|
+
'links': gfal_links,
|
|
183
|
+
'download': gfal_download_to_file,
|
|
184
|
+
},
|
|
185
|
+
'srm': {
|
|
186
|
+
'links': gfal_links,
|
|
187
|
+
'download': gfal_download_to_file,
|
|
188
|
+
},
|
|
189
|
+
'http': {
|
|
190
|
+
'links': http_links,
|
|
191
|
+
'download': http_download_to_file,
|
|
192
|
+
},
|
|
193
|
+
'https': {
|
|
194
|
+
'links': http_links,
|
|
195
|
+
'download': http_download_to_file,
|
|
196
|
+
},
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
def protocol(url: str) -> str:
|
|
201
|
+
'''
|
|
202
|
+
Given the URL `url` returns a string with the protocol part.
|
|
203
|
+
'''
|
|
204
|
+
proto = url.split('://')[0]
|
|
205
|
+
if proto not in protocol_funcs:
|
|
206
|
+
raise RuntimeError('Protocol {0} not supported'.format(proto))
|
|
207
|
+
|
|
208
|
+
return proto
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
def get_links(base_url: str) -> list[str]:
|
|
212
|
+
'''
|
|
213
|
+
Given the URL `base_url` returns the URLs linked or contained in it.
|
|
214
|
+
'''
|
|
215
|
+
return protocol_funcs[protocol(base_url)]['links'](base_url)
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
def download(url: str, filename: IO) -> None:
|
|
219
|
+
'''
|
|
220
|
+
Given the URL `url` downloads its contents on `filename`.
|
|
221
|
+
'''
|
|
222
|
+
return protocol_funcs[protocol(url)]['download'](url, filename)
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
def parse_configuration(conf_dirs: Optional[list[str]] = None) -> Parser:
|
|
226
|
+
'''
|
|
227
|
+
Parses the configuration for the endpoints contained in `conf_dir`.
|
|
228
|
+
Returns a ConfParser.RawConfParser subclass instance.
|
|
229
|
+
'''
|
|
230
|
+
conf_dirs = conf_dirs or __DUMPERCONFIGDIRS
|
|
231
|
+
logger = logging.getLogger('auditor.srmdumps')
|
|
232
|
+
if len(conf_dirs) == 0:
|
|
233
|
+
logger.error('No configuration directory given to load SRM dumps paths')
|
|
234
|
+
raise Exception('No configuration directory given to load SRM dumps paths')
|
|
235
|
+
|
|
236
|
+
configuration = Parser({
|
|
237
|
+
'disabled': False,
|
|
238
|
+
})
|
|
239
|
+
|
|
240
|
+
for conf_dir in conf_dirs:
|
|
241
|
+
configuration.read(glob.glob(conf_dir + '/*.cfg'))
|
|
242
|
+
return configuration
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
def download_rse_dump(
|
|
246
|
+
rse: str,
|
|
247
|
+
configuration: RawConfigParser,
|
|
248
|
+
date: Optional[datetime.datetime] = None,
|
|
249
|
+
destdir: str = DUMPS_CACHE_DIR
|
|
250
|
+
) -> tuple[str, datetime.datetime]:
|
|
251
|
+
'''
|
|
252
|
+
Downloads the dump for the given ddmendpoint. If this endpoint does not
|
|
253
|
+
follow the standardized method to publish the dumps it should have an
|
|
254
|
+
entry in the `configuration` object describing how to download the dump.
|
|
255
|
+
|
|
256
|
+
`rse` is the DDMEndpoint name.
|
|
257
|
+
|
|
258
|
+
`configuration` is a RawConfigParser subclass.
|
|
259
|
+
|
|
260
|
+
`date` is a datetime instance with the date of the desired dump or None
|
|
261
|
+
to download the latest available dump.
|
|
262
|
+
|
|
263
|
+
`destdir` is the directory where the dump will be saved (the final component
|
|
264
|
+
in the path is created if it doesn't exist).
|
|
265
|
+
|
|
266
|
+
Return value: a tuple with the filename and a datetime instance with
|
|
267
|
+
the date of the dump.
|
|
268
|
+
'''
|
|
269
|
+
logger = logging.getLogger('auditor.srmdumps')
|
|
270
|
+
base_url, url_pattern = generate_url(rse, configuration)
|
|
271
|
+
|
|
272
|
+
if not os.path.isdir(destdir):
|
|
273
|
+
os.mkdir(destdir)
|
|
274
|
+
|
|
275
|
+
# check for objectstores, which need to be handled differently
|
|
276
|
+
rse_id = get_rse_id(rse)
|
|
277
|
+
rse_attr = list_rse_attributes(rse_id)
|
|
278
|
+
if RseAttr.IS_OBJECT_STORE in rse_attr and rse_attr[RseAttr.IS_OBJECT_STORE] is not False:
|
|
279
|
+
tries = 1
|
|
280
|
+
if date is None:
|
|
281
|
+
# on objectstores, can't list dump files, so try the last N dates
|
|
282
|
+
date = datetime.datetime.now()
|
|
283
|
+
tries = OBJECTSTORE_NUM_TRIES
|
|
284
|
+
path = ''
|
|
285
|
+
while tries > 0:
|
|
286
|
+
url = '{0}/{1}'.format(base_url, date.strftime(url_pattern))
|
|
287
|
+
|
|
288
|
+
filename = '{0}_{1}_{2}_{3}'.format(
|
|
289
|
+
'ddmendpoint',
|
|
290
|
+
rse,
|
|
291
|
+
date.strftime('%d-%m-%Y'),
|
|
292
|
+
hashlib.sha1(url.encode()).hexdigest()
|
|
293
|
+
)
|
|
294
|
+
filename = re.sub(r'\W', '-', filename)
|
|
295
|
+
path = os.path.join(destdir, filename)
|
|
296
|
+
if not os.path.exists(path):
|
|
297
|
+
logger.debug('Trying to download: "%s"', url)
|
|
298
|
+
if RseAttr.SIGN_URL in rse_attr:
|
|
299
|
+
url = get_signed_url(rse_id, rse_attr[RseAttr.SIGN_URL], 'read', url)
|
|
300
|
+
try:
|
|
301
|
+
with temp_file(destdir, final_name=filename) as (f, _):
|
|
302
|
+
download(url, f)
|
|
303
|
+
tries = 0
|
|
304
|
+
except (HTTPDownloadFailed, gfal2.GError):
|
|
305
|
+
tries -= 1
|
|
306
|
+
date = date - datetime.timedelta(1)
|
|
307
|
+
else:
|
|
308
|
+
if date is None:
|
|
309
|
+
logger.debug('Looking for site dumps in: "%s"', base_url)
|
|
310
|
+
links = get_links(base_url)
|
|
311
|
+
url, date = get_newest(base_url, url_pattern, links)
|
|
312
|
+
else:
|
|
313
|
+
url = '{0}/{1}'.format(base_url, date.strftime(url_pattern))
|
|
314
|
+
|
|
315
|
+
filename = '{0}_{1}_{2}_{3}'.format(
|
|
316
|
+
'ddmendpoint',
|
|
317
|
+
rse,
|
|
318
|
+
date.strftime('%d-%m-%Y'),
|
|
319
|
+
hashlib.sha1(url.encode()).hexdigest()
|
|
320
|
+
)
|
|
321
|
+
filename = re.sub(r'\W', '-', filename)
|
|
322
|
+
path = os.path.join(destdir, filename)
|
|
323
|
+
|
|
324
|
+
if not os.path.exists(path):
|
|
325
|
+
logger.debug('Trying to download: "%s"', url)
|
|
326
|
+
with temp_file(destdir, final_name=filename) as (f, _):
|
|
327
|
+
download(url, f)
|
|
328
|
+
|
|
329
|
+
return (path, date)
|
|
330
|
+
|
|
331
|
+
|
|
332
|
+
def generate_url(
|
|
333
|
+
rse: str,
|
|
334
|
+
config: RawConfigParser
|
|
335
|
+
) -> tuple[str, str]:
|
|
336
|
+
'''
|
|
337
|
+
:param rse: Name of the endpoint.
|
|
338
|
+
:param config: RawConfigParser instance which may have configuration
|
|
339
|
+
related to the endpoint.
|
|
340
|
+
:returns: Tuple with the URL where the links can be queried to find new
|
|
341
|
+
dumps and the pattern used to parse the date of the dump of the files/directories
|
|
342
|
+
listed..
|
|
343
|
+
'''
|
|
344
|
+
site = rse.split('_')[0]
|
|
345
|
+
if site not in config.sections():
|
|
346
|
+
base_url = ddmendpoint_url(rse) + 'dumps'
|
|
347
|
+
url_pattern = 'dump_%Y%m%d'
|
|
348
|
+
else:
|
|
349
|
+
url_components = config.get(site, rse).split('/')
|
|
350
|
+
# The pattern may not be the last component
|
|
351
|
+
pattern_index = next(idx for idx, comp in enumerate(url_components) if '%m' in comp)
|
|
352
|
+
base_url = '/'.join(url_components[:pattern_index])
|
|
353
|
+
url_pattern = '/'.join(url_components[pattern_index:])
|
|
354
|
+
|
|
355
|
+
return base_url, url_pattern
|
|
@@ -0,0 +1,13 @@
|
|
|
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.
|