rucio 32.8.6__py3-none-any.whl → 35.8.0__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 +0 -1
- rucio/alembicrevision.py +1 -2
- rucio/client/__init__.py +0 -1
- rucio/client/accountclient.py +45 -25
- rucio/client/accountlimitclient.py +37 -9
- rucio/client/baseclient.py +199 -154
- rucio/client/client.py +2 -3
- rucio/client/configclient.py +19 -6
- rucio/client/credentialclient.py +9 -4
- rucio/client/didclient.py +238 -63
- rucio/client/diracclient.py +13 -5
- rucio/client/downloadclient.py +162 -51
- rucio/client/exportclient.py +4 -4
- rucio/client/fileclient.py +3 -4
- rucio/client/importclient.py +4 -4
- rucio/client/lifetimeclient.py +21 -5
- rucio/client/lockclient.py +18 -8
- rucio/client/{metaclient.py → metaconventionsclient.py} +18 -15
- rucio/client/pingclient.py +0 -1
- rucio/client/replicaclient.py +15 -5
- rucio/client/requestclient.py +35 -19
- rucio/client/rseclient.py +133 -51
- rucio/client/ruleclient.py +29 -22
- rucio/client/scopeclient.py +8 -6
- rucio/client/subscriptionclient.py +47 -35
- rucio/client/touchclient.py +8 -4
- rucio/client/uploadclient.py +166 -82
- rucio/common/__init__.py +0 -1
- rucio/common/cache.py +4 -4
- rucio/common/config.py +52 -47
- rucio/common/constants.py +69 -2
- rucio/common/constraints.py +0 -1
- rucio/common/didtype.py +24 -22
- rucio/common/dumper/__init__.py +70 -41
- rucio/common/dumper/consistency.py +26 -22
- rucio/common/dumper/data_models.py +16 -23
- rucio/common/dumper/path_parsing.py +0 -1
- rucio/common/exception.py +281 -222
- rucio/common/extra.py +0 -1
- rucio/common/logging.py +54 -38
- rucio/common/pcache.py +122 -101
- rucio/common/plugins.py +153 -0
- rucio/common/policy.py +4 -4
- rucio/common/schema/__init__.py +17 -10
- rucio/common/schema/atlas.py +7 -5
- rucio/common/schema/belleii.py +7 -5
- rucio/common/schema/domatpc.py +7 -5
- rucio/common/schema/escape.py +7 -5
- rucio/common/schema/generic.py +8 -6
- rucio/common/schema/generic_multi_vo.py +7 -5
- rucio/common/schema/icecube.py +7 -5
- rucio/common/stomp_utils.py +0 -1
- rucio/common/stopwatch.py +0 -1
- rucio/common/test_rucio_server.py +2 -2
- rucio/common/types.py +262 -17
- rucio/common/utils.py +743 -451
- rucio/core/__init__.py +0 -1
- rucio/core/account.py +99 -29
- rucio/core/account_counter.py +89 -24
- rucio/core/account_limit.py +90 -24
- rucio/core/authentication.py +86 -29
- rucio/core/config.py +108 -38
- rucio/core/credential.py +14 -7
- rucio/core/did.py +680 -782
- rucio/core/did_meta_plugins/__init__.py +8 -6
- rucio/core/did_meta_plugins/did_column_meta.py +17 -12
- rucio/core/did_meta_plugins/did_meta_plugin_interface.py +60 -11
- rucio/core/did_meta_plugins/filter_engine.py +90 -50
- rucio/core/did_meta_plugins/json_meta.py +41 -16
- rucio/core/did_meta_plugins/mongo_meta.py +25 -8
- rucio/core/did_meta_plugins/postgres_meta.py +3 -4
- rucio/core/dirac.py +46 -17
- rucio/core/distance.py +66 -43
- rucio/core/exporter.py +5 -5
- rucio/core/heartbeat.py +181 -81
- rucio/core/identity.py +22 -12
- rucio/core/importer.py +23 -12
- rucio/core/lifetime_exception.py +32 -32
- rucio/core/lock.py +244 -142
- rucio/core/message.py +79 -38
- rucio/core/{meta.py → meta_conventions.py} +57 -44
- rucio/core/monitor.py +19 -13
- rucio/core/naming_convention.py +68 -27
- rucio/core/nongrid_trace.py +17 -5
- rucio/core/oidc.py +151 -29
- rucio/core/permission/__init__.py +18 -6
- rucio/core/permission/atlas.py +50 -35
- rucio/core/permission/belleii.py +6 -5
- rucio/core/permission/escape.py +8 -6
- rucio/core/permission/generic.py +82 -80
- rucio/core/permission/generic_multi_vo.py +9 -7
- rucio/core/quarantined_replica.py +91 -58
- rucio/core/replica.py +1303 -772
- rucio/core/replica_sorter.py +10 -12
- rucio/core/request.py +1133 -285
- rucio/core/rse.py +142 -102
- rucio/core/rse_counter.py +49 -18
- rucio/core/rse_expression_parser.py +6 -7
- rucio/core/rse_selector.py +41 -16
- rucio/core/rule.py +1538 -474
- rucio/core/rule_grouping.py +213 -68
- rucio/core/scope.py +50 -22
- rucio/core/subscription.py +92 -44
- rucio/core/topology.py +66 -24
- rucio/core/trace.py +42 -28
- rucio/core/transfer.py +543 -259
- rucio/core/vo.py +36 -18
- rucio/core/volatile_replica.py +59 -32
- rucio/daemons/__init__.py +0 -1
- rucio/daemons/abacus/__init__.py +0 -1
- rucio/daemons/abacus/account.py +29 -19
- rucio/daemons/abacus/collection_replica.py +21 -10
- rucio/daemons/abacus/rse.py +22 -12
- rucio/daemons/atropos/__init__.py +0 -1
- rucio/daemons/atropos/atropos.py +1 -2
- rucio/daemons/auditor/__init__.py +56 -28
- rucio/daemons/auditor/hdfs.py +17 -6
- rucio/daemons/auditor/srmdumps.py +116 -45
- rucio/daemons/automatix/__init__.py +0 -1
- rucio/daemons/automatix/automatix.py +30 -18
- rucio/daemons/badreplicas/__init__.py +0 -1
- rucio/daemons/badreplicas/minos.py +29 -18
- rucio/daemons/badreplicas/minos_temporary_expiration.py +5 -7
- rucio/daemons/badreplicas/necromancer.py +9 -13
- rucio/daemons/bb8/__init__.py +0 -1
- rucio/daemons/bb8/bb8.py +10 -13
- rucio/daemons/bb8/common.py +151 -154
- rucio/daemons/bb8/nuclei_background_rebalance.py +15 -9
- rucio/daemons/bb8/t2_background_rebalance.py +15 -8
- rucio/daemons/c3po/__init__.py +0 -1
- rucio/daemons/c3po/algorithms/__init__.py +0 -1
- rucio/daemons/c3po/algorithms/simple.py +8 -5
- rucio/daemons/c3po/algorithms/t2_free_space.py +10 -7
- rucio/daemons/c3po/algorithms/t2_free_space_only_pop.py +10 -7
- rucio/daemons/c3po/algorithms/t2_free_space_only_pop_with_network.py +30 -15
- rucio/daemons/c3po/c3po.py +81 -52
- rucio/daemons/c3po/collectors/__init__.py +0 -1
- rucio/daemons/c3po/collectors/agis.py +17 -17
- rucio/daemons/c3po/collectors/free_space.py +32 -13
- rucio/daemons/c3po/collectors/jedi_did.py +14 -5
- rucio/daemons/c3po/collectors/mock_did.py +11 -6
- rucio/daemons/c3po/collectors/network_metrics.py +12 -4
- rucio/daemons/c3po/collectors/workload.py +21 -19
- rucio/daemons/c3po/utils/__init__.py +0 -1
- rucio/daemons/c3po/utils/dataset_cache.py +15 -5
- rucio/daemons/c3po/utils/expiring_dataset_cache.py +16 -5
- rucio/daemons/c3po/utils/expiring_list.py +6 -7
- rucio/daemons/c3po/utils/popularity.py +5 -2
- rucio/daemons/c3po/utils/timeseries.py +25 -12
- rucio/daemons/cache/__init__.py +0 -1
- rucio/daemons/cache/consumer.py +21 -15
- rucio/daemons/common.py +42 -18
- rucio/daemons/conveyor/__init__.py +0 -1
- rucio/daemons/conveyor/common.py +69 -37
- rucio/daemons/conveyor/finisher.py +83 -46
- rucio/daemons/conveyor/poller.py +101 -69
- rucio/daemons/conveyor/preparer.py +35 -28
- rucio/daemons/conveyor/receiver.py +64 -21
- rucio/daemons/conveyor/stager.py +33 -28
- rucio/daemons/conveyor/submitter.py +71 -47
- rucio/daemons/conveyor/throttler.py +99 -35
- rucio/daemons/follower/__init__.py +0 -1
- rucio/daemons/follower/follower.py +12 -8
- rucio/daemons/hermes/__init__.py +0 -1
- rucio/daemons/hermes/hermes.py +57 -21
- rucio/daemons/judge/__init__.py +0 -1
- rucio/daemons/judge/cleaner.py +27 -17
- rucio/daemons/judge/evaluator.py +31 -18
- rucio/daemons/judge/injector.py +31 -23
- rucio/daemons/judge/repairer.py +28 -18
- rucio/daemons/oauthmanager/__init__.py +0 -1
- rucio/daemons/oauthmanager/oauthmanager.py +7 -8
- rucio/daemons/reaper/__init__.py +0 -1
- rucio/daemons/reaper/dark_reaper.py +15 -9
- rucio/daemons/reaper/reaper.py +109 -67
- rucio/daemons/replicarecoverer/__init__.py +0 -1
- rucio/daemons/replicarecoverer/suspicious_replica_recoverer.py +255 -116
- rucio/{api → daemons/rsedecommissioner}/__init__.py +0 -1
- 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 +451 -0
- rucio/daemons/rsedecommissioner/profiles/types.py +92 -0
- rucio/daemons/rsedecommissioner/rse_decommissioner.py +280 -0
- rucio/daemons/storage/__init__.py +0 -1
- rucio/daemons/storage/consistency/__init__.py +0 -1
- rucio/daemons/storage/consistency/actions.py +152 -59
- rucio/daemons/tracer/__init__.py +0 -1
- rucio/daemons/tracer/kronos.py +47 -24
- rucio/daemons/transmogrifier/__init__.py +0 -1
- rucio/daemons/transmogrifier/transmogrifier.py +35 -26
- rucio/daemons/undertaker/__init__.py +0 -1
- rucio/daemons/undertaker/undertaker.py +10 -10
- rucio/db/__init__.py +0 -1
- rucio/db/sqla/__init__.py +16 -2
- rucio/db/sqla/constants.py +10 -1
- rucio/db/sqla/migrate_repo/__init__.py +0 -1
- rucio/db/sqla/migrate_repo/env.py +0 -1
- rucio/db/sqla/migrate_repo/versions/01eaf73ab656_add_new_rule_notification_state_progress.py +0 -1
- rucio/db/sqla/migrate_repo/versions/0437a40dbfd1_add_eol_at_in_rules.py +0 -3
- rucio/db/sqla/migrate_repo/versions/0f1adb7a599a_create_transfer_hops_table.py +1 -3
- rucio/db/sqla/migrate_repo/versions/102efcf145f4_added_stuck_at_column_to_rules.py +0 -3
- rucio/db/sqla/migrate_repo/versions/13d4f70c66a9_introduce_transfer_limits.py +1 -3
- rucio/db/sqla/migrate_repo/versions/140fef722e91_cleanup_distances_table.py +1 -3
- rucio/db/sqla/migrate_repo/versions/14ec5aeb64cf_add_request_external_host.py +0 -3
- rucio/db/sqla/migrate_repo/versions/156fb5b5a14_add_request_type_to_requests_idx.py +1 -4
- rucio/db/sqla/migrate_repo/versions/1677d4d803c8_split_rse_availability_into_multiple.py +0 -1
- rucio/db/sqla/migrate_repo/versions/16a0aca82e12_create_index_on_table_replicas_path.py +0 -2
- rucio/db/sqla/migrate_repo/versions/1803333ac20f_adding_provenance_and_phys_group.py +0 -1
- rucio/db/sqla/migrate_repo/versions/1a29d6a9504c_add_didtype_chck_to_requests.py +0 -1
- rucio/db/sqla/migrate_repo/versions/1a80adff031a_create_index_on_rules_hist_recent.py +0 -2
- rucio/db/sqla/migrate_repo/versions/1c45d9730ca6_increase_identity_length.py +0 -1
- rucio/db/sqla/migrate_repo/versions/1d1215494e95_add_quarantined_replicas_table.py +1 -3
- rucio/db/sqla/migrate_repo/versions/1d96f484df21_asynchronous_rules_and_rule_approval.py +0 -1
- rucio/db/sqla/migrate_repo/versions/1f46c5f240ac_add_bytes_column_to_bad_replicas.py +0 -3
- rucio/db/sqla/migrate_repo/versions/1fc15ab60d43_add_message_history_table.py +0 -1
- rucio/db/sqla/migrate_repo/versions/2190e703eb6e_move_rse_settings_to_rse_attributes.py +1 -2
- rucio/db/sqla/migrate_repo/versions/21d6b9dc9961_add_mismatch_scheme_state_to_requests.py +0 -1
- rucio/db/sqla/migrate_repo/versions/22cf51430c78_add_availability_column_to_table_rses.py +0 -3
- rucio/db/sqla/migrate_repo/versions/22d887e4ec0a_create_sources_table.py +1 -3
- rucio/db/sqla/migrate_repo/versions/25821a8a45a3_remove_unique_constraint_on_requests.py +1 -4
- rucio/db/sqla/migrate_repo/versions/25fc855625cf_added_unique_constraint_to_rules.py +0 -2
- rucio/db/sqla/migrate_repo/versions/269fee20dee9_add_repair_cnt_to_locks.py +0 -3
- rucio/db/sqla/migrate_repo/versions/271a46ea6244_add_ignore_availability_column_to_rules.py +0 -3
- rucio/db/sqla/migrate_repo/versions/277b5fbb41d3_switch_heartbeats_executable.py +1 -2
- rucio/db/sqla/migrate_repo/versions/27e3a68927fb_remove_replicas_tombstone_and_replicas_.py +0 -1
- rucio/db/sqla/migrate_repo/versions/2854cd9e168_added_rule_id_column.py +0 -1
- rucio/db/sqla/migrate_repo/versions/295289b5a800_processed_by_and__at_in_requests.py +0 -2
- rucio/db/sqla/migrate_repo/versions/2962ece31cf4_add_nbaccesses_column_in_the_did_table.py +0 -3
- rucio/db/sqla/migrate_repo/versions/2af3291ec4c_added_replicas_history_table.py +1 -3
- rucio/db/sqla/migrate_repo/versions/2b69addda658_add_columns_for_third_party_copy_read_.py +0 -2
- rucio/db/sqla/migrate_repo/versions/2b8e7bcb4783_add_config_table.py +1 -4
- rucio/db/sqla/migrate_repo/versions/2ba5229cb54c_add_submitted_at_to_requests_table.py +0 -3
- rucio/db/sqla/migrate_repo/versions/2cbee484dcf9_added_column_volume_to_rse_transfer_.py +1 -4
- rucio/db/sqla/migrate_repo/versions/2edee4a83846_add_source_to_requests_and_requests_.py +0 -1
- rucio/db/sqla/migrate_repo/versions/2eef46be23d4_change_tokens_pk.py +1 -3
- rucio/db/sqla/migrate_repo/versions/2f648fc909f3_index_in_rule_history_on_scope_name.py +0 -2
- rucio/db/sqla/migrate_repo/versions/3082b8cef557_add_naming_convention_table_and_closed_.py +1 -3
- rucio/db/sqla/migrate_repo/versions/30fa38b6434e_add_index_on_service_column_in_the_message_table.py +1 -3
- rucio/db/sqla/migrate_repo/versions/3152492b110b_added_staging_area_column.py +1 -2
- rucio/db/sqla/migrate_repo/versions/32c7d2783f7e_create_bad_replicas_table.py +1 -3
- rucio/db/sqla/migrate_repo/versions/3345511706b8_replicas_table_pk_definition_is_in_.py +1 -3
- rucio/db/sqla/migrate_repo/versions/35ef10d1e11b_change_index_on_table_requests.py +0 -2
- rucio/db/sqla/migrate_repo/versions/379a19b5332d_create_rse_limits_table.py +1 -3
- rucio/db/sqla/migrate_repo/versions/384b96aa0f60_created_rule_history_tables.py +2 -3
- rucio/db/sqla/migrate_repo/versions/3ac1660a1a72_extend_distance_table.py +0 -3
- rucio/db/sqla/migrate_repo/versions/3ad36e2268b0_create_collection_replicas_updates_table.py +1 -4
- rucio/db/sqla/migrate_repo/versions/3c9df354071b_extend_waiting_request_state.py +0 -1
- rucio/db/sqla/migrate_repo/versions/3d9813fab443_add_a_new_state_lost_in_badfilesstatus.py +0 -1
- rucio/db/sqla/migrate_repo/versions/40ad39ce3160_add_transferred_at_to_requests_table.py +0 -3
- rucio/db/sqla/migrate_repo/versions/4207be2fd914_add_notification_column_to_rules.py +0 -1
- rucio/db/sqla/migrate_repo/versions/42db2617c364_create_index_on_requests_external_id.py +0 -2
- rucio/db/sqla/migrate_repo/versions/436827b13f82_added_column_activity_to_table_requests.py +0 -3
- rucio/db/sqla/migrate_repo/versions/44278720f774_update_requests_typ_sta_upd_idx_index.py +0 -2
- rucio/db/sqla/migrate_repo/versions/45378a1e76a8_create_collection_replica_table.py +2 -4
- rucio/db/sqla/migrate_repo/versions/469d262be19_removing_created_at_index.py +0 -2
- rucio/db/sqla/migrate_repo/versions/4783c1f49cb4_create_distance_table.py +1 -3
- rucio/db/sqla/migrate_repo/versions/49a21b4d4357_create_index_on_table_tokens.py +1 -4
- rucio/db/sqla/migrate_repo/versions/4a2cbedda8b9_add_source_replica_expression_column_to_.py +0 -3
- rucio/db/sqla/migrate_repo/versions/4a7182d9578b_added_bytes_length_accessed_at_columns.py +0 -3
- rucio/db/sqla/migrate_repo/versions/4bab9edd01fc_create_index_on_requests_rule_id.py +0 -2
- rucio/db/sqla/migrate_repo/versions/4c3a4acfe006_new_attr_account_table.py +1 -3
- rucio/db/sqla/migrate_repo/versions/4cf0a2e127d4_adding_transient_metadata.py +0 -3
- 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 +0 -2
- rucio/db/sqla/migrate_repo/versions/52153819589c_add_rse_id_to_replicas_table.py +0 -2
- rucio/db/sqla/migrate_repo/versions/52fd9f4916fa_added_activity_to_rules.py +0 -3
- rucio/db/sqla/migrate_repo/versions/53b479c3cb0f_fix_did_meta_table_missing_updated_at_.py +0 -3
- rucio/db/sqla/migrate_repo/versions/5673b4b6e843_add_wfms_metadata_to_rule_tables.py +0 -3
- rucio/db/sqla/migrate_repo/versions/575767d9f89_added_source_history_table.py +1 -2
- rucio/db/sqla/migrate_repo/versions/58bff7008037_add_started_at_to_requests.py +0 -3
- rucio/db/sqla/migrate_repo/versions/58c8b78301ab_rename_callback_to_message.py +1 -3
- rucio/db/sqla/migrate_repo/versions/5f139f77382a_added_child_rule_id_column.py +1 -3
- rucio/db/sqla/migrate_repo/versions/688ef1840840_adding_did_meta_table.py +1 -2
- rucio/db/sqla/migrate_repo/versions/6e572a9bfbf3_add_new_split_container_column_to_rules.py +0 -3
- rucio/db/sqla/migrate_repo/versions/70587619328_add_comment_column_for_subscriptions.py +0 -3
- rucio/db/sqla/migrate_repo/versions/739064d31565_remove_history_table_pks.py +1 -2
- rucio/db/sqla/migrate_repo/versions/7541902bf173_add_didsfollowed_and_followevents_table.py +2 -4
- rucio/db/sqla/migrate_repo/versions/7ec22226cdbf_new_replica_state_for_temporary_.py +0 -1
- rucio/db/sqla/migrate_repo/versions/810a41685bc1_added_columns_rse_transfer_limits.py +1 -4
- rucio/db/sqla/migrate_repo/versions/83f991c63a93_correct_rse_expression_length.py +0 -2
- rucio/db/sqla/migrate_repo/versions/8523998e2e76_increase_size_of_extended_attributes_.py +0 -3
- rucio/db/sqla/migrate_repo/versions/8ea9122275b1_adding_missing_function_based_indices.py +1 -2
- rucio/db/sqla/migrate_repo/versions/90f47792bb76_add_clob_payload_to_messages.py +0 -3
- rucio/db/sqla/migrate_repo/versions/914b8f02df38_new_table_for_lifetime_model_exceptions.py +1 -3
- rucio/db/sqla/migrate_repo/versions/94a5961ddbf2_add_estimator_columns.py +0 -3
- rucio/db/sqla/migrate_repo/versions/9a1b149a2044_add_saml_identity_type.py +0 -1
- rucio/db/sqla/migrate_repo/versions/9a45bc4ea66d_add_vp_table.py +1 -2
- rucio/db/sqla/migrate_repo/versions/9eb936a81eb1_true_is_true.py +0 -2
- 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 +1 -3
- rucio/db/sqla/migrate_repo/versions/a193a275255c_add_status_column_in_messages.py +0 -2
- rucio/db/sqla/migrate_repo/versions/a5f6f6e928a7_1_7_0.py +1 -4
- rucio/db/sqla/migrate_repo/versions/a616581ee47_added_columns_to_table_requests.py +0 -1
- rucio/db/sqla/migrate_repo/versions/a6eb23955c28_state_idx_non_functional.py +0 -1
- rucio/db/sqla/migrate_repo/versions/a74275a1ad30_added_global_quota_table.py +1 -3
- rucio/db/sqla/migrate_repo/versions/a93e4e47bda_heartbeats.py +1 -4
- rucio/db/sqla/migrate_repo/versions/ae2a56fcc89_added_comment_column_to_rules.py +0 -1
- 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 +0 -3
- 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 +1 -2
- rucio/db/sqla/migrate_repo/versions/b818052fa670_add_index_to_quarantined_replicas.py +1 -3
- rucio/db/sqla/migrate_repo/versions/b8caac94d7f0_add_comments_column_for_subscriptions_.py +0 -3
- rucio/db/sqla/migrate_repo/versions/b96a1c7e1cc4_new_bad_pfns_table_and_bad_replicas_.py +1 -5
- rucio/db/sqla/migrate_repo/versions/bb695f45c04_extend_request_state.py +1 -3
- rucio/db/sqla/migrate_repo/versions/bc68e9946deb_add_staging_timestamps_to_request.py +0 -3
- rucio/db/sqla/migrate_repo/versions/bf3baa1c1474_correct_pk_and_idx_for_history_tables.py +1 -3
- rucio/db/sqla/migrate_repo/versions/c0937668555f_add_qos_policy_map_table.py +1 -2
- rucio/db/sqla/migrate_repo/versions/c129ccdb2d5_add_lumiblocknr_to_dids.py +0 -3
- rucio/db/sqla/migrate_repo/versions/ccdbcd48206e_add_did_type_column_index_on_did_meta_.py +1 -4
- rucio/db/sqla/migrate_repo/versions/cebad904c4dd_new_payload_column_for_heartbeats.py +1 -2
- rucio/db/sqla/migrate_repo/versions/d1189a09c6e0_oauth2_0_and_jwt_feature_support_adding_.py +1 -4
- rucio/db/sqla/migrate_repo/versions/d23453595260_extend_request_state_for_preparer.py +1 -3
- rucio/db/sqla/migrate_repo/versions/d6dceb1de2d_added_purge_column_to_rules.py +1 -4
- rucio/db/sqla/migrate_repo/versions/d6e2c3b2cf26_remove_third_party_copy_column_from_rse.py +0 -2
- rucio/db/sqla/migrate_repo/versions/d91002c5841_new_account_limits_table.py +1 -3
- rucio/db/sqla/migrate_repo/versions/e138c364ebd0_extending_columns_for_filter_and_.py +0 -3
- rucio/db/sqla/migrate_repo/versions/e59300c8b179_support_for_archive.py +1 -3
- rucio/db/sqla/migrate_repo/versions/f1b14a8c2ac1_postgres_use_check_constraints.py +0 -1
- rucio/db/sqla/migrate_repo/versions/f41ffe206f37_oracle_global_temporary_tables.py +1 -2
- rucio/db/sqla/migrate_repo/versions/f85a2962b021_adding_transfertool_column_to_requests_.py +1 -3
- rucio/db/sqla/migrate_repo/versions/fa7a7d78b602_increase_refresh_token_size.py +0 -2
- rucio/db/sqla/migrate_repo/versions/fb28a95fe288_add_replicas_rse_id_tombstone_idx.py +0 -1
- rucio/db/sqla/migrate_repo/versions/fe1a65b176c9_set_third_party_copy_read_and_write_.py +1 -2
- rucio/db/sqla/migrate_repo/versions/fe8ea2fa9788_added_third_party_copy_column_to_rse_.py +0 -3
- rucio/db/sqla/models.py +122 -216
- rucio/db/sqla/sautils.py +12 -5
- rucio/db/sqla/session.py +71 -43
- rucio/db/sqla/types.py +3 -4
- rucio/db/sqla/util.py +91 -69
- rucio/gateway/__init__.py +13 -0
- rucio/{api → gateway}/account.py +119 -46
- rucio/{api → gateway}/account_limit.py +12 -13
- rucio/{api → gateway}/authentication.py +106 -33
- rucio/{api → gateway}/config.py +12 -13
- rucio/{api → gateway}/credential.py +15 -4
- rucio/{api → gateway}/did.py +384 -140
- rucio/{api → gateway}/dirac.py +16 -6
- rucio/{api → gateway}/exporter.py +3 -4
- rucio/{api → gateway}/heartbeat.py +17 -5
- rucio/{api → gateway}/identity.py +63 -19
- rucio/{api → gateway}/importer.py +3 -4
- rucio/{api → gateway}/lifetime_exception.py +35 -10
- rucio/{api → gateway}/lock.py +34 -12
- rucio/{api/meta.py → gateway/meta_conventions.py} +18 -16
- rucio/{api → gateway}/permission.py +4 -5
- rucio/{api → gateway}/quarantined_replica.py +13 -4
- rucio/{api → gateway}/replica.py +12 -11
- rucio/{api → gateway}/request.py +129 -28
- rucio/{api → gateway}/rse.py +11 -12
- rucio/{api → gateway}/rule.py +117 -35
- rucio/{api → gateway}/scope.py +24 -14
- rucio/{api → gateway}/subscription.py +65 -43
- rucio/{api → gateway}/vo.py +17 -7
- rucio/rse/__init__.py +3 -4
- rucio/rse/protocols/__init__.py +0 -1
- rucio/rse/protocols/bittorrent.py +184 -0
- rucio/rse/protocols/cache.py +1 -2
- rucio/rse/protocols/dummy.py +1 -2
- rucio/rse/protocols/gfal.py +12 -10
- rucio/rse/protocols/globus.py +7 -7
- rucio/rse/protocols/gsiftp.py +2 -3
- rucio/rse/protocols/http_cache.py +1 -2
- rucio/rse/protocols/mock.py +1 -2
- rucio/rse/protocols/ngarc.py +1 -2
- rucio/rse/protocols/posix.py +12 -13
- rucio/rse/protocols/protocol.py +116 -52
- rucio/rse/protocols/rclone.py +6 -7
- rucio/rse/protocols/rfio.py +4 -5
- rucio/rse/protocols/srm.py +9 -10
- rucio/rse/protocols/ssh.py +8 -9
- rucio/rse/protocols/storm.py +2 -3
- rucio/rse/protocols/webdav.py +17 -14
- rucio/rse/protocols/xrootd.py +23 -17
- rucio/rse/rsemanager.py +19 -7
- rucio/tests/__init__.py +0 -1
- rucio/tests/common.py +43 -17
- rucio/tests/common_server.py +3 -3
- rucio/transfertool/__init__.py +0 -1
- rucio/transfertool/bittorrent.py +199 -0
- rucio/transfertool/bittorrent_driver.py +52 -0
- rucio/transfertool/bittorrent_driver_qbittorrent.py +133 -0
- rucio/transfertool/fts3.py +250 -138
- rucio/transfertool/fts3_plugins.py +152 -0
- rucio/transfertool/globus.py +9 -8
- rucio/transfertool/globus_library.py +1 -2
- rucio/transfertool/mock.py +21 -12
- rucio/transfertool/transfertool.py +33 -24
- rucio/vcsversion.py +4 -4
- rucio/version.py +5 -13
- rucio/web/__init__.py +0 -1
- rucio/web/rest/__init__.py +0 -1
- rucio/web/rest/flaskapi/__init__.py +0 -1
- rucio/web/rest/flaskapi/authenticated_bp.py +0 -1
- rucio/web/rest/flaskapi/v1/__init__.py +0 -1
- rucio/web/rest/flaskapi/v1/accountlimits.py +15 -13
- rucio/web/rest/flaskapi/v1/accounts.py +49 -48
- rucio/web/rest/flaskapi/v1/archives.py +12 -10
- rucio/web/rest/flaskapi/v1/auth.py +146 -144
- rucio/web/rest/flaskapi/v1/common.py +82 -41
- rucio/web/rest/flaskapi/v1/config.py +5 -6
- rucio/web/rest/flaskapi/v1/credentials.py +7 -8
- rucio/web/rest/flaskapi/v1/dids.py +158 -28
- rucio/web/rest/flaskapi/v1/dirac.py +8 -8
- rucio/web/rest/flaskapi/v1/export.py +3 -5
- rucio/web/rest/flaskapi/v1/heartbeats.py +3 -5
- rucio/web/rest/flaskapi/v1/identities.py +3 -5
- rucio/web/rest/flaskapi/v1/import.py +3 -4
- rucio/web/rest/flaskapi/v1/lifetime_exceptions.py +6 -9
- rucio/web/rest/flaskapi/v1/locks.py +2 -4
- rucio/web/rest/flaskapi/v1/main.py +10 -2
- rucio/web/rest/flaskapi/v1/{meta.py → meta_conventions.py} +26 -11
- rucio/web/rest/flaskapi/v1/metrics.py +1 -2
- rucio/web/rest/flaskapi/v1/nongrid_traces.py +4 -4
- rucio/web/rest/flaskapi/v1/ping.py +6 -7
- rucio/web/rest/flaskapi/v1/redirect.py +8 -9
- rucio/web/rest/flaskapi/v1/replicas.py +43 -19
- rucio/web/rest/flaskapi/v1/requests.py +178 -21
- rucio/web/rest/flaskapi/v1/rses.py +61 -26
- rucio/web/rest/flaskapi/v1/rules.py +48 -18
- rucio/web/rest/flaskapi/v1/scopes.py +3 -5
- rucio/web/rest/flaskapi/v1/subscriptions.py +22 -18
- rucio/web/rest/flaskapi/v1/traces.py +4 -4
- rucio/web/rest/flaskapi/v1/types.py +20 -0
- rucio/web/rest/flaskapi/v1/vos.py +3 -5
- rucio/web/rest/main.py +0 -1
- rucio/web/rest/metrics.py +0 -1
- rucio/web/rest/ping.py +27 -0
- {rucio-32.8.6.data → rucio-35.8.0.data}/data/rucio/etc/ldap.cfg.template +1 -1
- rucio-35.8.0.data/data/rucio/requirements.server.txt +268 -0
- {rucio-32.8.6.data → rucio-35.8.0.data}/data/rucio/tools/bootstrap.py +3 -3
- {rucio-32.8.6.data → rucio-35.8.0.data}/data/rucio/tools/merge_rucio_configs.py +2 -5
- {rucio-32.8.6.data → rucio-35.8.0.data}/data/rucio/tools/reset_database.py +3 -3
- {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio +87 -85
- {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-abacus-account +0 -1
- {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-abacus-collection-replica +0 -1
- {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-abacus-rse +0 -1
- {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-admin +45 -32
- {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-atropos +0 -1
- {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-auditor +13 -7
- {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-automatix +1 -2
- {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-bb8 +0 -1
- {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-c3po +0 -1
- {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-cache-client +2 -3
- {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-cache-consumer +0 -1
- {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-conveyor-finisher +1 -2
- {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-conveyor-poller +0 -1
- {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-conveyor-preparer +0 -1
- {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-conveyor-receiver +0 -1
- {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-conveyor-stager +0 -1
- {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-conveyor-submitter +2 -3
- {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-conveyor-throttler +0 -1
- {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-dark-reaper +0 -1
- {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-dumper +11 -10
- {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-follower +0 -1
- {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-hermes +0 -1
- {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-judge-cleaner +0 -1
- {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-judge-evaluator +2 -3
- {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-judge-injector +0 -1
- {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-judge-repairer +0 -1
- {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-kronos +1 -3
- {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-minos +0 -1
- {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-minos-temporary-expiration +0 -1
- {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-necromancer +1 -2
- {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-oauth-manager +2 -3
- {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-reaper +0 -1
- {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-replica-recoverer +6 -7
- rucio-35.8.0.data/scripts/rucio-rse-decommissioner +66 -0
- {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-storage-consistency-actions +0 -1
- {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-transmogrifier +0 -1
- {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-undertaker +1 -2
- rucio-35.8.0.dist-info/METADATA +72 -0
- rucio-35.8.0.dist-info/RECORD +493 -0
- {rucio-32.8.6.dist-info → rucio-35.8.0.dist-info}/WHEEL +1 -1
- {rucio-32.8.6.dist-info → rucio-35.8.0.dist-info}/licenses/AUTHORS.rst +3 -0
- rucio/api/temporary_did.py +0 -49
- rucio/common/schema/cms.py +0 -478
- rucio/common/schema/lsst.py +0 -423
- rucio/core/permission/cms.py +0 -1166
- rucio/core/temporary_did.py +0 -188
- rucio/daemons/reaper/light_reaper.py +0 -255
- rucio/web/rest/flaskapi/v1/tmp_dids.py +0 -115
- rucio-32.8.6.data/data/rucio/requirements.txt +0 -55
- rucio-32.8.6.data/scripts/rucio-light-reaper +0 -53
- rucio-32.8.6.dist-info/METADATA +0 -83
- rucio-32.8.6.dist-info/RECORD +0 -481
- {rucio-32.8.6.data → rucio-35.8.0.data}/data/rucio/etc/alembic.ini.template +0 -0
- {rucio-32.8.6.data → rucio-35.8.0.data}/data/rucio/etc/alembic_offline.ini.template +0 -0
- {rucio-32.8.6.data → rucio-35.8.0.data}/data/rucio/etc/globus-config.yml.template +0 -0
- {rucio-32.8.6.data → rucio-35.8.0.data}/data/rucio/etc/mail_templates/rule_approval_request.tmpl +0 -0
- {rucio-32.8.6.data → rucio-35.8.0.data}/data/rucio/etc/mail_templates/rule_approved_admin.tmpl +0 -0
- {rucio-32.8.6.data → rucio-35.8.0.data}/data/rucio/etc/mail_templates/rule_approved_user.tmpl +0 -0
- {rucio-32.8.6.data → rucio-35.8.0.data}/data/rucio/etc/mail_templates/rule_denied_admin.tmpl +0 -0
- {rucio-32.8.6.data → rucio-35.8.0.data}/data/rucio/etc/mail_templates/rule_denied_user.tmpl +0 -0
- {rucio-32.8.6.data → rucio-35.8.0.data}/data/rucio/etc/mail_templates/rule_ok_notification.tmpl +0 -0
- {rucio-32.8.6.data → rucio-35.8.0.data}/data/rucio/etc/rse-accounts.cfg.template +0 -0
- {rucio-32.8.6.data → rucio-35.8.0.data}/data/rucio/etc/rucio.cfg.atlas.client.template +0 -0
- {rucio-32.8.6.data → rucio-35.8.0.data}/data/rucio/etc/rucio.cfg.template +0 -0
- {rucio-32.8.6.data → rucio-35.8.0.data}/data/rucio/etc/rucio_multi_vo.cfg.template +0 -0
- {rucio-32.8.6.dist-info → rucio-35.8.0.dist-info}/licenses/LICENSE +0 -0
- {rucio-32.8.6.dist-info → rucio-35.8.0.dist-info}/top_level.txt +0 -0
rucio/core/heartbeat.py
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
# -*- coding: utf-8 -*-
|
|
2
1
|
# Copyright European Organization for Nuclear Research (CERN) since 2012
|
|
3
2
|
#
|
|
4
3
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
@@ -15,26 +14,45 @@
|
|
|
15
14
|
|
|
16
15
|
import datetime
|
|
17
16
|
import hashlib
|
|
18
|
-
from typing import TYPE_CHECKING
|
|
17
|
+
from typing import TYPE_CHECKING, Optional
|
|
19
18
|
|
|
20
|
-
from sqlalchemy import func
|
|
21
|
-
from sqlalchemy.sql import distinct
|
|
19
|
+
from sqlalchemy import and_, delete, func, select, update
|
|
22
20
|
|
|
23
21
|
from rucio.common.exception import DatabaseException
|
|
24
22
|
from rucio.common.utils import pid_exists
|
|
25
|
-
from rucio.db.sqla.models import
|
|
23
|
+
from rucio.db.sqla.models import Heartbeat
|
|
26
24
|
from rucio.db.sqla.session import read_session, transactional_session
|
|
27
25
|
|
|
28
26
|
if TYPE_CHECKING:
|
|
27
|
+
from threading import Thread
|
|
28
|
+
from typing import TypedDict
|
|
29
|
+
|
|
29
30
|
from sqlalchemy.orm import Session
|
|
30
31
|
|
|
32
|
+
class HeartbeatDict(TypedDict):
|
|
33
|
+
readable: Optional[str]
|
|
34
|
+
hostname: str
|
|
35
|
+
pid: int
|
|
36
|
+
thread_name: Optional[str]
|
|
37
|
+
updated_at: datetime.datetime
|
|
38
|
+
created_at: datetime.datetime
|
|
39
|
+
payload: Optional[str]
|
|
40
|
+
test: int
|
|
31
41
|
|
|
32
42
|
DEFAULT_EXPIRATION_DELAY = datetime.timedelta(days=1).total_seconds()
|
|
33
43
|
|
|
34
44
|
|
|
35
45
|
@transactional_session
|
|
36
|
-
def sanity_check(
|
|
37
|
-
|
|
46
|
+
def sanity_check(
|
|
47
|
+
executable: str,
|
|
48
|
+
hostname: str,
|
|
49
|
+
hash_executable: Optional[str] = None,
|
|
50
|
+
pid: Optional[int] = None,
|
|
51
|
+
thread: Optional["Thread"] = None,
|
|
52
|
+
expiration_delay: float = DEFAULT_EXPIRATION_DELAY,
|
|
53
|
+
*,
|
|
54
|
+
session: "Session"
|
|
55
|
+
) -> None:
|
|
38
56
|
"""
|
|
39
57
|
sanity_check wrapper to ignore DatabaseException errors.
|
|
40
58
|
|
|
@@ -57,7 +75,14 @@ def sanity_check(executable, hostname, hash_executable=None, pid=None, thread=No
|
|
|
57
75
|
|
|
58
76
|
|
|
59
77
|
@transactional_session
|
|
60
|
-
def _sanity_check(
|
|
78
|
+
def _sanity_check(
|
|
79
|
+
executable: str,
|
|
80
|
+
hostname: str,
|
|
81
|
+
hash_executable: Optional[str] = None,
|
|
82
|
+
expiration_delay: float = DEFAULT_EXPIRATION_DELAY,
|
|
83
|
+
*,
|
|
84
|
+
session: "Session"
|
|
85
|
+
) -> None:
|
|
61
86
|
"""
|
|
62
87
|
Check if processes on the host are still running.
|
|
63
88
|
|
|
@@ -67,24 +92,56 @@ def _sanity_check(executable, hostname, hash_executable=None, expiration_delay=D
|
|
|
67
92
|
:param expiration_delay: time (in seconds) after which any inactive health check will be removed
|
|
68
93
|
:param session: The database session in use.
|
|
69
94
|
"""
|
|
95
|
+
base_stmt = select(
|
|
96
|
+
Heartbeat.pid
|
|
97
|
+
).distinct(
|
|
98
|
+
).where(
|
|
99
|
+
Heartbeat.hostname == hostname
|
|
100
|
+
)
|
|
70
101
|
if executable:
|
|
71
102
|
if not hash_executable:
|
|
72
103
|
hash_executable = calc_hash(executable)
|
|
73
104
|
|
|
74
|
-
|
|
105
|
+
stmt = base_stmt.where(
|
|
106
|
+
Heartbeat.executable == hash_executable
|
|
107
|
+
)
|
|
108
|
+
for pid in session.execute(stmt).scalars().all():
|
|
75
109
|
if not pid_exists(pid):
|
|
76
|
-
|
|
110
|
+
stmt = delete(
|
|
111
|
+
Heartbeat
|
|
112
|
+
).where(
|
|
113
|
+
and_(Heartbeat.executable == hash_executable,
|
|
114
|
+
Heartbeat.hostname == hostname,
|
|
115
|
+
Heartbeat.pid == pid)
|
|
116
|
+
)
|
|
117
|
+
session.execute(stmt)
|
|
77
118
|
else:
|
|
78
|
-
for pid
|
|
119
|
+
for pid in session.execute(base_stmt).scalars().all():
|
|
79
120
|
if not pid_exists(pid):
|
|
80
|
-
|
|
121
|
+
stmt = delete(
|
|
122
|
+
Heartbeat
|
|
123
|
+
).where(
|
|
124
|
+
and_(Heartbeat.hostname == hostname,
|
|
125
|
+
Heartbeat.pid == pid)
|
|
126
|
+
)
|
|
127
|
+
session.execute(stmt)
|
|
81
128
|
|
|
82
129
|
if expiration_delay:
|
|
83
130
|
cardiac_arrest(older_than=expiration_delay, session=session)
|
|
84
131
|
|
|
85
132
|
|
|
86
133
|
@transactional_session
|
|
87
|
-
def live(
|
|
134
|
+
def live(
|
|
135
|
+
executable: str,
|
|
136
|
+
hostname: str,
|
|
137
|
+
pid: int,
|
|
138
|
+
thread: Optional["Thread"] = None,
|
|
139
|
+
older_than: int = 600,
|
|
140
|
+
hash_executable: Optional[str] = None,
|
|
141
|
+
payload: Optional[str] = None,
|
|
142
|
+
*,
|
|
143
|
+
session: "Session"
|
|
144
|
+
) -> dict[str, int]:
|
|
88
145
|
"""
|
|
89
146
|
Register a heartbeat for a process/thread on a given node.
|
|
90
147
|
The executable name is used for the calculation of thread assignments.
|
|
@@ -114,35 +171,48 @@ def live(executable, hostname, pid, thread=None, older_than=600, hash_executable
|
|
|
114
171
|
thread_name = "thread"
|
|
115
172
|
|
|
116
173
|
# upsert the heartbeat
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
174
|
+
stmt = update(
|
|
175
|
+
Heartbeat
|
|
176
|
+
).where(
|
|
177
|
+
and_(Heartbeat.executable == hash_executable,
|
|
178
|
+
Heartbeat.hostname == hostname,
|
|
179
|
+
Heartbeat.pid == pid,
|
|
180
|
+
Heartbeat.thread_id == thread_id)
|
|
181
|
+
).values({
|
|
182
|
+
Heartbeat.updated_at: datetime.datetime.utcnow(),
|
|
183
|
+
Heartbeat.payload: payload
|
|
184
|
+
})
|
|
185
|
+
if not session.execute(stmt).rowcount:
|
|
186
|
+
Heartbeat(executable=hash_executable,
|
|
187
|
+
readable=executable[:Heartbeat.readable.property.columns[0].type.length],
|
|
188
|
+
hostname=hostname,
|
|
189
|
+
pid=pid,
|
|
190
|
+
thread_id=thread_id,
|
|
191
|
+
thread_name=thread_name,
|
|
192
|
+
payload=payload).save(session=session)
|
|
131
193
|
|
|
132
194
|
# assign thread identifier
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
195
|
+
stmt = select(
|
|
196
|
+
Heartbeat.hostname,
|
|
197
|
+
Heartbeat.pid,
|
|
198
|
+
Heartbeat.thread_id
|
|
199
|
+
).with_hint(
|
|
200
|
+
Heartbeat,
|
|
201
|
+
'INDEX(HEARTBEATS HEARTBEATS_PK)',
|
|
202
|
+
'oracle'
|
|
203
|
+
).where(
|
|
204
|
+
and_(Heartbeat.executable == hash_executable,
|
|
205
|
+
Heartbeat.updated_at >= datetime.datetime.utcnow() - datetime.timedelta(seconds=older_than))
|
|
206
|
+
).group_by(
|
|
207
|
+
Heartbeat.hostname,
|
|
208
|
+
Heartbeat.pid,
|
|
209
|
+
Heartbeat.thread_id
|
|
210
|
+
).order_by(
|
|
211
|
+
Heartbeat.hostname,
|
|
212
|
+
Heartbeat.pid,
|
|
213
|
+
Heartbeat.thread_id
|
|
214
|
+
)
|
|
215
|
+
result = session.execute(stmt).all()
|
|
146
216
|
|
|
147
217
|
# there is no universally applicable rownumber in SQLAlchemy
|
|
148
218
|
# so we have to do it in Python
|
|
@@ -157,7 +227,16 @@ def live(executable, hostname, pid, thread=None, older_than=600, hash_executable
|
|
|
157
227
|
|
|
158
228
|
|
|
159
229
|
@transactional_session
|
|
160
|
-
def die(
|
|
230
|
+
def die(
|
|
231
|
+
executable: str,
|
|
232
|
+
hostname: str,
|
|
233
|
+
pid: int,
|
|
234
|
+
thread: "Thread",
|
|
235
|
+
older_than: Optional[int] = None,
|
|
236
|
+
hash_executable: Optional[str] = None,
|
|
237
|
+
*,
|
|
238
|
+
session: "Session"
|
|
239
|
+
) -> None:
|
|
161
240
|
"""
|
|
162
241
|
Remove a single heartbeat older than specified.
|
|
163
242
|
|
|
@@ -168,25 +247,28 @@ def die(executable, hostname, pid, thread, older_than=None, hash_executable=None
|
|
|
168
247
|
:param older_than: Removes specified heartbeats older than specified nr of seconds
|
|
169
248
|
:param hash_executable: Hash of the executable.
|
|
170
249
|
:param session: The database session in use.
|
|
171
|
-
|
|
172
|
-
:returns heartbeats: Dictionary {assign_thread, nr_threads}
|
|
173
250
|
"""
|
|
174
251
|
if not hash_executable:
|
|
175
252
|
hash_executable = calc_hash(executable)
|
|
176
253
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
254
|
+
stmt = delete(
|
|
255
|
+
Heartbeat
|
|
256
|
+
).where(
|
|
257
|
+
and_(Heartbeat.executable == hash_executable,
|
|
258
|
+
Heartbeat.hostname == hostname,
|
|
259
|
+
Heartbeat.pid == pid,
|
|
260
|
+
Heartbeat.thread_id == thread.ident)
|
|
261
|
+
)
|
|
181
262
|
|
|
182
263
|
if older_than:
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
264
|
+
stmt = stmt.where(
|
|
265
|
+
Heartbeat.updated_at < datetime.datetime.utcnow() - datetime.timedelta(seconds=older_than)
|
|
266
|
+
)
|
|
267
|
+
session.execute(stmt)
|
|
186
268
|
|
|
187
269
|
|
|
188
270
|
@transactional_session
|
|
189
|
-
def cardiac_arrest(older_than=None, *, session: "Session"):
|
|
271
|
+
def cardiac_arrest(older_than: Optional[int] = None, *, session: "Session") -> None:
|
|
190
272
|
"""
|
|
191
273
|
Removes all heartbeats older than specified.
|
|
192
274
|
|
|
@@ -194,35 +276,42 @@ def cardiac_arrest(older_than=None, *, session: "Session"):
|
|
|
194
276
|
:param session: The database session in use.
|
|
195
277
|
"""
|
|
196
278
|
|
|
197
|
-
|
|
279
|
+
stmt = delete(
|
|
280
|
+
Heartbeat
|
|
281
|
+
)
|
|
198
282
|
|
|
199
283
|
if older_than:
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
284
|
+
stmt = stmt.where(
|
|
285
|
+
Heartbeat.updated_at < datetime.datetime.utcnow() - datetime.timedelta(seconds=older_than)
|
|
286
|
+
)
|
|
287
|
+
session.execute(stmt)
|
|
203
288
|
|
|
204
289
|
|
|
205
290
|
@read_session
|
|
206
|
-
def list_heartbeats(*, session: "Session"):
|
|
291
|
+
def list_heartbeats(*, session: "Session") -> list["HeartbeatDict"]:
|
|
207
292
|
"""
|
|
208
293
|
List all heartbeats.
|
|
209
294
|
|
|
210
295
|
:param session: The database session in use.
|
|
211
296
|
|
|
212
|
-
:returns: List of
|
|
297
|
+
:returns: List of dicts
|
|
213
298
|
"""
|
|
214
299
|
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
300
|
+
stmt = select(
|
|
301
|
+
Heartbeat.readable,
|
|
302
|
+
Heartbeat.hostname,
|
|
303
|
+
Heartbeat.pid,
|
|
304
|
+
Heartbeat.thread_name,
|
|
305
|
+
Heartbeat.updated_at,
|
|
306
|
+
Heartbeat.created_at,
|
|
307
|
+
Heartbeat.payload
|
|
308
|
+
).order_by(
|
|
309
|
+
Heartbeat.readable,
|
|
310
|
+
Heartbeat.hostname,
|
|
311
|
+
Heartbeat.thread_name
|
|
312
|
+
)
|
|
313
|
+
|
|
314
|
+
result = session.execute(stmt).all()
|
|
226
315
|
json_result = []
|
|
227
316
|
for element in result:
|
|
228
317
|
json_result.append(element._asdict())
|
|
@@ -230,7 +319,13 @@ def list_heartbeats(*, session: "Session"):
|
|
|
230
319
|
|
|
231
320
|
|
|
232
321
|
@read_session
|
|
233
|
-
def list_payload_counts(
|
|
322
|
+
def list_payload_counts(
|
|
323
|
+
executable: str,
|
|
324
|
+
older_than: int = 600,
|
|
325
|
+
hash_executable: Optional[str] = None,
|
|
326
|
+
*,
|
|
327
|
+
session: "Session"
|
|
328
|
+
) -> dict[str, int]:
|
|
234
329
|
"""
|
|
235
330
|
Give the counts of number of threads per payload for a certain executable.
|
|
236
331
|
|
|
@@ -239,22 +334,27 @@ def list_payload_counts(executable, older_than=600, hash_executable=None, *, ses
|
|
|
239
334
|
:param hash_executable: Hash of the executable.
|
|
240
335
|
:param session: The database session in use.
|
|
241
336
|
|
|
242
|
-
:returns:
|
|
337
|
+
:returns: Dict
|
|
243
338
|
"""
|
|
244
339
|
|
|
245
340
|
if not hash_executable:
|
|
246
341
|
hash_executable = calc_hash(executable)
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
342
|
+
stmt = select(
|
|
343
|
+
Heartbeat.payload,
|
|
344
|
+
func.count(Heartbeat.payload)
|
|
345
|
+
).where(
|
|
346
|
+
and_(Heartbeat.executable == hash_executable,
|
|
347
|
+
Heartbeat.updated_at >= datetime.datetime.utcnow() - datetime.timedelta(seconds=older_than))
|
|
348
|
+
).group_by(
|
|
349
|
+
Heartbeat.payload
|
|
350
|
+
).order_by(
|
|
351
|
+
Heartbeat.payload
|
|
352
|
+
)
|
|
353
|
+
|
|
354
|
+
return dict((payload, count) for payload, count in session.execute(stmt).all() if payload)
|
|
355
|
+
|
|
356
|
+
|
|
357
|
+
def calc_hash(executable: str) -> str:
|
|
258
358
|
"""
|
|
259
359
|
Calculates a SHA256 hash.
|
|
260
360
|
|
rucio/core/identity.py
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
# -*- coding: utf-8 -*-
|
|
2
1
|
# Copyright European Organization for Nuclear Research (CERN) since 2012
|
|
3
2
|
#
|
|
4
3
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
@@ -16,8 +15,7 @@
|
|
|
16
15
|
import hashlib
|
|
17
16
|
import os
|
|
18
17
|
from re import match
|
|
19
|
-
from typing import Optional
|
|
20
|
-
from typing import TYPE_CHECKING
|
|
18
|
+
from typing import TYPE_CHECKING, Optional
|
|
21
19
|
|
|
22
20
|
from sqlalchemy import select, true
|
|
23
21
|
from sqlalchemy.exc import IntegrityError
|
|
@@ -30,11 +28,14 @@ from rucio.db.sqla.constants import IdentityType
|
|
|
30
28
|
from rucio.db.sqla.session import read_session, transactional_session
|
|
31
29
|
|
|
32
30
|
if TYPE_CHECKING:
|
|
31
|
+
from collections.abc import Sequence
|
|
32
|
+
|
|
33
|
+
from sqlalchemy import Row
|
|
33
34
|
from sqlalchemy.orm import Session
|
|
34
35
|
|
|
35
36
|
|
|
36
37
|
@transactional_session
|
|
37
|
-
def add_identity(identity: str, type_: IdentityType, email: str, password: Optional[str] = None, *, session: "Session"):
|
|
38
|
+
def add_identity(identity: str, type_: IdentityType, email: str, password: Optional[str] = None, *, session: "Session") -> None:
|
|
38
39
|
"""
|
|
39
40
|
Creates a user identity.
|
|
40
41
|
|
|
@@ -103,7 +104,7 @@ def verify_identity(identity: str, type_: IdentityType, password: Optional[str]
|
|
|
103
104
|
|
|
104
105
|
|
|
105
106
|
@transactional_session
|
|
106
|
-
def del_identity(identity: str, type_: IdentityType, *, session: "Session"):
|
|
107
|
+
def del_identity(identity: str, type_: IdentityType, *, session: "Session") -> None:
|
|
107
108
|
"""
|
|
108
109
|
Deletes a user identity.
|
|
109
110
|
|
|
@@ -125,7 +126,16 @@ def del_identity(identity: str, type_: IdentityType, *, session: "Session"):
|
|
|
125
126
|
|
|
126
127
|
|
|
127
128
|
@transactional_session
|
|
128
|
-
def add_account_identity(
|
|
129
|
+
def add_account_identity(
|
|
130
|
+
identity: str,
|
|
131
|
+
type_: IdentityType,
|
|
132
|
+
account: InternalAccount,
|
|
133
|
+
email: str,
|
|
134
|
+
default: bool = False,
|
|
135
|
+
password: Optional[str] = None,
|
|
136
|
+
*,
|
|
137
|
+
session: "Session"
|
|
138
|
+
) -> None:
|
|
129
139
|
"""
|
|
130
140
|
Adds a membership association between identity and account.
|
|
131
141
|
|
|
@@ -167,7 +177,7 @@ def add_account_identity(identity: str, type_: IdentityType, account: InternalAc
|
|
|
167
177
|
|
|
168
178
|
|
|
169
179
|
@read_session
|
|
170
|
-
def exist_identity_account(identity: str, type_: IdentityType, account: InternalAccount, *, session: "Session"):
|
|
180
|
+
def exist_identity_account(identity: str, type_: IdentityType, account: InternalAccount, *, session: "Session") -> bool:
|
|
171
181
|
"""
|
|
172
182
|
Check if an identity is mapped to an account.
|
|
173
183
|
|
|
@@ -189,13 +199,13 @@ def exist_identity_account(identity: str, type_: IdentityType, account: Internal
|
|
|
189
199
|
|
|
190
200
|
|
|
191
201
|
@read_session
|
|
192
|
-
def get_default_account(identity: str, type_: IdentityType, oldest_if_none: bool = False, *, session: "Session"):
|
|
202
|
+
def get_default_account(identity: str, type_: IdentityType, oldest_if_none: bool = False, *, session: "Session") -> Optional[InternalAccount]:
|
|
193
203
|
"""
|
|
194
204
|
Retrieves the default account mapped to an identity.
|
|
195
205
|
|
|
196
206
|
:param identity: The identity key name. For example, x509DN, or a username.
|
|
197
207
|
:param type_: The type of the authentication (x509, gss, userpass, saml, oidc).
|
|
198
|
-
:param oldest_if_none: If True and no default account it found the
|
|
208
|
+
:param oldest_if_none: If True and no default account it found the oldest known
|
|
199
209
|
account of that identity will be chosen, if False and
|
|
200
210
|
no default account is found, exception will be raised.
|
|
201
211
|
:param session: The database session to use.
|
|
@@ -230,7 +240,7 @@ def get_default_account(identity: str, type_: IdentityType, oldest_if_none: bool
|
|
|
230
240
|
|
|
231
241
|
|
|
232
242
|
@transactional_session
|
|
233
|
-
def del_account_identity(identity: str, type_: IdentityType, account: InternalAccount, *, session: "Session"):
|
|
243
|
+
def del_account_identity(identity: str, type_: IdentityType, account: InternalAccount, *, session: "Session") -> None:
|
|
234
244
|
"""
|
|
235
245
|
Removes a membership association between identity and account.
|
|
236
246
|
|
|
@@ -253,7 +263,7 @@ def del_account_identity(identity: str, type_: IdentityType, account: InternalAc
|
|
|
253
263
|
|
|
254
264
|
|
|
255
265
|
@read_session
|
|
256
|
-
def list_identities(*, session: "Session", **kwargs):
|
|
266
|
+
def list_identities(*, session: "Session", **kwargs) -> "Sequence[Row[tuple[str, IdentityType]]]":
|
|
257
267
|
"""
|
|
258
268
|
Returns a list of all identities.
|
|
259
269
|
|
|
@@ -271,7 +281,7 @@ def list_identities(*, session: "Session", **kwargs):
|
|
|
271
281
|
|
|
272
282
|
|
|
273
283
|
@read_session
|
|
274
|
-
def list_accounts_for_identity(identity: str, type_: IdentityType, *, session: "Session"):
|
|
284
|
+
def list_accounts_for_identity(identity: str, type_: IdentityType, *, session: "Session") -> "Sequence[InternalAccount]":
|
|
275
285
|
"""
|
|
276
286
|
Returns a list of all accounts for an identity.
|
|
277
287
|
|
rucio/core/importer.py
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
# -*- coding: utf-8 -*-
|
|
2
1
|
# Copyright European Organization for Nuclear Research (CERN) since 2012
|
|
3
2
|
#
|
|
4
3
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
@@ -13,14 +12,21 @@
|
|
|
13
12
|
# See the License for the specific language governing permissions and
|
|
14
13
|
# limitations under the License.
|
|
15
14
|
|
|
16
|
-
from
|
|
15
|
+
from collections.abc import Iterable
|
|
16
|
+
from typing import TYPE_CHECKING, Any
|
|
17
|
+
|
|
18
|
+
from sqlalchemy import select
|
|
17
19
|
|
|
18
20
|
from rucio.common.config import config_get
|
|
21
|
+
from rucio.common.constants import RseAttr
|
|
19
22
|
from rucio.common.exception import RSEOperationNotSupported
|
|
20
23
|
from rucio.common.types import InternalAccount
|
|
21
|
-
from rucio.core import
|
|
24
|
+
from rucio.core import account as account_module
|
|
25
|
+
from rucio.core import distance as distance_module
|
|
26
|
+
from rucio.core import identity as identity_module
|
|
27
|
+
from rucio.core import rse as rse_module
|
|
22
28
|
from rucio.db.sqla import models
|
|
23
|
-
from rucio.db.sqla.constants import
|
|
29
|
+
from rucio.db.sqla.constants import AccountType, IdentityType, RSEType
|
|
24
30
|
from rucio.db.sqla.session import transactional_session
|
|
25
31
|
|
|
26
32
|
if TYPE_CHECKING:
|
|
@@ -28,7 +34,7 @@ if TYPE_CHECKING:
|
|
|
28
34
|
|
|
29
35
|
|
|
30
36
|
@transactional_session
|
|
31
|
-
def import_rses(rses, rse_sync_method='edit', attr_sync_method='edit', protocol_sync_method='edit', vo='def', *, session: "Session"):
|
|
37
|
+
def import_rses(rses: dict[str, dict[str, Any]], rse_sync_method: str = 'edit', attr_sync_method: str = 'edit', protocol_sync_method: str = 'edit', vo: str = 'def', *, session: "Session") -> None:
|
|
32
38
|
new_rses = []
|
|
33
39
|
for rse_name in rses:
|
|
34
40
|
rse = rses[rse_name]
|
|
@@ -104,8 +110,8 @@ def import_rses(rses, rse_sync_method='edit', attr_sync_method='edit', protocol_
|
|
|
104
110
|
|
|
105
111
|
# Attributes
|
|
106
112
|
attributes = rse.get('attributes', {})
|
|
107
|
-
attributes[
|
|
108
|
-
attributes[
|
|
113
|
+
attributes[RseAttr.LFN2PFN_ALGORITHM] = rse.get('lfn2pfn_algorithm')
|
|
114
|
+
attributes[RseAttr.VERIFY_CHECKSUM] = rse.get('verify_checksum')
|
|
109
115
|
|
|
110
116
|
old_attributes = rse_module.list_rse_attributes(rse_id=rse_id, session=session)
|
|
111
117
|
missing_attributes = [attribute for attribute in old_attributes if attribute not in attributes]
|
|
@@ -136,7 +142,7 @@ def import_rses(rses, rse_sync_method='edit', attr_sync_method='edit', protocol_
|
|
|
136
142
|
|
|
137
143
|
|
|
138
144
|
@transactional_session
|
|
139
|
-
def import_distances(distances, vo='def', *, session: "Session"):
|
|
145
|
+
def import_distances(distances, vo: str = 'def', *, session: "Session") -> None:
|
|
140
146
|
for src_rse_name in distances:
|
|
141
147
|
src = rse_module.get_rse_id(rse=src_rse_name, vo=vo, session=session)
|
|
142
148
|
for dest_rse_name in distances[src_rse_name]:
|
|
@@ -156,7 +162,7 @@ def import_distances(distances, vo='def', *, session: "Session"):
|
|
|
156
162
|
|
|
157
163
|
|
|
158
164
|
@transactional_session
|
|
159
|
-
def import_identities(identities, account_name, old_identities, old_identity_account, account_email, *, session: "Session"):
|
|
165
|
+
def import_identities(identities: Iterable[dict[str, Any]], account_name: str, old_identities: Iterable[tuple], old_identity_account: tuple[str, str, str], account_email: str, *, session: "Session") -> None:
|
|
160
166
|
for identity in identities:
|
|
161
167
|
identity['type'] = IdentityType[identity['type'].upper()]
|
|
162
168
|
|
|
@@ -185,14 +191,19 @@ def import_identities(identities, account_name, old_identities, old_identity_acc
|
|
|
185
191
|
|
|
186
192
|
|
|
187
193
|
@transactional_session
|
|
188
|
-
def import_accounts(accounts, vo='def', *, session: "Session"):
|
|
194
|
+
def import_accounts(accounts: Iterable[dict[str, Any]], vo: str = 'def', *, session: "Session") -> None:
|
|
189
195
|
vo_filter = {'account': InternalAccount(account='*', vo=vo)}
|
|
190
196
|
old_accounts = {account['account']: account for account in account_module.list_accounts(filter_=vo_filter, session=session)}
|
|
191
197
|
missing_accounts = [account for account in accounts if account['account'] not in old_accounts]
|
|
192
198
|
outdated_accounts = [account for account in accounts if account['account'] in old_accounts]
|
|
193
199
|
to_be_removed_accounts = [old_account for old_account in old_accounts if old_account not in [account['account'] for account in accounts]]
|
|
194
200
|
old_identities = identity_module.list_identities(session=session)
|
|
195
|
-
|
|
201
|
+
stmt = select(
|
|
202
|
+
models.IdentityAccountAssociation.identity,
|
|
203
|
+
models.IdentityAccountAssociation.identity_type,
|
|
204
|
+
models.IdentityAccountAssociation.account
|
|
205
|
+
)
|
|
206
|
+
old_identity_account = session.execute(stmt).all()
|
|
196
207
|
|
|
197
208
|
# add missing accounts
|
|
198
209
|
for account_dict in missing_accounts:
|
|
@@ -222,7 +233,7 @@ def import_accounts(accounts, vo='def', *, session: "Session"):
|
|
|
222
233
|
|
|
223
234
|
|
|
224
235
|
@transactional_session
|
|
225
|
-
def import_data(data, vo='def', *, session: "Session"):
|
|
236
|
+
def import_data(data: dict[str, Any], vo: str = 'def', *, session: "Session") -> None:
|
|
226
237
|
"""
|
|
227
238
|
Import data to add and update records in Rucio.
|
|
228
239
|
|