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/message.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,11 +15,11 @@
|
|
|
16
15
|
import json
|
|
17
16
|
from typing import TYPE_CHECKING
|
|
18
17
|
|
|
19
|
-
from sqlalchemy import or_,
|
|
18
|
+
from sqlalchemy import delete, insert, or_, select, update
|
|
20
19
|
from sqlalchemy.exc import IntegrityError
|
|
21
20
|
|
|
22
21
|
from rucio.common.config import config_get_list
|
|
23
|
-
from rucio.common.constants import
|
|
22
|
+
from rucio.common.constants import MAX_MESSAGE_LENGTH, HermesService
|
|
24
23
|
from rucio.common.exception import InvalidObject, RucioException
|
|
25
24
|
from rucio.common.utils import APIEncoder, chunks
|
|
26
25
|
from rucio.db.sqla import filter_thread_work
|
|
@@ -29,6 +28,7 @@ from rucio.db.sqla.session import transactional_session
|
|
|
29
28
|
|
|
30
29
|
if TYPE_CHECKING:
|
|
31
30
|
from typing import Any, Optional
|
|
31
|
+
|
|
32
32
|
from sqlalchemy.orm import Session
|
|
33
33
|
|
|
34
34
|
MessageType = dict[str, Any]
|
|
@@ -74,7 +74,10 @@ def add_messages(messages: "MessagesListType", *, session: "Session") -> None:
|
|
|
74
74
|
except TypeError as err: # noqa: F841
|
|
75
75
|
raise InvalidObject(f'Invalid JSON for payload: {err}')
|
|
76
76
|
for messages_chunk in chunks(msgs, 1000):
|
|
77
|
-
|
|
77
|
+
stmt = insert(
|
|
78
|
+
Message
|
|
79
|
+
)
|
|
80
|
+
session.execute(stmt, messages_chunk)
|
|
78
81
|
|
|
79
82
|
|
|
80
83
|
@transactional_session
|
|
@@ -114,45 +117,58 @@ def retrieve_messages(bulk: int = 1000,
|
|
|
114
117
|
"""
|
|
115
118
|
messages = []
|
|
116
119
|
try:
|
|
117
|
-
|
|
118
|
-
|
|
120
|
+
stmt_subquery = select(
|
|
121
|
+
Message.id
|
|
122
|
+
).order_by(
|
|
123
|
+
Message.created_at
|
|
124
|
+
)
|
|
125
|
+
stmt_subquery = filter_thread_work(session=session, query=stmt_subquery, total_threads=total_threads, thread_id=thread)
|
|
119
126
|
if event_type:
|
|
120
|
-
|
|
127
|
+
stmt_subquery = stmt_subquery.where(
|
|
128
|
+
Message.event_type == event_type
|
|
129
|
+
)
|
|
121
130
|
elif old_mode:
|
|
122
|
-
|
|
131
|
+
stmt_subquery = stmt_subquery.where(
|
|
132
|
+
Message.event_type != 'email'
|
|
133
|
+
)
|
|
123
134
|
|
|
124
135
|
# Step 1:
|
|
125
136
|
# MySQL does not support limits in nested queries, limit on the outer query instead.
|
|
126
137
|
# This is not as performant, but the best we can get from MySQL.
|
|
127
138
|
# FIXME: SQLAlchemy generates wrong nowait MySQL8 statement for MySQL5
|
|
128
139
|
# Remove once this is resolved in SQLAlchemy
|
|
140
|
+
stmt = select(
|
|
141
|
+
Message.id,
|
|
142
|
+
Message.created_at,
|
|
143
|
+
Message.event_type,
|
|
144
|
+
Message.payload,
|
|
145
|
+
Message.services
|
|
146
|
+
)
|
|
129
147
|
if session.bind.dialect.name == 'mysql':
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
Message.event_type,
|
|
134
|
-
Message.payload,
|
|
135
|
-
Message.services)\
|
|
136
|
-
.filter(Message.id.in_(subquery))
|
|
148
|
+
stmt = stmt.where(
|
|
149
|
+
Message.id.in_(stmt_subquery)
|
|
150
|
+
)
|
|
137
151
|
else:
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
152
|
+
stmt_subquery = stmt_subquery.limit(
|
|
153
|
+
bulk
|
|
154
|
+
)
|
|
155
|
+
stmt = stmt.where(
|
|
156
|
+
Message.id.in_(stmt_subquery)
|
|
157
|
+
).with_for_update(
|
|
158
|
+
nowait=True
|
|
159
|
+
)
|
|
146
160
|
|
|
147
161
|
# Step 2:
|
|
148
162
|
# MySQL does not support limits in nested queries, limit on the outer query instead.
|
|
149
163
|
# This is not as performant, but the best we can get from MySQL.
|
|
150
164
|
if session.bind.dialect.name == 'mysql':
|
|
151
|
-
|
|
165
|
+
stmt = stmt.limit(
|
|
166
|
+
bulk
|
|
167
|
+
)
|
|
152
168
|
|
|
153
169
|
# Step 3:
|
|
154
170
|
# Assemble message object
|
|
155
|
-
for id_, created_at, event_type, payload, services in
|
|
171
|
+
for id_, created_at, event_type, payload, services in session.execute(stmt).all():
|
|
156
172
|
message = {'id': id_,
|
|
157
173
|
'created_at': created_at,
|
|
158
174
|
'event_type': event_type,
|
|
@@ -160,8 +176,12 @@ def retrieve_messages(bulk: int = 1000,
|
|
|
160
176
|
|
|
161
177
|
# Only switch SQL context when necessary
|
|
162
178
|
if payload == 'nolimit':
|
|
163
|
-
|
|
164
|
-
|
|
179
|
+
nolimit_stmt = select(
|
|
180
|
+
Message.payload_nolimit
|
|
181
|
+
).where(
|
|
182
|
+
Message.id == id_
|
|
183
|
+
)
|
|
184
|
+
message['payload'] = json.loads(str(session.execute(nolimit_stmt).scalar_one()))
|
|
165
185
|
else:
|
|
166
186
|
message['payload'] = json.loads(str(payload))
|
|
167
187
|
|
|
@@ -188,13 +208,22 @@ def delete_messages(messages: "MessagesListType", *, session: "Session") -> None
|
|
|
188
208
|
|
|
189
209
|
try:
|
|
190
210
|
if message_condition:
|
|
191
|
-
stmt = delete(
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
211
|
+
stmt = delete(
|
|
212
|
+
Message
|
|
213
|
+
).prefix_with(
|
|
214
|
+
'/*+ INDEX(messages MESSAGES_ID_PK) */',
|
|
215
|
+
dialect='oracle'
|
|
216
|
+
).where(
|
|
217
|
+
or_(*message_condition)
|
|
218
|
+
).execution_options(
|
|
219
|
+
synchronize_session=False
|
|
220
|
+
)
|
|
195
221
|
session.execute(stmt)
|
|
196
222
|
|
|
197
|
-
|
|
223
|
+
stmt = insert(
|
|
224
|
+
MessageHistory
|
|
225
|
+
)
|
|
226
|
+
session.execute(stmt, messages)
|
|
198
227
|
except IntegrityError as e:
|
|
199
228
|
raise RucioException(e.args)
|
|
200
229
|
|
|
@@ -208,7 +237,12 @@ def truncate_messages(*, session: "Session") -> None:
|
|
|
208
237
|
"""
|
|
209
238
|
|
|
210
239
|
try:
|
|
211
|
-
|
|
240
|
+
stmt = delete(
|
|
241
|
+
Message
|
|
242
|
+
).execution_options(
|
|
243
|
+
synchronize_session=False
|
|
244
|
+
)
|
|
245
|
+
session.execute(stmt)
|
|
212
246
|
except IntegrityError as e:
|
|
213
247
|
raise RucioException(e.args)
|
|
214
248
|
|
|
@@ -230,11 +264,18 @@ def update_messages_services(messages: "MessagesListType", services: str, *, ses
|
|
|
230
264
|
|
|
231
265
|
try:
|
|
232
266
|
if message_condition:
|
|
233
|
-
stmt = update(
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
267
|
+
stmt = update(
|
|
268
|
+
Message
|
|
269
|
+
).prefix_with(
|
|
270
|
+
'/*+ INDEX(messages MESSAGES_ID_PK) */',
|
|
271
|
+
dialect='oracle'
|
|
272
|
+
).where(
|
|
273
|
+
or_(*message_condition)
|
|
274
|
+
).execution_options(
|
|
275
|
+
synchronize_session=False
|
|
276
|
+
).values({
|
|
277
|
+
Message.services: services
|
|
278
|
+
})
|
|
238
279
|
session.execute(stmt)
|
|
239
280
|
|
|
240
281
|
except IntegrityError as err:
|
|
@@ -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");
|
|
@@ -14,15 +13,13 @@
|
|
|
14
13
|
# limitations under the License.
|
|
15
14
|
|
|
16
15
|
from re import match
|
|
17
|
-
from typing import TYPE_CHECKING
|
|
16
|
+
from typing import TYPE_CHECKING, Optional, Union
|
|
18
17
|
|
|
19
|
-
from sqlalchemy
|
|
20
|
-
from sqlalchemy.
|
|
18
|
+
from sqlalchemy import and_, delete, select
|
|
19
|
+
from sqlalchemy.exc import IntegrityError, NoResultFound
|
|
21
20
|
|
|
22
21
|
from rucio.common.constraints import AUTHORIZED_VALUE_TYPES
|
|
23
|
-
from rucio.common.exception import
|
|
24
|
-
KeyNotFound, InvalidValueForKey, UnsupportedValueType,
|
|
25
|
-
InvalidObject, UnsupportedKeyType)
|
|
22
|
+
from rucio.common.exception import Duplicate, InvalidObject, InvalidValueForKey, KeyNotFound, RucioException, UnsupportedKeyType, UnsupportedValueType
|
|
26
23
|
from rucio.db.sqla import models
|
|
27
24
|
from rucio.db.sqla.constants import DIDType, KeyType
|
|
28
25
|
from rucio.db.sqla.session import read_session, transactional_session
|
|
@@ -32,9 +29,9 @@ if TYPE_CHECKING:
|
|
|
32
29
|
|
|
33
30
|
|
|
34
31
|
@transactional_session
|
|
35
|
-
def add_key(key, key_type, value_type=None, value_regexp=None, *, session: "Session"):
|
|
32
|
+
def add_key(key: str, key_type: Union[KeyType, str], value_type: Optional[str] = None, value_regexp: Optional[str] = None, *, session: "Session") -> None:
|
|
36
33
|
"""
|
|
37
|
-
|
|
34
|
+
Add an allowed key for DID metadata (update the DID Metadata Conventions table with a new key).
|
|
38
35
|
|
|
39
36
|
:param key: the name for the new key.
|
|
40
37
|
:param key_type: the type of the key: all(container, dataset, file), collection(dataset or container), file, derived(compute from file for collection).
|
|
@@ -65,7 +62,7 @@ def add_key(key, key_type, value_type=None, value_regexp=None, *, session: "Sess
|
|
|
65
62
|
except ValueError:
|
|
66
63
|
raise UnsupportedKeyType('The type \'%s\' is not supported for keys!' % str(key_type))
|
|
67
64
|
|
|
68
|
-
new_key = models.
|
|
65
|
+
new_key = models.DIDMetaConventionsKey(key=key, value_type=value_type and str(value_type), value_regexp=value_regexp, key_type=key_type)
|
|
69
66
|
try:
|
|
70
67
|
new_key.save(session=session)
|
|
71
68
|
except IntegrityError as error:
|
|
@@ -77,46 +74,54 @@ def add_key(key, key_type, value_type=None, value_regexp=None, *, session: "Sess
|
|
|
77
74
|
or match('.*UniqueViolation.*duplicate key value violates unique constraint.*', error.args[0]) \
|
|
78
75
|
or match('.*IntegrityError.*columns? key.*not unique.*', error.args[0]):
|
|
79
76
|
raise Duplicate(f"key '{key}' already exists!")
|
|
80
|
-
raise
|
|
77
|
+
raise RucioException(error.args)
|
|
81
78
|
|
|
82
79
|
|
|
83
80
|
@transactional_session
|
|
84
|
-
def del_key(key, *, session: "Session"):
|
|
81
|
+
def del_key(key: str, *, session: "Session") -> None:
|
|
85
82
|
"""
|
|
86
|
-
|
|
83
|
+
Delete a key in the DID Metadata Conventions table.
|
|
87
84
|
|
|
88
85
|
:param key: the name for the key.
|
|
89
86
|
:param session: The database session in use.
|
|
90
87
|
"""
|
|
91
|
-
|
|
88
|
+
stmt = delete(
|
|
89
|
+
models.DIDMetaConventionsKey
|
|
90
|
+
).where(
|
|
91
|
+
models.DIDMetaConventionsKey.key == key
|
|
92
|
+
)
|
|
93
|
+
session.execute(stmt)
|
|
92
94
|
|
|
93
95
|
|
|
94
96
|
@read_session
|
|
95
|
-
def list_keys(*, session: "Session"):
|
|
97
|
+
def list_keys(*, session: "Session") -> list[str]:
|
|
96
98
|
"""
|
|
97
|
-
Lists all keys.
|
|
99
|
+
Lists all keys for DID Metadata Conventions.
|
|
98
100
|
|
|
99
101
|
:param session: The database session in use.
|
|
100
102
|
|
|
101
103
|
:returns: A list containing all keys.
|
|
102
104
|
"""
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
return key_list
|
|
105
|
+
stmt = select(
|
|
106
|
+
models.DIDMetaConventionsKey.key
|
|
107
|
+
)
|
|
108
|
+
return list(session.execute(stmt).scalars().all())
|
|
108
109
|
|
|
109
110
|
|
|
110
111
|
@transactional_session
|
|
111
|
-
def add_value(key, value, *, session: "Session"):
|
|
112
|
+
def add_value(key: str, value: str, *, session: "Session") -> None:
|
|
112
113
|
"""
|
|
113
|
-
Adds a new value
|
|
114
|
+
Adds a new value for a key in DID Metadata Convention.
|
|
114
115
|
|
|
115
116
|
:param key: the name for the key.
|
|
116
117
|
:param value: the value.
|
|
117
118
|
:param session: The database session in use.
|
|
119
|
+
|
|
120
|
+
:raises Duplicate: Key-Value pair exists
|
|
121
|
+
:raises KeyNotFound: Key not in metadata conventions table
|
|
122
|
+
:raises InvalidValueForKey: Value conflicts with rse expression for key values or does not have the correct type
|
|
118
123
|
"""
|
|
119
|
-
new_value = models.
|
|
124
|
+
new_value = models.DIDMetaConventionsConstraint(key=key, value=value)
|
|
120
125
|
try:
|
|
121
126
|
new_value.save(session=session)
|
|
122
127
|
except IntegrityError as error:
|
|
@@ -137,37 +142,43 @@ def add_value(key, value, *, session: "Session"):
|
|
|
137
142
|
|
|
138
143
|
raise RucioException(error.args)
|
|
139
144
|
|
|
140
|
-
|
|
145
|
+
statement = select(
|
|
146
|
+
models.DIDMetaConventionsKey,
|
|
147
|
+
).where(
|
|
148
|
+
models.DIDMetaConventionsKey.key == key
|
|
149
|
+
)
|
|
150
|
+
query = session.execute(statement).scalar_one()
|
|
141
151
|
|
|
142
152
|
# Check value against regexp, if defined
|
|
143
|
-
if
|
|
144
|
-
raise InvalidValueForKey("The value
|
|
153
|
+
if query.value_regexp and not match(query.value_regexp, value):
|
|
154
|
+
raise InvalidValueForKey(f"The value {value} for the key {key} does not match the regular expression {query.value_regexp}")
|
|
145
155
|
|
|
146
156
|
# Check value type, if defined
|
|
147
157
|
type_map = dict([(str(t), t) for t in AUTHORIZED_VALUE_TYPES])
|
|
148
|
-
if
|
|
149
|
-
raise InvalidValueForKey("The value
|
|
158
|
+
if query.value_type and not isinstance(value, type_map.get(query.value_type)): # type: ignore ; Typing error caused by 'isinstaince' not thinking types count as classes
|
|
159
|
+
raise InvalidValueForKey(f"The value {value} for the key {key} does not match the required type {query.value_type}")
|
|
150
160
|
|
|
151
161
|
|
|
152
162
|
@read_session
|
|
153
|
-
def list_values(key, *, session: "Session"):
|
|
163
|
+
def list_values(key: str, *, session: "Session") -> list[str]:
|
|
154
164
|
"""
|
|
155
|
-
Lists all values for a key.
|
|
165
|
+
Lists all allowed values for a DID key (all values for a key in DID Metadata Conventions).
|
|
156
166
|
|
|
157
167
|
:param key: the name for the key.
|
|
158
168
|
:param session: The database session in use.
|
|
159
169
|
|
|
160
170
|
:returns: A list containing all values.
|
|
161
171
|
"""
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
172
|
+
statement = select(
|
|
173
|
+
models.DIDMetaConventionsConstraint.value
|
|
174
|
+
).where(
|
|
175
|
+
models.DIDMetaConventionsConstraint.key == key
|
|
176
|
+
)
|
|
177
|
+
return list(session.execute(statement).scalars().all())
|
|
167
178
|
|
|
168
179
|
|
|
169
180
|
@read_session
|
|
170
|
-
def validate_meta(meta, did_type, *, session: "Session"):
|
|
181
|
+
def validate_meta(meta: dict, did_type: DIDType, *, session: "Session") -> None:
|
|
171
182
|
"""
|
|
172
183
|
Validates metadata for a did.
|
|
173
184
|
|
|
@@ -175,16 +186,18 @@ def validate_meta(meta, did_type, *, session: "Session"):
|
|
|
175
186
|
:param meta: the type of the did, e.g, DATASET, CONTAINER, FILE.
|
|
176
187
|
:param session: The database session in use.
|
|
177
188
|
|
|
178
|
-
:
|
|
189
|
+
:raises InvalidObject:
|
|
179
190
|
"""
|
|
180
191
|
# For now only validate the datatype for datasets
|
|
181
192
|
key = 'datatype'
|
|
182
193
|
if did_type == DIDType.DATASET and key in meta:
|
|
183
194
|
try:
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
195
|
+
statement = select(
|
|
196
|
+
models.DIDMetaConventionsConstraint.value
|
|
197
|
+
).where(
|
|
198
|
+
and_(models.DIDMetaConventionsConstraint.value == meta[key],
|
|
199
|
+
models.DIDMetaConventionsConstraint.key == key)
|
|
200
|
+
)
|
|
201
|
+
session.execute(statement).one()
|
|
188
202
|
except NoResultFound:
|
|
189
|
-
|
|
190
|
-
raise InvalidObject("The value '%s' for the key '%s' is not valid" % (meta[key], key))
|
|
203
|
+
raise InvalidObject(f"The value {meta[key]}' for the key {key} is not valid")
|
rucio/core/monitor.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");
|
|
@@ -17,7 +16,6 @@
|
|
|
17
16
|
Graphite and prometheus metrics
|
|
18
17
|
"""
|
|
19
18
|
|
|
20
|
-
import __main__ as main
|
|
21
19
|
import atexit
|
|
22
20
|
import logging
|
|
23
21
|
import os
|
|
@@ -28,23 +26,26 @@ from datetime import datetime, timedelta
|
|
|
28
26
|
from functools import wraps
|
|
29
27
|
from pathlib import Path
|
|
30
28
|
from threading import Lock
|
|
31
|
-
from typing import Any, Optional, TypeVar, Union
|
|
29
|
+
from typing import TYPE_CHECKING, Any, Optional, TypeVar, Union
|
|
32
30
|
|
|
33
|
-
from prometheus_client import
|
|
34
|
-
push_to_gateway, start_http_server, values)
|
|
31
|
+
from prometheus_client import REGISTRY, CollectorRegistry, Counter, Gauge, Histogram, generate_latest, multiprocess, push_to_gateway, start_http_server, values
|
|
35
32
|
from statsd import StatsClient
|
|
36
33
|
|
|
34
|
+
import __main__ as main
|
|
37
35
|
from rucio.common.config import config_get, config_get_bool, config_get_int
|
|
38
36
|
from rucio.common.stopwatch import Stopwatch
|
|
39
37
|
from rucio.common.utils import retrying
|
|
40
38
|
|
|
39
|
+
if TYPE_CHECKING:
|
|
40
|
+
from rucio.common.types import LoggerFunction
|
|
41
|
+
|
|
41
42
|
_T = TypeVar('_T')
|
|
42
43
|
_M = TypeVar('_M', bound="_MultiMetric")
|
|
43
44
|
|
|
44
45
|
PROMETHEUS_MULTIPROC_DIR = os.environ.get('PROMETHEUS_MULTIPROC_DIR', os.environ.get('prometheus_multiproc_dir', None))
|
|
45
46
|
|
|
46
47
|
|
|
47
|
-
def cleanup_prometheus_files_at_exit():
|
|
48
|
+
def cleanup_prometheus_files_at_exit() -> None:
|
|
48
49
|
if PROMETHEUS_MULTIPROC_DIR:
|
|
49
50
|
multiprocess.mark_process_dead(os.getpid())
|
|
50
51
|
|
|
@@ -101,7 +102,12 @@ METRICS_LOCK = Lock()
|
|
|
101
102
|
_HISTOGRAM_DEFAULT_BUCKETS = Histogram.DEFAULT_BUCKETS
|
|
102
103
|
|
|
103
104
|
|
|
104
|
-
def _cleanup_old_prometheus_files(
|
|
105
|
+
def _cleanup_old_prometheus_files(
|
|
106
|
+
path: str,
|
|
107
|
+
file_pattern: str,
|
|
108
|
+
cleanup_delay: float,
|
|
109
|
+
logger: "LoggerFunction"
|
|
110
|
+
) -> None:
|
|
105
111
|
"""cleanup behind processes which didn't finish gracefully."""
|
|
106
112
|
|
|
107
113
|
oldest_accepted_mtime = datetime.now() - timedelta(seconds=cleanup_delay)
|
|
@@ -120,7 +126,7 @@ def _cleanup_old_prometheus_files(path, file_pattern, cleanup_delay, logger):
|
|
|
120
126
|
pass
|
|
121
127
|
|
|
122
128
|
|
|
123
|
-
def cleanup_old_prometheus_files(logger=logging.log):
|
|
129
|
+
def cleanup_old_prometheus_files(logger: "LoggerFunction" = logging.log) -> None:
|
|
124
130
|
path = PROMETHEUS_MULTIPROC_DIR
|
|
125
131
|
if path:
|
|
126
132
|
_cleanup_old_prometheus_files(path, file_pattern='gauge_live*.db', cleanup_delay=timedelta(hours=1).total_seconds(), logger=logger)
|
|
@@ -130,7 +136,7 @@ def cleanup_old_prometheus_files(logger=logging.log):
|
|
|
130
136
|
@retrying(retry_on_exception=lambda _: True,
|
|
131
137
|
wait_fixed=500,
|
|
132
138
|
stop_max_attempt_number=2)
|
|
133
|
-
def generate_prometheus_metrics():
|
|
139
|
+
def generate_prometheus_metrics() -> bytes:
|
|
134
140
|
cleanup_old_prometheus_files()
|
|
135
141
|
|
|
136
142
|
registry = CollectorRegistry()
|
|
@@ -209,7 +215,7 @@ class _MultiCounter(_MultiMetric):
|
|
|
209
215
|
if STATSD_CLIENT:
|
|
210
216
|
STATSD_CLIENT.incr(self._statsd, delta)
|
|
211
217
|
|
|
212
|
-
def init_prometheus_metric(self, name: str, documentation:
|
|
218
|
+
def init_prometheus_metric(self, name: str, documentation: str, labelnames: Sequence[str] = ()) -> Counter:
|
|
213
219
|
return Counter(name, documentation, labelnames=labelnames, registry=self._registry)
|
|
214
220
|
|
|
215
221
|
|
|
@@ -220,7 +226,7 @@ class _MultiGauge(_MultiMetric):
|
|
|
220
226
|
if STATSD_CLIENT:
|
|
221
227
|
STATSD_CLIENT.gauge(self._statsd, value)
|
|
222
228
|
|
|
223
|
-
def init_prometheus_metric(self, name: str, documentation:
|
|
229
|
+
def init_prometheus_metric(self, name: str, documentation: str, labelnames: Sequence[str] = ()) -> Gauge:
|
|
224
230
|
return Gauge(name, documentation, labelnames=labelnames, registry=self._registry)
|
|
225
231
|
|
|
226
232
|
|
|
@@ -244,7 +250,7 @@ class _MultiTiming(_MultiMetric):
|
|
|
244
250
|
if STATSD_CLIENT:
|
|
245
251
|
STATSD_CLIENT.timing(self._statsd, value * 1000)
|
|
246
252
|
|
|
247
|
-
def init_prometheus_metric(self, name: str, documentation:
|
|
253
|
+
def init_prometheus_metric(self, name: str, documentation: str, labelnames: Sequence[str] = ()) -> Histogram:
|
|
248
254
|
return Histogram(name, documentation, labelnames=labelnames, registry=self._registry, buckets=self._histogram_buckets)
|
|
249
255
|
|
|
250
256
|
def __enter__(self):
|
|
@@ -336,7 +342,7 @@ class MetricManager:
|
|
|
336
342
|
self.registry = registry or REGISTRY
|
|
337
343
|
self.push_gateways = push_gateways or []
|
|
338
344
|
|
|
339
|
-
def full_name(self, name: str):
|
|
345
|
+
def full_name(self, name: str) -> str:
|
|
340
346
|
if self.prefix:
|
|
341
347
|
return f'{self.prefix}.{name}'
|
|
342
348
|
return name
|