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,153 @@
|
|
|
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
|
+
"""
|
|
16
|
+
This script is to be used to background rebalance ATLAS t2 datadisks
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
from sqlalchemy import and_, or_, select
|
|
20
|
+
|
|
21
|
+
from rucio.common.constants import RseAttr
|
|
22
|
+
from rucio.core.rse import get_rse_attribute, get_rse_usage
|
|
23
|
+
from rucio.core.rse_expression_parser import parse_expression
|
|
24
|
+
from rucio.daemons.bb8.common import rebalance_rse
|
|
25
|
+
from rucio.db.sqla import models
|
|
26
|
+
from rucio.db.sqla.constants import RuleState
|
|
27
|
+
from rucio.db.sqla.session import get_session
|
|
28
|
+
|
|
29
|
+
tolerance = 0.15
|
|
30
|
+
max_total_rebalance_volume = 200 * 1E12
|
|
31
|
+
max_rse_rebalance_volume = 20 * 1E12
|
|
32
|
+
min_total = 50 * 1E12
|
|
33
|
+
total_rebalance_volume = 0
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
# groupdisks
|
|
37
|
+
def group_space(site: str) -> int:
|
|
38
|
+
"""
|
|
39
|
+
groupdisks of given site
|
|
40
|
+
contributing to primaries
|
|
41
|
+
"""
|
|
42
|
+
site_groupdisks = []
|
|
43
|
+
group_total = 0
|
|
44
|
+
try:
|
|
45
|
+
site_groupdisks = parse_expression('site=%s&spacetoken=ATLASDATADISK&type=GROUPDISK' % site)
|
|
46
|
+
except:
|
|
47
|
+
return group_total
|
|
48
|
+
|
|
49
|
+
for rse in site_groupdisks:
|
|
50
|
+
used = get_rse_usage(rse_id=rse['id'], source='rucio')[0]['used']
|
|
51
|
+
group_total += used
|
|
52
|
+
|
|
53
|
+
return group_total
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
# Calculate the current ratios
|
|
57
|
+
rses = parse_expression("(datapolicynucleus=true|tier=1)&type=DATADISK\\bb8-enabled=false")
|
|
58
|
+
total_primary = 0
|
|
59
|
+
total_secondary = 0
|
|
60
|
+
total_total = 0
|
|
61
|
+
global_ratio = float(0)
|
|
62
|
+
for rse in rses:
|
|
63
|
+
site_name = get_rse_attribute(rse['id'], RseAttr.SITE)
|
|
64
|
+
rse['groupdisk'] = group_space(site_name) # type: ignore (site_name could be None)
|
|
65
|
+
rse['primary'] = get_rse_usage(rse_id=rse['id'], source='rucio')[0]['used'] - get_rse_usage(rse_id=rse['id'], source='expired')[0]['used']
|
|
66
|
+
rse['primary'] += rse['groupdisk']
|
|
67
|
+
rse['secondary'] = get_rse_usage(rse_id=rse['id'], source='expired')[0]['used']
|
|
68
|
+
rse['total'] = get_rse_usage(rse_id=rse['id'], source='storage')[0]['total'] - get_rse_usage(rse_id=rse['id'], source='min_free_space')[0]['used']
|
|
69
|
+
rse['ratio'] = float(rse['primary']) / float(rse['total'])
|
|
70
|
+
total_primary += rse['primary']
|
|
71
|
+
total_secondary += rse['secondary']
|
|
72
|
+
total_total += float(rse['total'])
|
|
73
|
+
rse['receive_volume'] = 0 # Already rebalanced volume in this run
|
|
74
|
+
|
|
75
|
+
global_ratio = float(total_primary) / float(total_total)
|
|
76
|
+
print('Global ratio: %f' % (global_ratio))
|
|
77
|
+
for rse in sorted(rses, key=lambda k: k['ratio']):
|
|
78
|
+
print(' %s (%f)' % (rse['rse'], rse['ratio']))
|
|
79
|
+
|
|
80
|
+
rses_over_ratio = sorted([rse for rse in rses if rse['ratio'] > global_ratio + global_ratio * tolerance], key=lambda k: k['ratio'], reverse=True)
|
|
81
|
+
rses_under_ratio = sorted([rse for rse in rses if rse['ratio'] < global_ratio - global_ratio * tolerance], key=lambda k: k['ratio'], reverse=False)
|
|
82
|
+
|
|
83
|
+
session = get_session()
|
|
84
|
+
stmt = select(
|
|
85
|
+
models.ReplicationRule.rse_expression
|
|
86
|
+
).where(
|
|
87
|
+
and_(or_(models.ReplicationRule.state == RuleState.REPLICATING,
|
|
88
|
+
models.ReplicationRule.state == RuleState.STUCK),
|
|
89
|
+
models.ReplicationRule.comments == 'T2 Background rebalancing')
|
|
90
|
+
).group_by(
|
|
91
|
+
models.ReplicationRule.rse_expression
|
|
92
|
+
)
|
|
93
|
+
# Excluding RSEs
|
|
94
|
+
print('Excluding RSEs as destination which have active Background Rebalancing rules:')
|
|
95
|
+
for rse in session.execute(stmt).all():
|
|
96
|
+
print(' %s' % (rse[0]))
|
|
97
|
+
for des in rses_under_ratio:
|
|
98
|
+
des_as_expr = des['rse']
|
|
99
|
+
if des_as_expr == rse[0]:
|
|
100
|
+
rses_under_ratio.remove(des)
|
|
101
|
+
break
|
|
102
|
+
|
|
103
|
+
print('Excluding RSEs as destination which are too small by size:')
|
|
104
|
+
for des in rses_under_ratio:
|
|
105
|
+
if des['total'] < min_total:
|
|
106
|
+
print(' %s' % (des['rse']))
|
|
107
|
+
rses_under_ratio.remove(des)
|
|
108
|
+
|
|
109
|
+
print('Excluding RSEs as sources which are too small by size:')
|
|
110
|
+
for src in rses_over_ratio:
|
|
111
|
+
if src['total'] < min_total:
|
|
112
|
+
print(' %s' % (src['rse']))
|
|
113
|
+
rses_over_ratio.remove(src)
|
|
114
|
+
|
|
115
|
+
print('Excluding RSEs as destinations which are blocklisted:')
|
|
116
|
+
for des in rses_under_ratio:
|
|
117
|
+
if not (des['availability_read'] and des['availability_write'] and des['availability_delete']):
|
|
118
|
+
print(' %s' % (des['rse']))
|
|
119
|
+
rses_under_ratio.remove(des)
|
|
120
|
+
|
|
121
|
+
print('Excluding RSEs as sources which are blocklisted:')
|
|
122
|
+
for src in rses_over_ratio:
|
|
123
|
+
if not (src['availability_read'] and src['availability_write'] and src['availability_delete']):
|
|
124
|
+
print(' %s' % (src['rse']))
|
|
125
|
+
rses_over_ratio.remove(src)
|
|
126
|
+
|
|
127
|
+
# Loop over RSEs over the ratio
|
|
128
|
+
for source_rse in rses_over_ratio:
|
|
129
|
+
|
|
130
|
+
# The volume that would be rebalanced, not real availability of the data:
|
|
131
|
+
available_source_rebalance_volume = int((source_rse['primary'] - global_ratio * source_rse['secondary']) / (global_ratio + 1))
|
|
132
|
+
if available_source_rebalance_volume > max_rse_rebalance_volume:
|
|
133
|
+
available_source_rebalance_volume = max_rse_rebalance_volume
|
|
134
|
+
if available_source_rebalance_volume > max_total_rebalance_volume - total_rebalance_volume:
|
|
135
|
+
available_source_rebalance_volume = max_total_rebalance_volume - total_rebalance_volume
|
|
136
|
+
|
|
137
|
+
# Select a target:
|
|
138
|
+
for destination_rse in rses_under_ratio:
|
|
139
|
+
if available_source_rebalance_volume > 0:
|
|
140
|
+
if destination_rse['receive_volume'] >= max_rse_rebalance_volume:
|
|
141
|
+
continue
|
|
142
|
+
available_target_rebalance_volume = max_rse_rebalance_volume - destination_rse['receive_volume']
|
|
143
|
+
if available_target_rebalance_volume >= available_source_rebalance_volume:
|
|
144
|
+
available_target_rebalance_volume = available_source_rebalance_volume
|
|
145
|
+
|
|
146
|
+
vo_str = 'on VO {}'.format(destination_rse['vo']) if destination_rse['vo'] != 'def' else 'def'
|
|
147
|
+
print('Rebalance %dTB from %s(%f) to %s(%f)%s' % (available_target_rebalance_volume / 1E12, source_rse['rse'], source_rse['ratio'], destination_rse['rse'], destination_rse['ratio'], vo_str))
|
|
148
|
+
expr = destination_rse['rse']
|
|
149
|
+
rebalance_rse(rse_id=source_rse['id'], max_bytes=available_target_rebalance_volume, dry_run=False, comment='Nuclei Background rebalancing', force_expression=expr)
|
|
150
|
+
|
|
151
|
+
destination_rse['receive_volume'] += available_target_rebalance_volume
|
|
152
|
+
total_rebalance_volume += available_target_rebalance_volume
|
|
153
|
+
available_source_rebalance_volume -= available_target_rebalance_volume
|
|
@@ -0,0 +1,153 @@
|
|
|
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
|
+
"""
|
|
16
|
+
This script is to be used to background rebalance ATLAS t2 datadisks
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
from sqlalchemy import and_, or_, select
|
|
20
|
+
|
|
21
|
+
from rucio.common.constants import RseAttr
|
|
22
|
+
from rucio.core.rse import get_rse_attribute, get_rse_usage
|
|
23
|
+
from rucio.core.rse_expression_parser import parse_expression
|
|
24
|
+
from rucio.daemons.bb8.common import rebalance_rse
|
|
25
|
+
from rucio.db.sqla import models
|
|
26
|
+
from rucio.db.sqla.constants import RuleState
|
|
27
|
+
from rucio.db.sqla.session import get_session
|
|
28
|
+
|
|
29
|
+
tolerance = 0.1
|
|
30
|
+
max_total_rebalance_volume = 200 * 1E12
|
|
31
|
+
max_rse_rebalance_volume = 20 * 1E12
|
|
32
|
+
min_total = 50 * 1E12
|
|
33
|
+
total_rebalance_volume = 0
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
# groupdisks
|
|
37
|
+
def group_space(site: str) -> int:
|
|
38
|
+
"""
|
|
39
|
+
groupdisks of given site
|
|
40
|
+
contributing to primaries
|
|
41
|
+
"""
|
|
42
|
+
site_groupdisks = []
|
|
43
|
+
group_total = 0
|
|
44
|
+
try:
|
|
45
|
+
site_groupdisks = parse_expression('site=%s&spacetoken=ATLASDATADISK&type=GROUPDISK' % site)
|
|
46
|
+
except:
|
|
47
|
+
return group_total
|
|
48
|
+
|
|
49
|
+
for rse in site_groupdisks:
|
|
50
|
+
used = get_rse_usage(rse_id=rse['id'], source='rucio')[0]['used']
|
|
51
|
+
group_total += used
|
|
52
|
+
|
|
53
|
+
return group_total
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
# Calculate the current ratios
|
|
57
|
+
rses = parse_expression("datapolicynucleus=false&tier=2&type=DATADISK\\bb8-enabled=false")
|
|
58
|
+
total_primary = 0
|
|
59
|
+
total_secondary = 0
|
|
60
|
+
total_total = 0
|
|
61
|
+
global_ratio = float(0)
|
|
62
|
+
for rse in rses:
|
|
63
|
+
site_name = get_rse_attribute(rse['id'], RseAttr.SITE)
|
|
64
|
+
rse['groupdisk'] = group_space(site_name) # type: ignore (site_name could be None)
|
|
65
|
+
rse['primary'] = get_rse_usage(rse_id=rse['id'], source='rucio')[0]['used'] - get_rse_usage(rse_id=rse['id'], source='expired')[0]['used']
|
|
66
|
+
rse['primary'] += rse['groupdisk']
|
|
67
|
+
rse['secondary'] = get_rse_usage(rse_id=rse['id'], source='expired')[0]['used']
|
|
68
|
+
rse['total'] = get_rse_usage(rse_id=rse['id'], source='storage')[0]['total'] - get_rse_usage(rse_id=rse['id'], source='min_free_space')[0]['used']
|
|
69
|
+
rse['ratio'] = float(rse['primary']) / float(rse['total'])
|
|
70
|
+
total_primary += rse['primary']
|
|
71
|
+
total_secondary += rse['secondary']
|
|
72
|
+
total_total += float(rse['total'])
|
|
73
|
+
rse['receive_volume'] = 0 # Already rebalanced volume in this run
|
|
74
|
+
|
|
75
|
+
global_ratio = float(total_primary) / float(total_total)
|
|
76
|
+
print('Global ratio: %f' % (global_ratio))
|
|
77
|
+
for rse in sorted(rses, key=lambda k: k['ratio']):
|
|
78
|
+
print(' %s (%f)' % (rse['rse'], rse['ratio']))
|
|
79
|
+
|
|
80
|
+
rses_over_ratio = sorted([rse for rse in rses if rse['ratio'] > global_ratio + global_ratio * tolerance], key=lambda k: k['ratio'], reverse=True)
|
|
81
|
+
rses_under_ratio = sorted([rse for rse in rses if rse['ratio'] < global_ratio - global_ratio * tolerance], key=lambda k: k['ratio'], reverse=False)
|
|
82
|
+
|
|
83
|
+
session = get_session()
|
|
84
|
+
stmt = select(
|
|
85
|
+
models.ReplicationRule.rse_expression
|
|
86
|
+
).where(
|
|
87
|
+
and_(or_(models.ReplicationRule.state == RuleState.REPLICATING,
|
|
88
|
+
models.ReplicationRule.state == RuleState.STUCK),
|
|
89
|
+
models.ReplicationRule.comments == 'T2 Background rebalancing')
|
|
90
|
+
).group_by(
|
|
91
|
+
models.ReplicationRule.rse_expression
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
# Excluding RSEs
|
|
95
|
+
print('Excluding RSEs as destination which have active Background Rebalancing rules:')
|
|
96
|
+
for rse in session.execute(stmt).all():
|
|
97
|
+
print(' %s' % (rse[0]))
|
|
98
|
+
for des in rses_under_ratio:
|
|
99
|
+
des_as_expr = des['rse']
|
|
100
|
+
if des_as_expr == rse[0]:
|
|
101
|
+
rses_under_ratio.remove(des)
|
|
102
|
+
break
|
|
103
|
+
|
|
104
|
+
print('Excluding RSEs as destination which are too small by size:')
|
|
105
|
+
for des in rses_under_ratio:
|
|
106
|
+
if des['total'] < min_total:
|
|
107
|
+
print(' %s' % (des['rse']))
|
|
108
|
+
rses_under_ratio.remove(des)
|
|
109
|
+
|
|
110
|
+
print('Excluding RSEs as sources which are too small by size:')
|
|
111
|
+
for src in rses_over_ratio:
|
|
112
|
+
if src['total'] < min_total:
|
|
113
|
+
print(' %s' % (src['rse']))
|
|
114
|
+
rses_over_ratio.remove(src)
|
|
115
|
+
|
|
116
|
+
print('Excluding RSEs as desetinations which are blocklisted:')
|
|
117
|
+
for des in rses_under_ratio:
|
|
118
|
+
if not (des['availability_read'] and des['availability_write'] and des['availability_delete']):
|
|
119
|
+
print(' %s' % (des['rse']))
|
|
120
|
+
rses_under_ratio.remove(des)
|
|
121
|
+
|
|
122
|
+
print('Excluding RSEs as sources which are blocklisted:')
|
|
123
|
+
for src in rses_over_ratio:
|
|
124
|
+
if not (src['availability_read'] and src['availability_write'] and src['availability_delete']):
|
|
125
|
+
print(' %s' % (src['rse']))
|
|
126
|
+
rses_over_ratio.remove(src)
|
|
127
|
+
|
|
128
|
+
# Loop over RSEs over the ratio
|
|
129
|
+
for source_rse in rses_over_ratio:
|
|
130
|
+
|
|
131
|
+
# The volume that would be rebalanced, not real availability of the data:
|
|
132
|
+
available_source_rebalance_volume = int((source_rse['primary'] - global_ratio * source_rse['secondary']) / (global_ratio + 1))
|
|
133
|
+
if available_source_rebalance_volume > max_rse_rebalance_volume:
|
|
134
|
+
available_source_rebalance_volume = max_rse_rebalance_volume
|
|
135
|
+
if available_source_rebalance_volume > max_total_rebalance_volume - total_rebalance_volume:
|
|
136
|
+
available_source_rebalance_volume = max_total_rebalance_volume - total_rebalance_volume
|
|
137
|
+
|
|
138
|
+
# Select a target:
|
|
139
|
+
for destination_rse in rses_under_ratio:
|
|
140
|
+
if available_source_rebalance_volume > 0:
|
|
141
|
+
if destination_rse['receive_volume'] >= max_rse_rebalance_volume:
|
|
142
|
+
continue
|
|
143
|
+
available_target_rebalance_volume = max_rse_rebalance_volume - destination_rse['receive_volume']
|
|
144
|
+
if available_target_rebalance_volume >= available_source_rebalance_volume:
|
|
145
|
+
available_target_rebalance_volume = available_source_rebalance_volume
|
|
146
|
+
|
|
147
|
+
print('Rebalance %dTB from %s(%f) to %s(%f)' % (available_target_rebalance_volume / 1E12, source_rse['rse'], source_rse['ratio'], destination_rse['rse'], destination_rse['ratio']))
|
|
148
|
+
expr = destination_rse['rse']
|
|
149
|
+
rebalance_rse(rse_id=source_rse['id'], max_bytes=available_target_rebalance_volume, dry_run=False, comment='T2 Background rebalancing', force_expression=expr)
|
|
150
|
+
|
|
151
|
+
destination_rse['receive_volume'] += available_target_rebalance_volume
|
|
152
|
+
total_rebalance_volume += available_target_rebalance_volume
|
|
153
|
+
available_source_rebalance_volume -= available_target_rebalance_volume
|
|
@@ -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.
|
|
@@ -0,0 +1,133 @@
|
|
|
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
|
+
"""
|
|
16
|
+
Cache consumer is a daemon to retrieve rucio cache operation information to synchronize rucio catalog.
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
import json
|
|
20
|
+
import logging
|
|
21
|
+
import threading
|
|
22
|
+
import time
|
|
23
|
+
from traceback import format_exc
|
|
24
|
+
from typing import TYPE_CHECKING
|
|
25
|
+
|
|
26
|
+
import rucio.db.sqla.util
|
|
27
|
+
from rucio.common import exception
|
|
28
|
+
from rucio.common.logging import formatted_logger, setup_logging
|
|
29
|
+
from rucio.common.stomp_utils import ListenerBase, StompConnectionManager
|
|
30
|
+
from rucio.common.types import InternalScope, LoggerFunction
|
|
31
|
+
from rucio.core.monitor import MetricManager
|
|
32
|
+
from rucio.core.rse import get_rse_id
|
|
33
|
+
from rucio.core.volatile_replica import add_volatile_replicas, delete_volatile_replicas
|
|
34
|
+
|
|
35
|
+
if TYPE_CHECKING:
|
|
36
|
+
from types import FrameType
|
|
37
|
+
|
|
38
|
+
from stomp.utils import Frame
|
|
39
|
+
|
|
40
|
+
logging.getLogger("stomp").setLevel(logging.CRITICAL)
|
|
41
|
+
|
|
42
|
+
METRICS = MetricManager(module=__name__)
|
|
43
|
+
GRACEFUL_STOP = threading.Event()
|
|
44
|
+
DAEMON_NAME = 'cache-consumer'
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
class AMQConsumer(ListenerBase):
|
|
48
|
+
"""
|
|
49
|
+
class Consumer
|
|
50
|
+
"""
|
|
51
|
+
|
|
52
|
+
@METRICS.count_it
|
|
53
|
+
def on_message(self, frame: "Frame") -> None:
|
|
54
|
+
"""
|
|
55
|
+
on_message
|
|
56
|
+
"""
|
|
57
|
+
try:
|
|
58
|
+
msg = json.loads(frame.body) # type: ignore
|
|
59
|
+
self._logger(logging.DEBUG, 'Message received: %s', msg)
|
|
60
|
+
if isinstance(msg, dict) and 'operation' in msg.keys():
|
|
61
|
+
for f in msg['files']:
|
|
62
|
+
f['scope'] = InternalScope(f['scope'])
|
|
63
|
+
if 'rse_id' in msg:
|
|
64
|
+
rse_id = msg['rse_id']
|
|
65
|
+
else:
|
|
66
|
+
rse_id = get_rse_id(rse=msg['rse'], vo=msg.get('vo', 'def'))
|
|
67
|
+
|
|
68
|
+
rse_vo_str = msg['rse']
|
|
69
|
+
if 'vo' in msg and msg['vo'] != 'def':
|
|
70
|
+
rse_vo_str = f"{rse_vo_str} on {msg['vo']}"
|
|
71
|
+
if msg['operation'] == 'add_replicas':
|
|
72
|
+
self._logger(logging.INFO, "add_replicas to RSE %s: %s", rse_vo_str, str(msg['files']))
|
|
73
|
+
add_volatile_replicas(rse_id=rse_id, replicas=msg['files'])
|
|
74
|
+
elif msg['operation'] == 'delete_replicas':
|
|
75
|
+
self._logger(logging.INFO, "delete_replicas to RSE %s: %s", rse_vo_str, str(msg['files']))
|
|
76
|
+
delete_volatile_replicas(rse_id=rse_id, replicas=msg['files'])
|
|
77
|
+
else:
|
|
78
|
+
self._logger(logging.DEBUG, 'Check failed: %s %s', isinstance(msg, dict), "operation" in msg.keys())
|
|
79
|
+
except:
|
|
80
|
+
self._logger(logging.ERROR, str(format_exc()))
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def consumer(id_: int, num_thread: int = 1, logger: LoggerFunction = logging.log) -> None:
|
|
84
|
+
"""
|
|
85
|
+
Main loop to consume messages from the Rucio Cache producer.
|
|
86
|
+
"""
|
|
87
|
+
logger(logging.INFO, 'Rucio Cache consumer starting')
|
|
88
|
+
|
|
89
|
+
conn_mgr = StompConnectionManager(config_section='messaging-cache', logger=logger)
|
|
90
|
+
|
|
91
|
+
logger(logging.INFO, 'consumer started')
|
|
92
|
+
|
|
93
|
+
conn_mgr.set_listener_factory('rucio-cache-consumer', AMQConsumer, heartbeats=conn_mgr.config.heartbeats)
|
|
94
|
+
|
|
95
|
+
while not GRACEFUL_STOP.is_set():
|
|
96
|
+
|
|
97
|
+
conn_mgr.subscribe(id_='rucio-cache-messaging', ack='auto')
|
|
98
|
+
time.sleep(1)
|
|
99
|
+
|
|
100
|
+
logger(logging.INFO, 'graceful stop requested')
|
|
101
|
+
conn_mgr.disconnect()
|
|
102
|
+
logger(logging.INFO, 'graceful stop done')
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def stop(signum: "int | None" = None, frame: "FrameType | None" = None) -> None:
|
|
106
|
+
"""
|
|
107
|
+
Graceful exit.
|
|
108
|
+
"""
|
|
109
|
+
|
|
110
|
+
GRACEFUL_STOP.set()
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
def run(num_thread: int = 1) -> None:
|
|
114
|
+
"""
|
|
115
|
+
Starts up the rucio cache consumer thread
|
|
116
|
+
"""
|
|
117
|
+
setup_logging(process_name=DAEMON_NAME)
|
|
118
|
+
logger = formatted_logger(logging.log, DAEMON_NAME + ' %s')
|
|
119
|
+
|
|
120
|
+
if rucio.db.sqla.util.is_old_db():
|
|
121
|
+
raise exception.DatabaseException('Database was not updated, daemon won\'t start')
|
|
122
|
+
|
|
123
|
+
logger(logging.INFO, 'starting consumer thread')
|
|
124
|
+
threads = []
|
|
125
|
+
for i in range(num_thread):
|
|
126
|
+
con_thread = threading.Thread(target=consumer, kwargs={'id_': i, 'num_thread': num_thread, 'logger': logger})
|
|
127
|
+
con_thread.start()
|
|
128
|
+
threads.append(con_thread)
|
|
129
|
+
|
|
130
|
+
logger(logging.INFO, 'waiting for interrupts')
|
|
131
|
+
|
|
132
|
+
while [thread.join(timeout=3.14) for thread in threads if thread.is_alive()]:
|
|
133
|
+
pass
|