rucio 37.0.0rc1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of rucio might be problematic. Click here for more details.
- rucio/__init__.py +17 -0
- rucio/alembicrevision.py +15 -0
- rucio/cli/__init__.py +14 -0
- rucio/cli/account.py +216 -0
- rucio/cli/bin_legacy/__init__.py +13 -0
- rucio/cli/bin_legacy/rucio.py +2825 -0
- rucio/cli/bin_legacy/rucio_admin.py +2500 -0
- rucio/cli/command.py +272 -0
- rucio/cli/config.py +72 -0
- rucio/cli/did.py +191 -0
- rucio/cli/download.py +128 -0
- rucio/cli/lifetime_exception.py +33 -0
- rucio/cli/replica.py +162 -0
- rucio/cli/rse.py +293 -0
- rucio/cli/rule.py +158 -0
- rucio/cli/scope.py +40 -0
- rucio/cli/subscription.py +73 -0
- rucio/cli/upload.py +60 -0
- rucio/cli/utils.py +226 -0
- rucio/client/__init__.py +15 -0
- rucio/client/accountclient.py +432 -0
- rucio/client/accountlimitclient.py +183 -0
- rucio/client/baseclient.py +983 -0
- rucio/client/client.py +120 -0
- rucio/client/configclient.py +126 -0
- rucio/client/credentialclient.py +59 -0
- rucio/client/didclient.py +868 -0
- rucio/client/diracclient.py +56 -0
- rucio/client/downloadclient.py +1783 -0
- rucio/client/exportclient.py +44 -0
- rucio/client/fileclient.py +50 -0
- rucio/client/importclient.py +42 -0
- rucio/client/lifetimeclient.py +90 -0
- rucio/client/lockclient.py +109 -0
- rucio/client/metaconventionsclient.py +140 -0
- rucio/client/pingclient.py +44 -0
- rucio/client/replicaclient.py +452 -0
- rucio/client/requestclient.py +125 -0
- rucio/client/richclient.py +317 -0
- rucio/client/rseclient.py +746 -0
- rucio/client/ruleclient.py +294 -0
- rucio/client/scopeclient.py +90 -0
- rucio/client/subscriptionclient.py +173 -0
- rucio/client/touchclient.py +82 -0
- rucio/client/uploadclient.py +969 -0
- rucio/common/__init__.py +13 -0
- rucio/common/bittorrent.py +234 -0
- rucio/common/cache.py +111 -0
- rucio/common/checksum.py +168 -0
- rucio/common/client.py +122 -0
- rucio/common/config.py +788 -0
- rucio/common/constants.py +217 -0
- rucio/common/constraints.py +17 -0
- rucio/common/didtype.py +237 -0
- rucio/common/dumper/__init__.py +342 -0
- rucio/common/dumper/consistency.py +497 -0
- rucio/common/dumper/data_models.py +362 -0
- rucio/common/dumper/path_parsing.py +75 -0
- rucio/common/exception.py +1208 -0
- rucio/common/extra.py +31 -0
- rucio/common/logging.py +420 -0
- rucio/common/pcache.py +1409 -0
- rucio/common/plugins.py +185 -0
- rucio/common/policy.py +93 -0
- rucio/common/schema/__init__.py +200 -0
- rucio/common/schema/generic.py +416 -0
- rucio/common/schema/generic_multi_vo.py +395 -0
- rucio/common/stomp_utils.py +423 -0
- rucio/common/stopwatch.py +55 -0
- rucio/common/test_rucio_server.py +154 -0
- rucio/common/types.py +483 -0
- rucio/common/utils.py +1688 -0
- rucio/core/__init__.py +13 -0
- rucio/core/account.py +496 -0
- rucio/core/account_counter.py +236 -0
- rucio/core/account_limit.py +425 -0
- rucio/core/authentication.py +620 -0
- rucio/core/config.py +437 -0
- rucio/core/credential.py +224 -0
- rucio/core/did.py +3004 -0
- rucio/core/did_meta_plugins/__init__.py +252 -0
- rucio/core/did_meta_plugins/did_column_meta.py +331 -0
- rucio/core/did_meta_plugins/did_meta_plugin_interface.py +165 -0
- rucio/core/did_meta_plugins/elasticsearch_meta.py +407 -0
- rucio/core/did_meta_plugins/filter_engine.py +672 -0
- rucio/core/did_meta_plugins/json_meta.py +240 -0
- rucio/core/did_meta_plugins/mongo_meta.py +229 -0
- rucio/core/did_meta_plugins/postgres_meta.py +352 -0
- rucio/core/dirac.py +237 -0
- rucio/core/distance.py +187 -0
- rucio/core/exporter.py +59 -0
- rucio/core/heartbeat.py +363 -0
- rucio/core/identity.py +301 -0
- rucio/core/importer.py +260 -0
- rucio/core/lifetime_exception.py +377 -0
- rucio/core/lock.py +577 -0
- rucio/core/message.py +288 -0
- rucio/core/meta_conventions.py +203 -0
- rucio/core/monitor.py +448 -0
- rucio/core/naming_convention.py +195 -0
- rucio/core/nongrid_trace.py +136 -0
- rucio/core/oidc.py +1463 -0
- rucio/core/permission/__init__.py +161 -0
- rucio/core/permission/generic.py +1124 -0
- rucio/core/permission/generic_multi_vo.py +1144 -0
- rucio/core/quarantined_replica.py +224 -0
- rucio/core/replica.py +4483 -0
- rucio/core/replica_sorter.py +362 -0
- rucio/core/request.py +3091 -0
- rucio/core/rse.py +2079 -0
- rucio/core/rse_counter.py +185 -0
- rucio/core/rse_expression_parser.py +459 -0
- rucio/core/rse_selector.py +304 -0
- rucio/core/rule.py +4484 -0
- rucio/core/rule_grouping.py +1620 -0
- rucio/core/scope.py +181 -0
- rucio/core/subscription.py +362 -0
- rucio/core/topology.py +490 -0
- rucio/core/trace.py +375 -0
- rucio/core/transfer.py +1531 -0
- rucio/core/vo.py +169 -0
- rucio/core/volatile_replica.py +151 -0
- rucio/daemons/__init__.py +13 -0
- rucio/daemons/abacus/__init__.py +13 -0
- rucio/daemons/abacus/account.py +116 -0
- rucio/daemons/abacus/collection_replica.py +124 -0
- rucio/daemons/abacus/rse.py +117 -0
- rucio/daemons/atropos/__init__.py +13 -0
- rucio/daemons/atropos/atropos.py +242 -0
- rucio/daemons/auditor/__init__.py +289 -0
- rucio/daemons/auditor/hdfs.py +97 -0
- rucio/daemons/auditor/srmdumps.py +355 -0
- rucio/daemons/automatix/__init__.py +13 -0
- rucio/daemons/automatix/automatix.py +304 -0
- rucio/daemons/badreplicas/__init__.py +13 -0
- rucio/daemons/badreplicas/minos.py +322 -0
- rucio/daemons/badreplicas/minos_temporary_expiration.py +171 -0
- rucio/daemons/badreplicas/necromancer.py +196 -0
- rucio/daemons/bb8/__init__.py +13 -0
- rucio/daemons/bb8/bb8.py +353 -0
- rucio/daemons/bb8/common.py +759 -0
- rucio/daemons/bb8/nuclei_background_rebalance.py +153 -0
- rucio/daemons/bb8/t2_background_rebalance.py +153 -0
- rucio/daemons/cache/__init__.py +13 -0
- rucio/daemons/cache/consumer.py +133 -0
- rucio/daemons/common.py +405 -0
- rucio/daemons/conveyor/__init__.py +13 -0
- rucio/daemons/conveyor/common.py +562 -0
- rucio/daemons/conveyor/finisher.py +529 -0
- rucio/daemons/conveyor/poller.py +394 -0
- rucio/daemons/conveyor/preparer.py +205 -0
- rucio/daemons/conveyor/receiver.py +179 -0
- rucio/daemons/conveyor/stager.py +133 -0
- rucio/daemons/conveyor/submitter.py +403 -0
- rucio/daemons/conveyor/throttler.py +532 -0
- rucio/daemons/follower/__init__.py +13 -0
- rucio/daemons/follower/follower.py +101 -0
- rucio/daemons/hermes/__init__.py +13 -0
- rucio/daemons/hermes/hermes.py +534 -0
- rucio/daemons/judge/__init__.py +13 -0
- rucio/daemons/judge/cleaner.py +159 -0
- rucio/daemons/judge/evaluator.py +185 -0
- rucio/daemons/judge/injector.py +162 -0
- rucio/daemons/judge/repairer.py +154 -0
- rucio/daemons/oauthmanager/__init__.py +13 -0
- rucio/daemons/oauthmanager/oauthmanager.py +198 -0
- rucio/daemons/reaper/__init__.py +13 -0
- rucio/daemons/reaper/dark_reaper.py +282 -0
- rucio/daemons/reaper/reaper.py +739 -0
- rucio/daemons/replicarecoverer/__init__.py +13 -0
- rucio/daemons/replicarecoverer/suspicious_replica_recoverer.py +626 -0
- rucio/daemons/rsedecommissioner/__init__.py +13 -0
- rucio/daemons/rsedecommissioner/config.py +81 -0
- rucio/daemons/rsedecommissioner/profiles/__init__.py +24 -0
- rucio/daemons/rsedecommissioner/profiles/atlas.py +60 -0
- rucio/daemons/rsedecommissioner/profiles/generic.py +452 -0
- rucio/daemons/rsedecommissioner/profiles/types.py +93 -0
- rucio/daemons/rsedecommissioner/rse_decommissioner.py +280 -0
- rucio/daemons/storage/__init__.py +13 -0
- rucio/daemons/storage/consistency/__init__.py +13 -0
- rucio/daemons/storage/consistency/actions.py +848 -0
- rucio/daemons/tracer/__init__.py +13 -0
- rucio/daemons/tracer/kronos.py +511 -0
- rucio/daemons/transmogrifier/__init__.py +13 -0
- rucio/daemons/transmogrifier/transmogrifier.py +762 -0
- rucio/daemons/undertaker/__init__.py +13 -0
- rucio/daemons/undertaker/undertaker.py +137 -0
- rucio/db/__init__.py +13 -0
- rucio/db/sqla/__init__.py +52 -0
- rucio/db/sqla/constants.py +206 -0
- rucio/db/sqla/migrate_repo/__init__.py +13 -0
- rucio/db/sqla/migrate_repo/env.py +110 -0
- rucio/db/sqla/migrate_repo/versions/01eaf73ab656_add_new_rule_notification_state_progress.py +70 -0
- rucio/db/sqla/migrate_repo/versions/0437a40dbfd1_add_eol_at_in_rules.py +47 -0
- rucio/db/sqla/migrate_repo/versions/0f1adb7a599a_create_transfer_hops_table.py +59 -0
- rucio/db/sqla/migrate_repo/versions/102efcf145f4_added_stuck_at_column_to_rules.py +43 -0
- rucio/db/sqla/migrate_repo/versions/13d4f70c66a9_introduce_transfer_limits.py +91 -0
- rucio/db/sqla/migrate_repo/versions/140fef722e91_cleanup_distances_table.py +76 -0
- rucio/db/sqla/migrate_repo/versions/14ec5aeb64cf_add_request_external_host.py +43 -0
- rucio/db/sqla/migrate_repo/versions/156fb5b5a14_add_request_type_to_requests_idx.py +50 -0
- rucio/db/sqla/migrate_repo/versions/1677d4d803c8_split_rse_availability_into_multiple.py +68 -0
- rucio/db/sqla/migrate_repo/versions/16a0aca82e12_create_index_on_table_replicas_path.py +40 -0
- rucio/db/sqla/migrate_repo/versions/1803333ac20f_adding_provenance_and_phys_group.py +45 -0
- rucio/db/sqla/migrate_repo/versions/1a29d6a9504c_add_didtype_chck_to_requests.py +60 -0
- rucio/db/sqla/migrate_repo/versions/1a80adff031a_create_index_on_rules_hist_recent.py +40 -0
- rucio/db/sqla/migrate_repo/versions/1c45d9730ca6_increase_identity_length.py +140 -0
- rucio/db/sqla/migrate_repo/versions/1d1215494e95_add_quarantined_replicas_table.py +73 -0
- rucio/db/sqla/migrate_repo/versions/1d96f484df21_asynchronous_rules_and_rule_approval.py +74 -0
- rucio/db/sqla/migrate_repo/versions/1f46c5f240ac_add_bytes_column_to_bad_replicas.py +43 -0
- rucio/db/sqla/migrate_repo/versions/1fc15ab60d43_add_message_history_table.py +50 -0
- rucio/db/sqla/migrate_repo/versions/2190e703eb6e_move_rse_settings_to_rse_attributes.py +134 -0
- rucio/db/sqla/migrate_repo/versions/21d6b9dc9961_add_mismatch_scheme_state_to_requests.py +64 -0
- rucio/db/sqla/migrate_repo/versions/22cf51430c78_add_availability_column_to_table_rses.py +39 -0
- rucio/db/sqla/migrate_repo/versions/22d887e4ec0a_create_sources_table.py +64 -0
- rucio/db/sqla/migrate_repo/versions/25821a8a45a3_remove_unique_constraint_on_requests.py +51 -0
- rucio/db/sqla/migrate_repo/versions/25fc855625cf_added_unique_constraint_to_rules.py +41 -0
- rucio/db/sqla/migrate_repo/versions/269fee20dee9_add_repair_cnt_to_locks.py +43 -0
- rucio/db/sqla/migrate_repo/versions/271a46ea6244_add_ignore_availability_column_to_rules.py +44 -0
- rucio/db/sqla/migrate_repo/versions/277b5fbb41d3_switch_heartbeats_executable.py +53 -0
- rucio/db/sqla/migrate_repo/versions/27e3a68927fb_remove_replicas_tombstone_and_replicas_.py +38 -0
- rucio/db/sqla/migrate_repo/versions/2854cd9e168_added_rule_id_column.py +47 -0
- rucio/db/sqla/migrate_repo/versions/295289b5a800_processed_by_and__at_in_requests.py +45 -0
- rucio/db/sqla/migrate_repo/versions/2962ece31cf4_add_nbaccesses_column_in_the_did_table.py +45 -0
- rucio/db/sqla/migrate_repo/versions/2af3291ec4c_added_replicas_history_table.py +57 -0
- rucio/db/sqla/migrate_repo/versions/2b69addda658_add_columns_for_third_party_copy_read_.py +45 -0
- rucio/db/sqla/migrate_repo/versions/2b8e7bcb4783_add_config_table.py +69 -0
- rucio/db/sqla/migrate_repo/versions/2ba5229cb54c_add_submitted_at_to_requests_table.py +43 -0
- rucio/db/sqla/migrate_repo/versions/2cbee484dcf9_added_column_volume_to_rse_transfer_.py +42 -0
- rucio/db/sqla/migrate_repo/versions/2edee4a83846_add_source_to_requests_and_requests_.py +47 -0
- rucio/db/sqla/migrate_repo/versions/2eef46be23d4_change_tokens_pk.py +46 -0
- rucio/db/sqla/migrate_repo/versions/2f648fc909f3_index_in_rule_history_on_scope_name.py +40 -0
- rucio/db/sqla/migrate_repo/versions/3082b8cef557_add_naming_convention_table_and_closed_.py +67 -0
- rucio/db/sqla/migrate_repo/versions/30d5206e9cad_increase_oauthrequest_redirect_msg_.py +37 -0
- rucio/db/sqla/migrate_repo/versions/30fa38b6434e_add_index_on_service_column_in_the_message_table.py +44 -0
- rucio/db/sqla/migrate_repo/versions/3152492b110b_added_staging_area_column.py +77 -0
- rucio/db/sqla/migrate_repo/versions/32c7d2783f7e_create_bad_replicas_table.py +60 -0
- rucio/db/sqla/migrate_repo/versions/3345511706b8_replicas_table_pk_definition_is_in_.py +72 -0
- rucio/db/sqla/migrate_repo/versions/35ef10d1e11b_change_index_on_table_requests.py +42 -0
- rucio/db/sqla/migrate_repo/versions/379a19b5332d_create_rse_limits_table.py +65 -0
- rucio/db/sqla/migrate_repo/versions/384b96aa0f60_created_rule_history_tables.py +133 -0
- rucio/db/sqla/migrate_repo/versions/3ac1660a1a72_extend_distance_table.py +55 -0
- rucio/db/sqla/migrate_repo/versions/3ad36e2268b0_create_collection_replicas_updates_table.py +76 -0
- rucio/db/sqla/migrate_repo/versions/3c9df354071b_extend_waiting_request_state.py +60 -0
- rucio/db/sqla/migrate_repo/versions/3d9813fab443_add_a_new_state_lost_in_badfilesstatus.py +44 -0
- rucio/db/sqla/migrate_repo/versions/40ad39ce3160_add_transferred_at_to_requests_table.py +43 -0
- rucio/db/sqla/migrate_repo/versions/4207be2fd914_add_notification_column_to_rules.py +64 -0
- rucio/db/sqla/migrate_repo/versions/42db2617c364_create_index_on_requests_external_id.py +40 -0
- rucio/db/sqla/migrate_repo/versions/436827b13f82_added_column_activity_to_table_requests.py +43 -0
- rucio/db/sqla/migrate_repo/versions/44278720f774_update_requests_typ_sta_upd_idx_index.py +44 -0
- rucio/db/sqla/migrate_repo/versions/45378a1e76a8_create_collection_replica_table.py +78 -0
- rucio/db/sqla/migrate_repo/versions/469d262be19_removing_created_at_index.py +41 -0
- rucio/db/sqla/migrate_repo/versions/4783c1f49cb4_create_distance_table.py +59 -0
- rucio/db/sqla/migrate_repo/versions/49a21b4d4357_create_index_on_table_tokens.py +44 -0
- rucio/db/sqla/migrate_repo/versions/4a2cbedda8b9_add_source_replica_expression_column_to_.py +43 -0
- rucio/db/sqla/migrate_repo/versions/4a7182d9578b_added_bytes_length_accessed_at_columns.py +49 -0
- rucio/db/sqla/migrate_repo/versions/4bab9edd01fc_create_index_on_requests_rule_id.py +40 -0
- rucio/db/sqla/migrate_repo/versions/4c3a4acfe006_new_attr_account_table.py +63 -0
- rucio/db/sqla/migrate_repo/versions/4cf0a2e127d4_adding_transient_metadata.py +43 -0
- rucio/db/sqla/migrate_repo/versions/4df2c5ddabc0_remove_temporary_dids.py +55 -0
- rucio/db/sqla/migrate_repo/versions/50280c53117c_add_qos_class_to_rse.py +45 -0
- rucio/db/sqla/migrate_repo/versions/52153819589c_add_rse_id_to_replicas_table.py +43 -0
- rucio/db/sqla/migrate_repo/versions/52fd9f4916fa_added_activity_to_rules.py +43 -0
- rucio/db/sqla/migrate_repo/versions/53b479c3cb0f_fix_did_meta_table_missing_updated_at_.py +45 -0
- rucio/db/sqla/migrate_repo/versions/5673b4b6e843_add_wfms_metadata_to_rule_tables.py +47 -0
- rucio/db/sqla/migrate_repo/versions/575767d9f89_added_source_history_table.py +58 -0
- rucio/db/sqla/migrate_repo/versions/58bff7008037_add_started_at_to_requests.py +45 -0
- rucio/db/sqla/migrate_repo/versions/58c8b78301ab_rename_callback_to_message.py +106 -0
- rucio/db/sqla/migrate_repo/versions/5f139f77382a_added_child_rule_id_column.py +55 -0
- rucio/db/sqla/migrate_repo/versions/688ef1840840_adding_did_meta_table.py +50 -0
- rucio/db/sqla/migrate_repo/versions/6e572a9bfbf3_add_new_split_container_column_to_rules.py +47 -0
- rucio/db/sqla/migrate_repo/versions/70587619328_add_comment_column_for_subscriptions.py +43 -0
- rucio/db/sqla/migrate_repo/versions/739064d31565_remove_history_table_pks.py +41 -0
- rucio/db/sqla/migrate_repo/versions/7541902bf173_add_didsfollowed_and_followevents_table.py +91 -0
- rucio/db/sqla/migrate_repo/versions/7ec22226cdbf_new_replica_state_for_temporary_.py +72 -0
- rucio/db/sqla/migrate_repo/versions/810a41685bc1_added_columns_rse_transfer_limits.py +49 -0
- rucio/db/sqla/migrate_repo/versions/83f991c63a93_correct_rse_expression_length.py +43 -0
- rucio/db/sqla/migrate_repo/versions/8523998e2e76_increase_size_of_extended_attributes_.py +43 -0
- rucio/db/sqla/migrate_repo/versions/8ea9122275b1_adding_missing_function_based_indices.py +53 -0
- rucio/db/sqla/migrate_repo/versions/90f47792bb76_add_clob_payload_to_messages.py +45 -0
- rucio/db/sqla/migrate_repo/versions/914b8f02df38_new_table_for_lifetime_model_exceptions.py +68 -0
- rucio/db/sqla/migrate_repo/versions/94a5961ddbf2_add_estimator_columns.py +45 -0
- rucio/db/sqla/migrate_repo/versions/9a1b149a2044_add_saml_identity_type.py +94 -0
- rucio/db/sqla/migrate_repo/versions/9a45bc4ea66d_add_vp_table.py +54 -0
- rucio/db/sqla/migrate_repo/versions/9eb936a81eb1_true_is_true.py +72 -0
- rucio/db/sqla/migrate_repo/versions/a08fa8de1545_transfer_stats_table.py +55 -0
- rucio/db/sqla/migrate_repo/versions/a118956323f8_added_vo_table_and_vo_col_to_rse.py +76 -0
- rucio/db/sqla/migrate_repo/versions/a193a275255c_add_status_column_in_messages.py +47 -0
- rucio/db/sqla/migrate_repo/versions/a5f6f6e928a7_1_7_0.py +121 -0
- rucio/db/sqla/migrate_repo/versions/a616581ee47_added_columns_to_table_requests.py +59 -0
- rucio/db/sqla/migrate_repo/versions/a6eb23955c28_state_idx_non_functional.py +52 -0
- rucio/db/sqla/migrate_repo/versions/a74275a1ad30_added_global_quota_table.py +54 -0
- rucio/db/sqla/migrate_repo/versions/a93e4e47bda_heartbeats.py +64 -0
- rucio/db/sqla/migrate_repo/versions/ae2a56fcc89_added_comment_column_to_rules.py +49 -0
- rucio/db/sqla/migrate_repo/versions/b0070f3695c8_add_deletedidmeta_table.py +57 -0
- rucio/db/sqla/migrate_repo/versions/b4293a99f344_added_column_identity_to_table_tokens.py +43 -0
- rucio/db/sqla/migrate_repo/versions/b5493606bbf5_fix_primary_key_for_subscription_history.py +41 -0
- rucio/db/sqla/migrate_repo/versions/b7d287de34fd_removal_of_replicastate_source.py +91 -0
- rucio/db/sqla/migrate_repo/versions/b818052fa670_add_index_to_quarantined_replicas.py +40 -0
- rucio/db/sqla/migrate_repo/versions/b8caac94d7f0_add_comments_column_for_subscriptions_.py +43 -0
- rucio/db/sqla/migrate_repo/versions/b96a1c7e1cc4_new_bad_pfns_table_and_bad_replicas_.py +143 -0
- rucio/db/sqla/migrate_repo/versions/bb695f45c04_extend_request_state.py +76 -0
- rucio/db/sqla/migrate_repo/versions/bc68e9946deb_add_staging_timestamps_to_request.py +50 -0
- rucio/db/sqla/migrate_repo/versions/bf3baa1c1474_correct_pk_and_idx_for_history_tables.py +72 -0
- rucio/db/sqla/migrate_repo/versions/c0937668555f_add_qos_policy_map_table.py +55 -0
- rucio/db/sqla/migrate_repo/versions/c129ccdb2d5_add_lumiblocknr_to_dids.py +43 -0
- rucio/db/sqla/migrate_repo/versions/ccdbcd48206e_add_did_type_column_index_on_did_meta_.py +65 -0
- rucio/db/sqla/migrate_repo/versions/cebad904c4dd_new_payload_column_for_heartbeats.py +47 -0
- rucio/db/sqla/migrate_repo/versions/d1189a09c6e0_oauth2_0_and_jwt_feature_support_adding_.py +146 -0
- rucio/db/sqla/migrate_repo/versions/d23453595260_extend_request_state_for_preparer.py +104 -0
- rucio/db/sqla/migrate_repo/versions/d6dceb1de2d_added_purge_column_to_rules.py +44 -0
- rucio/db/sqla/migrate_repo/versions/d6e2c3b2cf26_remove_third_party_copy_column_from_rse.py +43 -0
- rucio/db/sqla/migrate_repo/versions/d91002c5841_new_account_limits_table.py +103 -0
- rucio/db/sqla/migrate_repo/versions/e138c364ebd0_extending_columns_for_filter_and_.py +49 -0
- rucio/db/sqla/migrate_repo/versions/e59300c8b179_support_for_archive.py +104 -0
- rucio/db/sqla/migrate_repo/versions/f1b14a8c2ac1_postgres_use_check_constraints.py +29 -0
- rucio/db/sqla/migrate_repo/versions/f41ffe206f37_oracle_global_temporary_tables.py +74 -0
- rucio/db/sqla/migrate_repo/versions/f85a2962b021_adding_transfertool_column_to_requests_.py +47 -0
- rucio/db/sqla/migrate_repo/versions/fa7a7d78b602_increase_refresh_token_size.py +43 -0
- rucio/db/sqla/migrate_repo/versions/fb28a95fe288_add_replicas_rse_id_tombstone_idx.py +37 -0
- rucio/db/sqla/migrate_repo/versions/fe1a65b176c9_set_third_party_copy_read_and_write_.py +43 -0
- rucio/db/sqla/migrate_repo/versions/fe8ea2fa9788_added_third_party_copy_column_to_rse_.py +43 -0
- rucio/db/sqla/models.py +1743 -0
- rucio/db/sqla/sautils.py +55 -0
- rucio/db/sqla/session.py +529 -0
- rucio/db/sqla/types.py +206 -0
- rucio/db/sqla/util.py +543 -0
- rucio/gateway/__init__.py +13 -0
- rucio/gateway/account.py +345 -0
- rucio/gateway/account_limit.py +363 -0
- rucio/gateway/authentication.py +381 -0
- rucio/gateway/config.py +227 -0
- rucio/gateway/credential.py +70 -0
- rucio/gateway/did.py +987 -0
- rucio/gateway/dirac.py +83 -0
- rucio/gateway/exporter.py +60 -0
- rucio/gateway/heartbeat.py +76 -0
- rucio/gateway/identity.py +189 -0
- rucio/gateway/importer.py +46 -0
- rucio/gateway/lifetime_exception.py +121 -0
- rucio/gateway/lock.py +153 -0
- rucio/gateway/meta_conventions.py +98 -0
- rucio/gateway/permission.py +74 -0
- rucio/gateway/quarantined_replica.py +79 -0
- rucio/gateway/replica.py +538 -0
- rucio/gateway/request.py +330 -0
- rucio/gateway/rse.py +632 -0
- rucio/gateway/rule.py +437 -0
- rucio/gateway/scope.py +100 -0
- rucio/gateway/subscription.py +280 -0
- rucio/gateway/vo.py +126 -0
- rucio/rse/__init__.py +96 -0
- rucio/rse/protocols/__init__.py +13 -0
- rucio/rse/protocols/bittorrent.py +194 -0
- rucio/rse/protocols/cache.py +111 -0
- rucio/rse/protocols/dummy.py +100 -0
- rucio/rse/protocols/gfal.py +708 -0
- rucio/rse/protocols/globus.py +243 -0
- rucio/rse/protocols/http_cache.py +82 -0
- rucio/rse/protocols/mock.py +123 -0
- rucio/rse/protocols/ngarc.py +209 -0
- rucio/rse/protocols/posix.py +250 -0
- rucio/rse/protocols/protocol.py +361 -0
- rucio/rse/protocols/rclone.py +365 -0
- rucio/rse/protocols/rfio.py +145 -0
- rucio/rse/protocols/srm.py +338 -0
- rucio/rse/protocols/ssh.py +414 -0
- rucio/rse/protocols/storm.py +195 -0
- rucio/rse/protocols/webdav.py +594 -0
- rucio/rse/protocols/xrootd.py +302 -0
- rucio/rse/rsemanager.py +881 -0
- rucio/rse/translation.py +260 -0
- rucio/tests/__init__.py +13 -0
- rucio/tests/common.py +280 -0
- rucio/tests/common_server.py +149 -0
- rucio/transfertool/__init__.py +13 -0
- rucio/transfertool/bittorrent.py +200 -0
- rucio/transfertool/bittorrent_driver.py +50 -0
- rucio/transfertool/bittorrent_driver_qbittorrent.py +134 -0
- rucio/transfertool/fts3.py +1600 -0
- rucio/transfertool/fts3_plugins.py +152 -0
- rucio/transfertool/globus.py +201 -0
- rucio/transfertool/globus_library.py +181 -0
- rucio/transfertool/mock.py +89 -0
- rucio/transfertool/transfertool.py +221 -0
- rucio/vcsversion.py +11 -0
- rucio/version.py +45 -0
- rucio/web/__init__.py +13 -0
- rucio/web/rest/__init__.py +13 -0
- rucio/web/rest/flaskapi/__init__.py +13 -0
- rucio/web/rest/flaskapi/authenticated_bp.py +27 -0
- rucio/web/rest/flaskapi/v1/__init__.py +13 -0
- rucio/web/rest/flaskapi/v1/accountlimits.py +236 -0
- rucio/web/rest/flaskapi/v1/accounts.py +1103 -0
- rucio/web/rest/flaskapi/v1/archives.py +102 -0
- rucio/web/rest/flaskapi/v1/auth.py +1644 -0
- rucio/web/rest/flaskapi/v1/common.py +426 -0
- rucio/web/rest/flaskapi/v1/config.py +304 -0
- rucio/web/rest/flaskapi/v1/credentials.py +213 -0
- rucio/web/rest/flaskapi/v1/dids.py +2340 -0
- rucio/web/rest/flaskapi/v1/dirac.py +116 -0
- rucio/web/rest/flaskapi/v1/export.py +75 -0
- rucio/web/rest/flaskapi/v1/heartbeats.py +127 -0
- rucio/web/rest/flaskapi/v1/identities.py +285 -0
- rucio/web/rest/flaskapi/v1/import.py +132 -0
- rucio/web/rest/flaskapi/v1/lifetime_exceptions.py +312 -0
- rucio/web/rest/flaskapi/v1/locks.py +358 -0
- rucio/web/rest/flaskapi/v1/main.py +91 -0
- rucio/web/rest/flaskapi/v1/meta_conventions.py +241 -0
- rucio/web/rest/flaskapi/v1/metrics.py +36 -0
- rucio/web/rest/flaskapi/v1/nongrid_traces.py +97 -0
- rucio/web/rest/flaskapi/v1/ping.py +88 -0
- rucio/web/rest/flaskapi/v1/redirect.py +366 -0
- rucio/web/rest/flaskapi/v1/replicas.py +1894 -0
- rucio/web/rest/flaskapi/v1/requests.py +998 -0
- rucio/web/rest/flaskapi/v1/rses.py +2250 -0
- rucio/web/rest/flaskapi/v1/rules.py +854 -0
- rucio/web/rest/flaskapi/v1/scopes.py +159 -0
- rucio/web/rest/flaskapi/v1/subscriptions.py +650 -0
- rucio/web/rest/flaskapi/v1/templates/auth_crash.html +80 -0
- rucio/web/rest/flaskapi/v1/templates/auth_granted.html +82 -0
- rucio/web/rest/flaskapi/v1/traces.py +137 -0
- rucio/web/rest/flaskapi/v1/types.py +20 -0
- rucio/web/rest/flaskapi/v1/vos.py +278 -0
- rucio/web/rest/main.py +18 -0
- rucio/web/rest/metrics.py +27 -0
- rucio/web/rest/ping.py +27 -0
- rucio-37.0.0rc1.data/data/rucio/etc/alembic.ini.template +71 -0
- rucio-37.0.0rc1.data/data/rucio/etc/alembic_offline.ini.template +74 -0
- rucio-37.0.0rc1.data/data/rucio/etc/globus-config.yml.template +5 -0
- rucio-37.0.0rc1.data/data/rucio/etc/ldap.cfg.template +30 -0
- rucio-37.0.0rc1.data/data/rucio/etc/mail_templates/rule_approval_request.tmpl +38 -0
- rucio-37.0.0rc1.data/data/rucio/etc/mail_templates/rule_approved_admin.tmpl +4 -0
- rucio-37.0.0rc1.data/data/rucio/etc/mail_templates/rule_approved_user.tmpl +17 -0
- rucio-37.0.0rc1.data/data/rucio/etc/mail_templates/rule_denied_admin.tmpl +6 -0
- rucio-37.0.0rc1.data/data/rucio/etc/mail_templates/rule_denied_user.tmpl +17 -0
- rucio-37.0.0rc1.data/data/rucio/etc/mail_templates/rule_ok_notification.tmpl +19 -0
- rucio-37.0.0rc1.data/data/rucio/etc/rse-accounts.cfg.template +25 -0
- rucio-37.0.0rc1.data/data/rucio/etc/rucio.cfg.atlas.client.template +43 -0
- rucio-37.0.0rc1.data/data/rucio/etc/rucio.cfg.template +241 -0
- rucio-37.0.0rc1.data/data/rucio/etc/rucio_multi_vo.cfg.template +217 -0
- rucio-37.0.0rc1.data/data/rucio/requirements.server.txt +297 -0
- rucio-37.0.0rc1.data/data/rucio/tools/bootstrap.py +34 -0
- rucio-37.0.0rc1.data/data/rucio/tools/merge_rucio_configs.py +144 -0
- rucio-37.0.0rc1.data/data/rucio/tools/reset_database.py +40 -0
- rucio-37.0.0rc1.data/scripts/rucio +133 -0
- rucio-37.0.0rc1.data/scripts/rucio-abacus-account +74 -0
- rucio-37.0.0rc1.data/scripts/rucio-abacus-collection-replica +46 -0
- rucio-37.0.0rc1.data/scripts/rucio-abacus-rse +78 -0
- rucio-37.0.0rc1.data/scripts/rucio-admin +97 -0
- rucio-37.0.0rc1.data/scripts/rucio-atropos +60 -0
- rucio-37.0.0rc1.data/scripts/rucio-auditor +206 -0
- rucio-37.0.0rc1.data/scripts/rucio-automatix +50 -0
- rucio-37.0.0rc1.data/scripts/rucio-bb8 +57 -0
- rucio-37.0.0rc1.data/scripts/rucio-cache-client +141 -0
- rucio-37.0.0rc1.data/scripts/rucio-cache-consumer +42 -0
- rucio-37.0.0rc1.data/scripts/rucio-conveyor-finisher +58 -0
- rucio-37.0.0rc1.data/scripts/rucio-conveyor-poller +66 -0
- rucio-37.0.0rc1.data/scripts/rucio-conveyor-preparer +37 -0
- rucio-37.0.0rc1.data/scripts/rucio-conveyor-receiver +44 -0
- rucio-37.0.0rc1.data/scripts/rucio-conveyor-stager +76 -0
- rucio-37.0.0rc1.data/scripts/rucio-conveyor-submitter +139 -0
- rucio-37.0.0rc1.data/scripts/rucio-conveyor-throttler +104 -0
- rucio-37.0.0rc1.data/scripts/rucio-dark-reaper +53 -0
- rucio-37.0.0rc1.data/scripts/rucio-dumper +160 -0
- rucio-37.0.0rc1.data/scripts/rucio-follower +44 -0
- rucio-37.0.0rc1.data/scripts/rucio-hermes +54 -0
- rucio-37.0.0rc1.data/scripts/rucio-judge-cleaner +89 -0
- rucio-37.0.0rc1.data/scripts/rucio-judge-evaluator +137 -0
- rucio-37.0.0rc1.data/scripts/rucio-judge-injector +44 -0
- rucio-37.0.0rc1.data/scripts/rucio-judge-repairer +44 -0
- rucio-37.0.0rc1.data/scripts/rucio-kronos +44 -0
- rucio-37.0.0rc1.data/scripts/rucio-minos +53 -0
- rucio-37.0.0rc1.data/scripts/rucio-minos-temporary-expiration +50 -0
- rucio-37.0.0rc1.data/scripts/rucio-necromancer +120 -0
- rucio-37.0.0rc1.data/scripts/rucio-oauth-manager +63 -0
- rucio-37.0.0rc1.data/scripts/rucio-reaper +83 -0
- rucio-37.0.0rc1.data/scripts/rucio-replica-recoverer +248 -0
- rucio-37.0.0rc1.data/scripts/rucio-rse-decommissioner +66 -0
- rucio-37.0.0rc1.data/scripts/rucio-storage-consistency-actions +74 -0
- rucio-37.0.0rc1.data/scripts/rucio-transmogrifier +77 -0
- rucio-37.0.0rc1.data/scripts/rucio-undertaker +76 -0
- rucio-37.0.0rc1.dist-info/METADATA +92 -0
- rucio-37.0.0rc1.dist-info/RECORD +487 -0
- rucio-37.0.0rc1.dist-info/WHEEL +5 -0
- rucio-37.0.0rc1.dist-info/licenses/AUTHORS.rst +100 -0
- rucio-37.0.0rc1.dist-info/licenses/LICENSE +201 -0
- rucio-37.0.0rc1.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,377 @@
|
|
|
1
|
+
# Copyright European Organization for Nuclear Research (CERN) since 2012
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
from configparser import NoSectionError
|
|
16
|
+
from datetime import datetime, timedelta
|
|
17
|
+
from re import match
|
|
18
|
+
from typing import TYPE_CHECKING, Any, Optional, Union
|
|
19
|
+
|
|
20
|
+
from sqlalchemy import or_, select, update
|
|
21
|
+
from sqlalchemy.exc import IntegrityError, NoResultFound
|
|
22
|
+
|
|
23
|
+
import rucio.common.policy
|
|
24
|
+
from rucio.common.config import config_get, config_get_int, config_get_list
|
|
25
|
+
from rucio.common.constants import RseAttr
|
|
26
|
+
from rucio.common.exception import ConfigNotFound, LifetimeExceptionDuplicate, LifetimeExceptionNotFound, RucioException, UnsupportedOperation
|
|
27
|
+
from rucio.common.utils import generate_uuid, str_to_date
|
|
28
|
+
from rucio.core.message import add_message
|
|
29
|
+
from rucio.core.rse import list_rse_attributes
|
|
30
|
+
from rucio.db.sqla import models
|
|
31
|
+
from rucio.db.sqla.constants import DIDType, LifetimeExceptionsState
|
|
32
|
+
from rucio.db.sqla.session import read_session, stream_session, transactional_session
|
|
33
|
+
|
|
34
|
+
if TYPE_CHECKING:
|
|
35
|
+
from collections.abc import Iterable, Iterator, Sequence
|
|
36
|
+
|
|
37
|
+
from sqlalchemy.orm import Session
|
|
38
|
+
|
|
39
|
+
from rucio.common.types import InternalAccount, InternalScope
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
@stream_session
|
|
43
|
+
def list_exceptions(
|
|
44
|
+
exception_id: Optional[str],
|
|
45
|
+
states: Optional['Iterable[LifetimeExceptionsState]'],
|
|
46
|
+
*,
|
|
47
|
+
session: 'Session',
|
|
48
|
+
) -> 'Iterator[dict[str, Any]]':
|
|
49
|
+
"""
|
|
50
|
+
List exceptions to Lifetime Model.
|
|
51
|
+
|
|
52
|
+
:param exception_id: The id of the exception
|
|
53
|
+
:param states: The states to filter
|
|
54
|
+
:param session: The database session in use.
|
|
55
|
+
"""
|
|
56
|
+
|
|
57
|
+
state_clause = []
|
|
58
|
+
if states:
|
|
59
|
+
state_clause = [models.LifetimeException.state == state for state in states]
|
|
60
|
+
|
|
61
|
+
query = select(models.LifetimeException)
|
|
62
|
+
if state_clause != []:
|
|
63
|
+
query = query.where(or_(*state_clause))
|
|
64
|
+
if exception_id:
|
|
65
|
+
query = query.filter_by(id=exception_id)
|
|
66
|
+
|
|
67
|
+
for exception in session.execute(query).yield_per(5).scalars():
|
|
68
|
+
yield {'id': exception.id, 'scope': exception.scope, 'name': exception.name,
|
|
69
|
+
'did_type': exception.did_type, 'account': exception.account,
|
|
70
|
+
'pattern': exception.pattern, 'comments': exception.comments,
|
|
71
|
+
'state': exception.state, 'created_at': exception.created_at,
|
|
72
|
+
'expires_at': exception.expires_at}
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
@transactional_session
|
|
76
|
+
def add_exception(
|
|
77
|
+
dids: "Iterable[dict[str, Any]]",
|
|
78
|
+
account: 'InternalAccount',
|
|
79
|
+
pattern: Optional[str],
|
|
80
|
+
comments: str,
|
|
81
|
+
expires_at: Optional[Union[str, datetime]],
|
|
82
|
+
*,
|
|
83
|
+
session: 'Session'
|
|
84
|
+
) -> dict[str, Any]:
|
|
85
|
+
"""
|
|
86
|
+
Add exceptions to Lifetime Model.
|
|
87
|
+
|
|
88
|
+
:param dids: The list of dids
|
|
89
|
+
:param account: The account of the requester.
|
|
90
|
+
:param pattern: The account.
|
|
91
|
+
:param comments: The comments associated to the exception.
|
|
92
|
+
:param expires_at: The expiration date of the exception.
|
|
93
|
+
:param session: The database session in use.
|
|
94
|
+
|
|
95
|
+
returns: A dictionary with id of the exceptions split by scope, datatype.
|
|
96
|
+
"""
|
|
97
|
+
from rucio.core.did import get_metadata_bulk
|
|
98
|
+
result = dict()
|
|
99
|
+
result['exceptions'] = dict()
|
|
100
|
+
try:
|
|
101
|
+
max_extension = config_get_int('lifetime_model', 'max_extension', session=session)
|
|
102
|
+
if max_extension:
|
|
103
|
+
if not expires_at:
|
|
104
|
+
expires_at = datetime.utcnow() + timedelta(days=max_extension)
|
|
105
|
+
else:
|
|
106
|
+
if isinstance(expires_at, str):
|
|
107
|
+
expires_at = str_to_date(expires_at)
|
|
108
|
+
if expires_at and (expires_at > datetime.utcnow() + timedelta(days=max_extension)):
|
|
109
|
+
expires_at = datetime.utcnow() + timedelta(days=max_extension)
|
|
110
|
+
except (ConfigNotFound, ValueError, NoSectionError):
|
|
111
|
+
max_extension = None
|
|
112
|
+
|
|
113
|
+
try:
|
|
114
|
+
cutoff_date = config_get('lifetime_model', 'cutoff_date', session=session)
|
|
115
|
+
except (ConfigNotFound, NoSectionError):
|
|
116
|
+
raise UnsupportedOperation('Cannot submit exception at that date.')
|
|
117
|
+
try:
|
|
118
|
+
cutoff_date = datetime.strptime(cutoff_date, '%Y-%m-%d')
|
|
119
|
+
except ValueError:
|
|
120
|
+
raise UnsupportedOperation('Cannot submit exception at that date.')
|
|
121
|
+
if cutoff_date < datetime.utcnow():
|
|
122
|
+
raise UnsupportedOperation('Cannot submit exception at that date.')
|
|
123
|
+
|
|
124
|
+
did_group = dict()
|
|
125
|
+
not_affected = list()
|
|
126
|
+
list_dids = [(did['scope'], did['name']) for did in dids]
|
|
127
|
+
metadata = [meta for meta in get_metadata_bulk(dids=dids, session=session)]
|
|
128
|
+
for did in metadata:
|
|
129
|
+
scope, name, did_type = did['scope'], did['name'], did['did_type']
|
|
130
|
+
if (scope, name) in list_dids:
|
|
131
|
+
list_dids.remove((scope, name))
|
|
132
|
+
datatype = did.get('datatype', '')
|
|
133
|
+
eol_at = did.get('eol_at', None)
|
|
134
|
+
if eol_at and eol_at < cutoff_date:
|
|
135
|
+
if (scope, datatype) not in did_group:
|
|
136
|
+
did_group[(scope, datatype)] = [list(), 0]
|
|
137
|
+
did_group[(scope, datatype)][0].append({'scope': scope, 'name': name, 'did_type': did_type})
|
|
138
|
+
did_group[(scope, datatype)][1] += did['bytes'] or 0
|
|
139
|
+
else:
|
|
140
|
+
not_affected.append((scope, name, did_type))
|
|
141
|
+
for entry in did_group:
|
|
142
|
+
exception_id = __add_exception(did_group[entry][0], account=account, pattern=pattern, comments=comments, expires_at=expires_at, estimated_volume=did_group[entry][1], session=session)
|
|
143
|
+
result['exceptions'][exception_id] = did_group[entry][0]
|
|
144
|
+
result['unknown'] = [{'scope': did[0], 'name': did[1], 'did_type': DIDType.DATASET} for did in list_dids]
|
|
145
|
+
result['not_affected'] = [{'scope': did[0], 'name': did[1], 'did_type': did[2]} for did in not_affected]
|
|
146
|
+
return result
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
@transactional_session
|
|
150
|
+
def __add_exception(
|
|
151
|
+
dids: 'Sequence[dict[str, Any]]',
|
|
152
|
+
account: 'InternalAccount',
|
|
153
|
+
pattern: Optional[str],
|
|
154
|
+
comments: str,
|
|
155
|
+
expires_at: Optional[Union[str, datetime]],
|
|
156
|
+
estimated_volume: Optional[int] = None,
|
|
157
|
+
*,
|
|
158
|
+
session: 'Session',
|
|
159
|
+
) -> str:
|
|
160
|
+
"""
|
|
161
|
+
Add exceptions to Lifetime Model.
|
|
162
|
+
|
|
163
|
+
:param dids: The list of dids
|
|
164
|
+
:param account: The account of the requester.
|
|
165
|
+
:param pattern: The pattern of the exception (not used).
|
|
166
|
+
:param comments: The comments associated to the exception.
|
|
167
|
+
:param expires_at: The expiration date of the exception.
|
|
168
|
+
:params estimated_volume: The estimated logical volume of the exception.
|
|
169
|
+
:param session: The database session in use.
|
|
170
|
+
|
|
171
|
+
returns: The id of the exception.
|
|
172
|
+
"""
|
|
173
|
+
exception_id = generate_uuid()
|
|
174
|
+
text = 'Account %s requested a lifetime extension for a list of DIDs that can be found below\n' % account
|
|
175
|
+
reason = comments
|
|
176
|
+
volume = None
|
|
177
|
+
lifetime = None
|
|
178
|
+
if comments.find('||||') > -1:
|
|
179
|
+
reason, volume = comments.split('||||')
|
|
180
|
+
text += 'The reason for the extension is "%s"\n' % reason
|
|
181
|
+
text += 'It represents %s datasets\n' % len(dids)
|
|
182
|
+
if estimated_volume:
|
|
183
|
+
text += 'The estimated logical volume is %s\n' % estimated_volume
|
|
184
|
+
if volume:
|
|
185
|
+
text += 'The estimated physical volume is %s\n' % volume
|
|
186
|
+
if expires_at and isinstance(expires_at, str):
|
|
187
|
+
lifetime = str_to_date(expires_at)
|
|
188
|
+
text += 'The lifetime exception should expires on %s\n' % str(expires_at)
|
|
189
|
+
elif isinstance(expires_at, datetime):
|
|
190
|
+
lifetime = expires_at
|
|
191
|
+
text += 'The lifetime exception should expires on %s\n' % str(expires_at)
|
|
192
|
+
text += 'Link to approve or reject this request can be found at the end of the mail\n'
|
|
193
|
+
text += '\n'
|
|
194
|
+
text += 'DIDTYPE SCOPE NAME\n'
|
|
195
|
+
text += '\n'
|
|
196
|
+
truncated_message = False
|
|
197
|
+
for did in dids:
|
|
198
|
+
did_type = None
|
|
199
|
+
if 'did_type' in did:
|
|
200
|
+
if isinstance(did['did_type'], str):
|
|
201
|
+
did_type = DIDType[did['did_type']]
|
|
202
|
+
else:
|
|
203
|
+
did_type = did['did_type']
|
|
204
|
+
new_exception = models.LifetimeException(id=exception_id, scope=did['scope'], name=did['name'], did_type=did_type,
|
|
205
|
+
account=account, pattern=pattern, comments=reason, state=LifetimeExceptionsState.WAITING, expires_at=lifetime)
|
|
206
|
+
if len(text) < 3000:
|
|
207
|
+
text += '%s %s %s\n' % (str(did_type), did['scope'], did['name'])
|
|
208
|
+
else:
|
|
209
|
+
truncated_message = True
|
|
210
|
+
try:
|
|
211
|
+
new_exception.save(session=session, flush=False)
|
|
212
|
+
except IntegrityError as error:
|
|
213
|
+
if match('.*ORA-00001.*', str(error.args[0])) \
|
|
214
|
+
or match('.*IntegrityError.*UNIQUE constraint failed.*', str(error.args[0])) \
|
|
215
|
+
or match('.*1062.*Duplicate entry.*for key.*', str(error.args[0])) \
|
|
216
|
+
or match('.*IntegrityError.*columns? .*not unique.*', error.args[0]):
|
|
217
|
+
raise LifetimeExceptionDuplicate()
|
|
218
|
+
raise RucioException(error.args[0])
|
|
219
|
+
if truncated_message:
|
|
220
|
+
text += '...\n'
|
|
221
|
+
text += 'List too long. Truncated\n'
|
|
222
|
+
text += '\n'
|
|
223
|
+
text += 'Approve: https://rucio-ui.cern.ch/lifetime_exception?id=%s&action=approve\n' % str(exception_id)
|
|
224
|
+
text += 'Deny: https://rucio-ui.cern.ch/lifetime_exception?id=%s&action=deny\n' % str(exception_id)
|
|
225
|
+
approvers_email = config_get_list('lifetime_model', 'approvers_email', default=[], session=session)
|
|
226
|
+
|
|
227
|
+
add_message(event_type='email',
|
|
228
|
+
payload={'body': text, 'to': approvers_email,
|
|
229
|
+
'subject': '[RUCIO] Request to approve lifetime exception %s' % str(exception_id)},
|
|
230
|
+
session=session)
|
|
231
|
+
return exception_id
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
@transactional_session
|
|
235
|
+
def update_exception(
|
|
236
|
+
exception_id: str,
|
|
237
|
+
state: LifetimeExceptionsState,
|
|
238
|
+
*,
|
|
239
|
+
session: 'Session',
|
|
240
|
+
) -> None:
|
|
241
|
+
"""
|
|
242
|
+
Update exceptions state to Lifetime Model.
|
|
243
|
+
|
|
244
|
+
:param exception_id: The id of the exception
|
|
245
|
+
:param state: The states to filter
|
|
246
|
+
:param session: The database session in use.
|
|
247
|
+
"""
|
|
248
|
+
allowed_states = (LifetimeExceptionsState.APPROVED, LifetimeExceptionsState.REJECTED)
|
|
249
|
+
if state not in allowed_states:
|
|
250
|
+
raise UnsupportedOperation
|
|
251
|
+
|
|
252
|
+
query = update(
|
|
253
|
+
models.LifetimeException
|
|
254
|
+
).where(
|
|
255
|
+
models.LifetimeException.id == exception_id
|
|
256
|
+
).values(
|
|
257
|
+
state=state,
|
|
258
|
+
updated_at=datetime.utcnow()
|
|
259
|
+
)
|
|
260
|
+
|
|
261
|
+
if session.execute(query).rowcount == 0:
|
|
262
|
+
raise LifetimeExceptionNotFound
|
|
263
|
+
|
|
264
|
+
|
|
265
|
+
@read_session
|
|
266
|
+
def define_eol(
|
|
267
|
+
scope: 'InternalScope',
|
|
268
|
+
name: str,
|
|
269
|
+
rses: 'Iterable[dict[str, Any]]',
|
|
270
|
+
*,
|
|
271
|
+
session: 'Session',
|
|
272
|
+
) -> Optional[datetime]:
|
|
273
|
+
"""
|
|
274
|
+
ATLAS policy for rules on SCRATCHDISK
|
|
275
|
+
|
|
276
|
+
:param scope: Scope of the DID.
|
|
277
|
+
:param name: Name of the DID.
|
|
278
|
+
:param rses: List of RSEs.
|
|
279
|
+
:param session: The database session in use.
|
|
280
|
+
"""
|
|
281
|
+
policy = rucio.common.policy.get_policy()
|
|
282
|
+
if policy != 'atlas':
|
|
283
|
+
return None
|
|
284
|
+
|
|
285
|
+
# Check if on ATLAS managed space
|
|
286
|
+
if [rse for rse in rses if list_rse_attributes(rse_id=rse['id'], session=session).get(RseAttr.TYPE) in ['LOCALGROUPDISK', 'LOCALGROUPTAPE', 'GROUPDISK', 'GROUPTAPE']]:
|
|
287
|
+
return None
|
|
288
|
+
# Now check the lifetime policy
|
|
289
|
+
try:
|
|
290
|
+
query = select(
|
|
291
|
+
models.DataIdentifier
|
|
292
|
+
).where(
|
|
293
|
+
models.DataIdentifier.scope == scope,
|
|
294
|
+
models.DataIdentifier.name == name
|
|
295
|
+
)
|
|
296
|
+
|
|
297
|
+
did = session.execute(query).scalar_one()
|
|
298
|
+
except NoResultFound:
|
|
299
|
+
return None
|
|
300
|
+
policy_dict = rucio.common.policy.get_lifetime_policy()
|
|
301
|
+
did_type = 'other'
|
|
302
|
+
if scope.external.startswith('mc'): # type: ignore
|
|
303
|
+
did_type = 'mc'
|
|
304
|
+
elif scope.external.startswith('data'): # type: ignore
|
|
305
|
+
did_type = 'data'
|
|
306
|
+
elif scope.external.startswith('valid'): # type: ignore
|
|
307
|
+
did_type = 'valid'
|
|
308
|
+
else:
|
|
309
|
+
did_type = 'other'
|
|
310
|
+
for policy in policy_dict[did_type]:
|
|
311
|
+
if 'exclude' in policy:
|
|
312
|
+
to_exclude = False
|
|
313
|
+
for key in policy['exclude']:
|
|
314
|
+
meta_key = None
|
|
315
|
+
if key not in ['datatype', 'project', ]:
|
|
316
|
+
if key == 'stream':
|
|
317
|
+
meta_key = 'stream_name'
|
|
318
|
+
elif key == 'tags':
|
|
319
|
+
meta_key = 'version'
|
|
320
|
+
else:
|
|
321
|
+
meta_key = key
|
|
322
|
+
values = policy['exclude'][key]
|
|
323
|
+
for value in values:
|
|
324
|
+
value = value.replace('%', '.*')
|
|
325
|
+
if meta_key and did[meta_key] and value and match(value, did[meta_key]):
|
|
326
|
+
to_exclude = True
|
|
327
|
+
break
|
|
328
|
+
if to_exclude:
|
|
329
|
+
break
|
|
330
|
+
if to_exclude:
|
|
331
|
+
continue
|
|
332
|
+
if 'include' in policy:
|
|
333
|
+
match_policy = True
|
|
334
|
+
for key in policy['include']:
|
|
335
|
+
meta_key = None
|
|
336
|
+
if key not in ['datatype', 'project', ]:
|
|
337
|
+
if key == 'stream':
|
|
338
|
+
meta_key = 'stream_name'
|
|
339
|
+
elif key == 'tags':
|
|
340
|
+
meta_key = 'version'
|
|
341
|
+
else:
|
|
342
|
+
continue
|
|
343
|
+
else:
|
|
344
|
+
meta_key = key
|
|
345
|
+
values = policy['include'][key]
|
|
346
|
+
to_keep = False
|
|
347
|
+
for value in values:
|
|
348
|
+
value = value.replace('%', '.*')
|
|
349
|
+
if meta_key and did[meta_key] and value and match(value, did[meta_key]):
|
|
350
|
+
to_keep = True
|
|
351
|
+
break
|
|
352
|
+
match_policy = match_policy and to_keep
|
|
353
|
+
if not to_keep:
|
|
354
|
+
match_policy = False
|
|
355
|
+
break
|
|
356
|
+
if match_policy:
|
|
357
|
+
if int(policy['age']) >= 12:
|
|
358
|
+
years = int(int(policy['age']) / 12)
|
|
359
|
+
months = int(policy['age']) - years * 12
|
|
360
|
+
lifetime_value = 365 * years + 30 * months
|
|
361
|
+
else:
|
|
362
|
+
lifetime_value = int(policy['age']) * 30
|
|
363
|
+
if int(policy['extension']) >= 12:
|
|
364
|
+
years = int(int(policy['extension']) / 12)
|
|
365
|
+
months = int(policy['extension']) - years * 12
|
|
366
|
+
extension = 365 * years + 30 * months
|
|
367
|
+
else:
|
|
368
|
+
extension = int(policy['extension']) * 30
|
|
369
|
+
|
|
370
|
+
default_eol_at = did.created_at + timedelta(days=lifetime_value)
|
|
371
|
+
eol_at = default_eol_at
|
|
372
|
+
if did.accessed_at:
|
|
373
|
+
eol_at = did.accessed_at + timedelta(days=extension)
|
|
374
|
+
if eol_at < default_eol_at:
|
|
375
|
+
eol_at = default_eol_at
|
|
376
|
+
return eol_at
|
|
377
|
+
return None
|