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
rucio/core/vo.py
ADDED
|
@@ -0,0 +1,169 @@
|
|
|
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 re
|
|
16
|
+
from typing import TYPE_CHECKING, Any
|
|
17
|
+
|
|
18
|
+
from sqlalchemy import select, update
|
|
19
|
+
from sqlalchemy.exc import DatabaseError, IntegrityError, NoResultFound
|
|
20
|
+
|
|
21
|
+
from rucio.common import exception
|
|
22
|
+
from rucio.common.config import config_get, config_get_bool
|
|
23
|
+
from rucio.common.types import InternalAccount
|
|
24
|
+
from rucio.db.sqla import models
|
|
25
|
+
from rucio.db.sqla.constants import AccountType, IdentityType
|
|
26
|
+
from rucio.db.sqla.session import read_session, transactional_session
|
|
27
|
+
|
|
28
|
+
# Format for long VO names
|
|
29
|
+
LONG_VO_RE = re.compile(r"^[a-zA-Z0-9\.\-]+$")
|
|
30
|
+
|
|
31
|
+
if TYPE_CHECKING:
|
|
32
|
+
from sqlalchemy.orm import Session
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
@read_session
|
|
36
|
+
def vo_exists(vo: str, *, session: "Session") -> bool:
|
|
37
|
+
"""
|
|
38
|
+
Verify that the vo exists.
|
|
39
|
+
|
|
40
|
+
:param vo: The vo to verify.
|
|
41
|
+
:param session: The db session in use.
|
|
42
|
+
|
|
43
|
+
:returns: True if the vo is in the vo table, False otherwise
|
|
44
|
+
"""
|
|
45
|
+
stmt = select(
|
|
46
|
+
models.VO
|
|
47
|
+
).where(
|
|
48
|
+
models.VO.vo == vo
|
|
49
|
+
)
|
|
50
|
+
return bool(session.execute(stmt).scalar())
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
@transactional_session
|
|
54
|
+
def add_vo(vo: str, description: str, email: str, *, session: "Session") -> None:
|
|
55
|
+
"""
|
|
56
|
+
Add a VO and setup a new root user.
|
|
57
|
+
New root user will have account name 'root' and a userpass identity with username: 'root@<vo>' and password: 'password'
|
|
58
|
+
|
|
59
|
+
:param vo: 3-letter unique tag for a VO.
|
|
60
|
+
:param description: Descriptive string for the VO (e.g. Full name).
|
|
61
|
+
:param email: Contact email for the VO.
|
|
62
|
+
:param session: The db session in use.
|
|
63
|
+
"""
|
|
64
|
+
if not config_get_bool('common', 'multi_vo', raise_exception=False, default=False):
|
|
65
|
+
raise exception.UnsupportedOperation('VO operations cannot be performed in single VO mode.')
|
|
66
|
+
|
|
67
|
+
if len(vo) != 3:
|
|
68
|
+
raise exception.RucioException('Invalid VO tag, must be 3 chars.')
|
|
69
|
+
|
|
70
|
+
new_vo = models.VO(vo=vo, description=description, email=email)
|
|
71
|
+
|
|
72
|
+
try:
|
|
73
|
+
new_vo.save(session=session)
|
|
74
|
+
except IntegrityError:
|
|
75
|
+
raise exception.Duplicate('VO {} already exists!'.format(vo))
|
|
76
|
+
except DatabaseError as error:
|
|
77
|
+
raise exception.RucioException(error.args)
|
|
78
|
+
|
|
79
|
+
from rucio.core.account import add_account, list_identities
|
|
80
|
+
from rucio.core.identity import add_account_identity
|
|
81
|
+
new_root = InternalAccount('root', vo=vo)
|
|
82
|
+
add_account(account=new_root, type_=AccountType['SERVICE'], email=email, session=session)
|
|
83
|
+
add_account_identity(identity='root@{}'.format(vo),
|
|
84
|
+
type_=IdentityType['USERPASS'],
|
|
85
|
+
account=new_root,
|
|
86
|
+
email=email,
|
|
87
|
+
default=False,
|
|
88
|
+
password='password', # noqa: S106
|
|
89
|
+
session=session)
|
|
90
|
+
|
|
91
|
+
for ident in list_identities(account=InternalAccount('super_root', vo='def'), session=session):
|
|
92
|
+
add_account_identity(identity=ident['identity'], type_=ident['type'], account=new_root, email='', session=session)
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
@read_session
|
|
96
|
+
def list_vos(*, session: "Session") -> list[dict[str, Any]]:
|
|
97
|
+
"""
|
|
98
|
+
List all the VOs in the db.
|
|
99
|
+
|
|
100
|
+
:param session: The db session in use.
|
|
101
|
+
:returns: List of VO dictionaries.
|
|
102
|
+
"""
|
|
103
|
+
if not config_get_bool('common', 'multi_vo', raise_exception=False, default=False):
|
|
104
|
+
raise exception.UnsupportedOperation('VO operations cannot be performed in single VO mode.')
|
|
105
|
+
|
|
106
|
+
stmt = select(
|
|
107
|
+
models.VO
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
vos = []
|
|
111
|
+
for vo in session.execute(stmt).scalars().all():
|
|
112
|
+
vo_dict = {'vo': vo.vo,
|
|
113
|
+
'description': vo.description,
|
|
114
|
+
'email': vo.email,
|
|
115
|
+
'created_at': vo.created_at,
|
|
116
|
+
'updated_at': vo.updated_at}
|
|
117
|
+
vos.append(vo_dict)
|
|
118
|
+
|
|
119
|
+
return vos
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
@transactional_session
|
|
123
|
+
def update_vo(vo: str, parameters: dict[str, Any], *, session: "Session") -> None:
|
|
124
|
+
"""
|
|
125
|
+
Update VO properties (email, description).
|
|
126
|
+
|
|
127
|
+
:param vo: The VO to update.
|
|
128
|
+
:param parameters: A dictionary with the new properties.
|
|
129
|
+
:param session: The db session in use.
|
|
130
|
+
"""
|
|
131
|
+
if not config_get_bool('common', 'multi_vo', raise_exception=False, default=False):
|
|
132
|
+
raise exception.UnsupportedOperation('VO operations cannot be performed in single VO mode.')
|
|
133
|
+
|
|
134
|
+
try:
|
|
135
|
+
stmt = select(
|
|
136
|
+
models.VO
|
|
137
|
+
).where(
|
|
138
|
+
models.VO.vo == vo
|
|
139
|
+
)
|
|
140
|
+
session.execute(stmt).scalar_one()
|
|
141
|
+
except NoResultFound:
|
|
142
|
+
raise exception.VONotFound('VO {} not found'.format(vo))
|
|
143
|
+
param = {}
|
|
144
|
+
for key in parameters:
|
|
145
|
+
if key in ['email', 'description']:
|
|
146
|
+
param[key] = parameters[key]
|
|
147
|
+
stmt = update(
|
|
148
|
+
models.VO
|
|
149
|
+
).where(
|
|
150
|
+
models.VO.vo == vo
|
|
151
|
+
).values(
|
|
152
|
+
param
|
|
153
|
+
)
|
|
154
|
+
session.execute(stmt)
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
def map_vo(vo: str) -> str:
|
|
158
|
+
"""
|
|
159
|
+
Converts a long VO name into the internal short (three letter)
|
|
160
|
+
tag mapping.
|
|
161
|
+
Mappings are loaded from the vo-map section of the config database table.
|
|
162
|
+
If a mapping is not found, the original is returned unchanged.
|
|
163
|
+
:param vo: The long VO name string.
|
|
164
|
+
:returns: The short VO name string.
|
|
165
|
+
"""
|
|
166
|
+
# Newline is ignored by regexp if at end of string, so test for that as well.
|
|
167
|
+
if not LONG_VO_RE.match(vo) or '\n' in vo:
|
|
168
|
+
raise exception.RucioException('Invalid characters in VO name.')
|
|
169
|
+
return config_get("vo-map", vo, raise_exception=False, default=vo)
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
# Copyright European Organization for Nuclear Research (CERN) since 2012
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
from datetime import datetime
|
|
16
|
+
from typing import TYPE_CHECKING, Any
|
|
17
|
+
|
|
18
|
+
from sqlalchemy import and_, delete, exists, insert, or_, select, true, update
|
|
19
|
+
from sqlalchemy.exc import NoResultFound
|
|
20
|
+
|
|
21
|
+
from rucio.common import exception
|
|
22
|
+
from rucio.core.rse import get_rse_name
|
|
23
|
+
from rucio.db.sqla import models
|
|
24
|
+
from rucio.db.sqla.constants import ReplicaState
|
|
25
|
+
from rucio.db.sqla.session import transactional_session
|
|
26
|
+
|
|
27
|
+
if TYPE_CHECKING:
|
|
28
|
+
from collections.abc import Iterable
|
|
29
|
+
|
|
30
|
+
from sqlalchemy.orm import Session
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
@transactional_session
|
|
34
|
+
def add_volatile_replicas(rse_id: str, replicas: "Iterable[dict[str, Any]]", *, session: "Session") -> None:
|
|
35
|
+
"""
|
|
36
|
+
Bulk add volatile replicas.
|
|
37
|
+
|
|
38
|
+
:param rse_id: the rse id.
|
|
39
|
+
:param replicas: the iterable of volatile replicas.
|
|
40
|
+
:param session: The database session in use.
|
|
41
|
+
"""
|
|
42
|
+
# first check that the rse is a volatile one
|
|
43
|
+
try:
|
|
44
|
+
stmt = select(
|
|
45
|
+
models.RSE
|
|
46
|
+
).where(
|
|
47
|
+
and_(models.RSE.id == rse_id,
|
|
48
|
+
models.RSE.volatile == true())
|
|
49
|
+
)
|
|
50
|
+
session.execute(stmt).one()
|
|
51
|
+
except NoResultFound:
|
|
52
|
+
raise exception.UnsupportedOperation('No volatile rse found for %s !'
|
|
53
|
+
% get_rse_name(rse_id=rse_id, session=session))
|
|
54
|
+
|
|
55
|
+
file_clause, replica_clause = [], []
|
|
56
|
+
for replica in replicas:
|
|
57
|
+
file_clause.append(and_(models.DataIdentifier.scope == replica['scope'],
|
|
58
|
+
models.DataIdentifier.name == replica['name'],
|
|
59
|
+
~exists(select(1).prefix_with('/*+ INDEX(REPLICAS REPLICAS_PK) */', dialect='oracle'))
|
|
60
|
+
.where(and_(models.RSEFileAssociation.scope == replica['scope'],
|
|
61
|
+
models.RSEFileAssociation.name == replica['name'],
|
|
62
|
+
models.RSEFileAssociation.rse_id == rse_id))))
|
|
63
|
+
replica_clause.append(and_(models.RSEFileAssociation.scope == replica['scope'],
|
|
64
|
+
models.RSEFileAssociation.name == replica['name'],
|
|
65
|
+
models.RSEFileAssociation.rse_id == rse_id))
|
|
66
|
+
if replica_clause:
|
|
67
|
+
now = datetime.utcnow()
|
|
68
|
+
stmt = update(
|
|
69
|
+
models.RSEFileAssociation
|
|
70
|
+
).prefix_with(
|
|
71
|
+
'/*+ INDEX(REPLICAS REPLICAS_PK) */',
|
|
72
|
+
dialect='oracle'
|
|
73
|
+
).where(
|
|
74
|
+
or_(*replica_clause)
|
|
75
|
+
).execution_options(
|
|
76
|
+
synchronize_session=False
|
|
77
|
+
).values({
|
|
78
|
+
models.RSEFileAssociation.updated_at: now,
|
|
79
|
+
models.RSEFileAssociation.tombstone: now
|
|
80
|
+
})
|
|
81
|
+
session.execute(stmt)
|
|
82
|
+
|
|
83
|
+
if file_clause:
|
|
84
|
+
stmt = select(
|
|
85
|
+
models.DataIdentifier.scope,
|
|
86
|
+
models.DataIdentifier.name,
|
|
87
|
+
models.DataIdentifier.bytes,
|
|
88
|
+
models.DataIdentifier.md5,
|
|
89
|
+
models.DataIdentifier.adler32
|
|
90
|
+
).filter(
|
|
91
|
+
or_(*file_clause)
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
new_replicas = [
|
|
95
|
+
{
|
|
96
|
+
'rse_id': rse_id,
|
|
97
|
+
'adler32': adler32,
|
|
98
|
+
'state': ReplicaState.AVAILABLE,
|
|
99
|
+
'scope': scope,
|
|
100
|
+
'name': name,
|
|
101
|
+
'lock_cnt': 0,
|
|
102
|
+
'tombstone': datetime.utcnow(),
|
|
103
|
+
'bytes': bytes_,
|
|
104
|
+
'md5': md5
|
|
105
|
+
}
|
|
106
|
+
for scope, name, bytes_, md5, adler32 in session.execute(stmt).all()
|
|
107
|
+
]
|
|
108
|
+
if new_replicas:
|
|
109
|
+
stmt = insert(
|
|
110
|
+
models.RSEFileAssociation
|
|
111
|
+
)
|
|
112
|
+
session.execute(stmt, new_replicas)
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
@transactional_session
|
|
116
|
+
def delete_volatile_replicas(rse_id: str, replicas: "Iterable[dict[str, Any]]", *, session: "Session") -> None:
|
|
117
|
+
"""
|
|
118
|
+
Bulk delete volatile replicas.
|
|
119
|
+
|
|
120
|
+
:param rse_id: the rse id.
|
|
121
|
+
:param replicas: the iterable of volatile replicas.
|
|
122
|
+
:param session: The database session in use.
|
|
123
|
+
"""
|
|
124
|
+
# first check that the rse is a volatile one
|
|
125
|
+
try:
|
|
126
|
+
stmt = select(
|
|
127
|
+
models.RSE
|
|
128
|
+
).where(
|
|
129
|
+
and_(models.RSE.id == rse_id,
|
|
130
|
+
models.RSE.volatile == true())
|
|
131
|
+
)
|
|
132
|
+
session.execute(stmt).one()
|
|
133
|
+
except NoResultFound:
|
|
134
|
+
raise exception.UnsupportedOperation('No volatile rse found for %s !'
|
|
135
|
+
% get_rse_name(rse_id=rse_id, session=session))
|
|
136
|
+
|
|
137
|
+
conditions = []
|
|
138
|
+
for replica in replicas:
|
|
139
|
+
conditions.append(and_(models.RSEFileAssociation.scope == replica['scope'],
|
|
140
|
+
models.RSEFileAssociation.name == replica['name']))
|
|
141
|
+
|
|
142
|
+
if conditions:
|
|
143
|
+
stmt = delete(
|
|
144
|
+
models.RSEFileAssociation
|
|
145
|
+
).where(
|
|
146
|
+
and_(models.RSEFileAssociation.rse_id == rse_id,
|
|
147
|
+
or_(*conditions))
|
|
148
|
+
).execution_options(
|
|
149
|
+
synchronize_session=False
|
|
150
|
+
)
|
|
151
|
+
session.execute(stmt)
|
|
@@ -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,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,116 @@
|
|
|
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
|
+
Abacus-Account is a daemon to update Account counters.
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
import logging
|
|
20
|
+
import threading
|
|
21
|
+
import time
|
|
22
|
+
from typing import TYPE_CHECKING
|
|
23
|
+
|
|
24
|
+
import rucio.db.sqla.util
|
|
25
|
+
from rucio.common import exception
|
|
26
|
+
from rucio.common.logging import setup_logging
|
|
27
|
+
from rucio.common.utils import get_thread_with_periodic_running_function
|
|
28
|
+
from rucio.core.account_counter import fill_account_counter_history_table, get_updated_account_counters, update_account_counter
|
|
29
|
+
from rucio.daemons.common import HeartbeatHandler, run_daemon
|
|
30
|
+
|
|
31
|
+
if TYPE_CHECKING:
|
|
32
|
+
from types import FrameType
|
|
33
|
+
from typing import Optional
|
|
34
|
+
|
|
35
|
+
graceful_stop = threading.Event()
|
|
36
|
+
DAEMON_NAME = 'abacus-account'
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def account_update(
|
|
40
|
+
once: bool = False,
|
|
41
|
+
sleep_time: int = 10
|
|
42
|
+
) -> None:
|
|
43
|
+
"""
|
|
44
|
+
Main loop to check and update the Account Counters.
|
|
45
|
+
"""
|
|
46
|
+
run_daemon(
|
|
47
|
+
once=once,
|
|
48
|
+
graceful_stop=graceful_stop,
|
|
49
|
+
executable=DAEMON_NAME,
|
|
50
|
+
partition_wait_time=1,
|
|
51
|
+
sleep_time=sleep_time,
|
|
52
|
+
run_once_fnc=run_once,
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def run_once(
|
|
57
|
+
heartbeat_handler: HeartbeatHandler,
|
|
58
|
+
**_kwargs
|
|
59
|
+
) -> None:
|
|
60
|
+
worker_number, total_workers, logger = heartbeat_handler.live()
|
|
61
|
+
|
|
62
|
+
start = time.time() # NOQA
|
|
63
|
+
updated_account_counters = get_updated_account_counters(total_workers=total_workers,
|
|
64
|
+
worker_number=worker_number)
|
|
65
|
+
logger(logging.DEBUG, 'Index query time %f size=%d' % (time.time() - start, len(updated_account_counters)))
|
|
66
|
+
|
|
67
|
+
# If the list is empty, sent the worker to sleep
|
|
68
|
+
if not updated_account_counters:
|
|
69
|
+
logger(logging.INFO, 'did not get any work')
|
|
70
|
+
return
|
|
71
|
+
|
|
72
|
+
for account_counter in updated_account_counters:
|
|
73
|
+
worker_number, total_workers, logger = heartbeat_handler.live()
|
|
74
|
+
if graceful_stop.is_set():
|
|
75
|
+
break
|
|
76
|
+
start_time = time.time()
|
|
77
|
+
update_account_counter(account=account_counter['account'], rse_id=account_counter['rse_id'])
|
|
78
|
+
logger(logging.DEBUG, 'update of account-rse counter "%s-%s" took %f' % (account_counter['account'], account_counter['rse_id'], time.time() - start_time))
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def stop(signum: "Optional[int]" = None, frame: "Optional[FrameType]" = None) -> None:
|
|
82
|
+
"""
|
|
83
|
+
Graceful exit.
|
|
84
|
+
"""
|
|
85
|
+
|
|
86
|
+
graceful_stop.set()
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def run(
|
|
90
|
+
once: bool = False,
|
|
91
|
+
threads: int = 1,
|
|
92
|
+
fill_history_table: bool = False,
|
|
93
|
+
sleep_time: int = 10
|
|
94
|
+
) -> None:
|
|
95
|
+
"""
|
|
96
|
+
Starts up the Abacus-Account threads.
|
|
97
|
+
"""
|
|
98
|
+
setup_logging(process_name=DAEMON_NAME)
|
|
99
|
+
|
|
100
|
+
if rucio.db.sqla.util.is_old_db():
|
|
101
|
+
raise exception.DatabaseException('Database was not updated, daemon won\'t start')
|
|
102
|
+
|
|
103
|
+
if once:
|
|
104
|
+
logging.info('main: executing one iteration only')
|
|
105
|
+
account_update(once)
|
|
106
|
+
else:
|
|
107
|
+
logging.info('main: starting threads')
|
|
108
|
+
thread_list = [threading.Thread(target=account_update, kwargs={'once': once, 'sleep_time': sleep_time}) for i in
|
|
109
|
+
range(0, threads)]
|
|
110
|
+
if fill_history_table:
|
|
111
|
+
thread_list.append(get_thread_with_periodic_running_function(3600, fill_account_counter_history_table, graceful_stop))
|
|
112
|
+
[t.start() for t in thread_list]
|
|
113
|
+
logging.info('main: waiting for interrupts')
|
|
114
|
+
# Interruptible joins require a timeout.
|
|
115
|
+
while thread_list[0].is_alive():
|
|
116
|
+
[t.join(timeout=3.14) for t in thread_list]
|
|
@@ -0,0 +1,124 @@
|
|
|
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
|
+
Abacus-Collection-Replica is a daemon to update collection replica.
|
|
17
|
+
"""
|
|
18
|
+
import functools
|
|
19
|
+
import logging
|
|
20
|
+
import threading
|
|
21
|
+
import time
|
|
22
|
+
from typing import TYPE_CHECKING
|
|
23
|
+
|
|
24
|
+
import rucio.db.sqla.util
|
|
25
|
+
from rucio.common import exception
|
|
26
|
+
from rucio.common.logging import setup_logging
|
|
27
|
+
from rucio.core.replica import get_cleaned_updated_collection_replicas, update_collection_replica
|
|
28
|
+
from rucio.daemons.common import HeartbeatHandler, run_daemon
|
|
29
|
+
|
|
30
|
+
if TYPE_CHECKING:
|
|
31
|
+
from types import FrameType
|
|
32
|
+
from typing import Optional
|
|
33
|
+
|
|
34
|
+
graceful_stop = threading.Event()
|
|
35
|
+
DAEMON_NAME = 'abacus-collection-replica'
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def collection_replica_update(
|
|
39
|
+
once: bool = False,
|
|
40
|
+
limit: int = 1000,
|
|
41
|
+
sleep_time: int = 10
|
|
42
|
+
) -> None:
|
|
43
|
+
"""
|
|
44
|
+
Main loop to check and update the collection replicas.
|
|
45
|
+
"""
|
|
46
|
+
run_daemon(
|
|
47
|
+
once=once,
|
|
48
|
+
graceful_stop=graceful_stop,
|
|
49
|
+
executable=DAEMON_NAME,
|
|
50
|
+
partition_wait_time=1,
|
|
51
|
+
sleep_time=sleep_time,
|
|
52
|
+
run_once_fnc=functools.partial(
|
|
53
|
+
run_once,
|
|
54
|
+
limit=limit,
|
|
55
|
+
),
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def run_once(
|
|
60
|
+
heartbeat_handler: HeartbeatHandler,
|
|
61
|
+
limit: int,
|
|
62
|
+
**_kwargs
|
|
63
|
+
) -> bool:
|
|
64
|
+
worker_number, total_workers, logger = heartbeat_handler.live()
|
|
65
|
+
# Select a bunch of collection replicas for to update for this worker
|
|
66
|
+
start = time.time() # NOQA
|
|
67
|
+
replicas = get_cleaned_updated_collection_replicas(total_workers=total_workers - 1,
|
|
68
|
+
worker_number=worker_number,
|
|
69
|
+
limit=limit)
|
|
70
|
+
|
|
71
|
+
logger(logging.DEBUG, 'Index query time %f size=%d' % (time.time() - start, len(replicas)))
|
|
72
|
+
# If the list is empty, sent the worker to sleep
|
|
73
|
+
if not replicas:
|
|
74
|
+
logger(logging.INFO, 'did not get any work')
|
|
75
|
+
must_sleep = True
|
|
76
|
+
return must_sleep
|
|
77
|
+
|
|
78
|
+
for replica in replicas:
|
|
79
|
+
worker_number, total_workers, logger = heartbeat_handler.live()
|
|
80
|
+
if graceful_stop.is_set():
|
|
81
|
+
break
|
|
82
|
+
start_time = time.time()
|
|
83
|
+
update_collection_replica(replica)
|
|
84
|
+
logger(logging.DEBUG, 'update of collection replica "%s" took %f' % (replica['id'], time.time() - start_time))
|
|
85
|
+
|
|
86
|
+
must_sleep = False
|
|
87
|
+
if limit and len(replicas) < limit:
|
|
88
|
+
must_sleep = True
|
|
89
|
+
return must_sleep
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def stop(signum: "Optional[int]" = None, frame: "Optional[FrameType]" = None) -> None:
|
|
93
|
+
"""
|
|
94
|
+
Graceful exit.
|
|
95
|
+
"""
|
|
96
|
+
|
|
97
|
+
graceful_stop.set()
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
def run(
|
|
101
|
+
once: bool = False,
|
|
102
|
+
threads: int = 1,
|
|
103
|
+
sleep_time: int = 10,
|
|
104
|
+
limit: int = 1000):
|
|
105
|
+
"""
|
|
106
|
+
Starts up the Abacus-Collection-Replica threads.
|
|
107
|
+
"""
|
|
108
|
+
setup_logging(process_name=DAEMON_NAME)
|
|
109
|
+
|
|
110
|
+
if rucio.db.sqla.util.is_old_db():
|
|
111
|
+
raise exception.DatabaseException('Database was not updated, daemon won\'t start')
|
|
112
|
+
|
|
113
|
+
if once:
|
|
114
|
+
logging.info('main: executing one iteration only')
|
|
115
|
+
collection_replica_update(once)
|
|
116
|
+
else:
|
|
117
|
+
logging.info('main: starting threads')
|
|
118
|
+
thread_list = [threading.Thread(target=collection_replica_update, kwargs={'once': once, 'sleep_time': sleep_time, 'limit': limit})
|
|
119
|
+
for _ in range(0, threads)]
|
|
120
|
+
[t.start() for t in thread_list]
|
|
121
|
+
logging.info('main: waiting for interrupts')
|
|
122
|
+
# Interruptible joins require a timeout.
|
|
123
|
+
while thread_list[0].is_alive():
|
|
124
|
+
[t.join(timeout=3.14) for t in thread_list]
|