diff --git a/docs/architecture/migration-progress.md b/docs/architecture/migration-progress.md index 50ed004c4..fd0c759a5 100644 --- a/docs/architecture/migration-progress.md +++ b/docs/architecture/migration-progress.md @@ -5,24 +5,25 @@ Status values: `[ ]` not started, `[~]` in progress, `[x]` complete, `[!]` block ## Current Context - Issue: [`rustfs/backlog#660`](https://github.com/rustfs/backlog/issues/660) -- Branch: `overtrue/arch-global-fallback-removal-batch` +- Branch: `overtrue/arch-global-admin-context-consumer-batch` - Baseline: completed `C-011/C-012/C-013/API-055/API-059/API-079/API-080/API-081/API-082/API-083/API-084/API-085/API-086/API-087/API-088/API-089/API-090/API-091/API-092/API-093/API-094/API-095/API-096/API-097/API-098/API-099/API-100/API-101/API-102/API-103/API-104/API-105/API-106/API-107/API-108/API-109/API-110/API-111/API-112/API-113/API-114/API-115/API-116/API-117/API-118/API-119/API-120/API-121/API-122/API-123/API-124/API-125/API-126/API-127/API-128/API-129/API-130/API-131/API-132/API-133/API-134/API-135/API-136/API-137/API-138/API-139/API-140/API-141/API-142/API-143/API-144/API-145/API-146/API-147/API-148/API-149/API-150/API-151/API-152/API-153/API-154/API-155/API-156/API-157/API-158/API-159/API-160/API-161/API-162/API-163/API-164/API-165/API-166/API-167/API-168/API-169/API-170/API-171/API-172/API-173/API-174/API-175/API-176/API-177/API-178/API-179/API-180/API-181/API-182/API-183/API-184/API-185/API-186/API-187/API-188/API-189/API-190/API-191/API-192/API-193/API-194/API-195/API-196/API-197/API-198/API-199/API-200/API-201/API-202/API-203/API-204/API-205/API-206/API-207/API-208/API-209/API-210/API-211/API-212/API-213/API-214/API-215/API-216/API-217/API-218/API-219/API-220/API-221/API-222/API-223/API-224/API-225/API-226/API-227/API-228/API-229/API-230/API-231/API-232/API-233/API-234/API-235/API-236/API-237/API-238/API-239/API-240/API-241/API-242/API-243/API-244/API-245/API-246/API-247/API-248/API-249/API-250/API-251/API-252/API-253/API-254/CTX-002`. - Current baseline also includes API-255 from PR #3923, API-256 from PR #3925, CFG-009 from PR #3927, C-007/C-009 from PR #3935, C-008/C-010 from PR #3936, and DOC-001/DOC-002/DOC-003/DOC-004/DOC-005/ TEST-DOC-001 from PR #3938, GLOB-001/GLOB-002/GLOB-003/GLOB-004/ - GLOB-005/CRATE-001/CRATE-002 from PR #3939, and GLOB-006 from PR #3941. -- Current phase PR: GLOB-007 admin runtime context handoff batch. -- Based on: `origin/main` after PR #3941 merged. + GLOB-005/CRATE-001/CRATE-002 from PR #3939, GLOB-006 from PR #3941, + and the first GLOB-007 admin runtime context handoff from PR #3942. +- Current phase PR: GLOB-007 admin context consumer batch. +- Based on: `origin/main` after PR #3942 merged. - PR type for this branch: `ci-gate`. - Runtime behavior changes: none intended. -- Rust code changes: add context-aware notification-system and server-config - resolution, then route admin config, OIDC config, audit runtime config, and - dynamic KMS config storage access through current AppContext-aware resolver - boundaries before falling back to legacy globals. +- Rust code changes: add admin current-runtime resolver helpers and route the + remaining admin handler/router object-store, notification-system, and + server-config consumers through AppContext-aware boundaries before legacy + fallbacks. - CI/script changes: none intended. -- Docs changes: update the global-state plan and this progress ledger for the - admin runtime context handoff batch. +- Docs changes: update this progress ledger for the admin context consumer + batch. ## Phase 0 Tasks @@ -2776,15 +2777,20 @@ Status values: `[ ]` not started, `[~]` in progress, `[x]` complete, `[!]` block - Verification: focused compile coverage, architecture migration guard, diff hygiene, Rust risk scan, and full PR gate. - [~] `GLOB-007` Remove fallbacks. - - Current slice: move admin config, OIDC config, audit runtime config, and + - Completed slice: move admin config, OIDC config, audit runtime config, and dynamic KMS config storage access paths to current AppContext-aware resolver boundaries, and expose notification-system/server-config resolution for explicit AppContext handoff. + - Current slice: route the remaining admin handler/router direct + object-store, notification-system, and server-config consumers through + admin current-runtime helpers backed by AppContext-aware resolver + boundaries. - Remaining work: remove one fallback family per PR only after scans prove no production caller depends on it; this slice keeps the fallback behavior - because broader admin/server consumers still use the root resolvers. - - Verification: focused RustFS compile, resolver residual scan, formatting, - diff hygiene, architecture guard, Rust risk scan, and full PR gate. + because broader app/storage/server consumers still use the root resolvers. + - Verification: focused RustFS compile and admin test-target compile, + resolver residual scan, formatting, diff hygiene, architecture guard, Rust + risk scan, and full PR gate. - [~] `CRATE-001/CRATE-002` Evaluate future crate splits. - Current slice: record evidence required before `ecstore-erasure` or `storage-cluster` split proposals. @@ -6048,6 +6054,9 @@ Status values: `[ ]` not started, `[~]` in progress, `[x]` complete, `[!]` block | Expert | Status | Notes | |---|---|---| +| Quality/architecture | pass | GLOB-007 adds admin current-runtime resolver helpers and moves remaining admin handler/router object-store, notification-system, and server-config consumers off direct root resolver calls without changing owner boundaries. | +| Migration preservation | pass | The helpers call `current_app_context()` and delegate to the same AppContext-aware resolver/fallback paths from PR #3942, so account, bucket metadata, heal, zip download, pool, quota, rebalance, replication, site replication, table catalog, tier, and router behavior stays unchanged. | +| Testing/verification | pass | Focused RustFS compile/tests, admin test-target compile, admin resolver residual scan, formatting, architecture guard, diff hygiene, Rust risk scan, and full `make pre-pr` passed before PR. | | Quality/architecture | pass | GLOB-007 adds AppContext-aware notification-system and server-config resolver boundaries, then routes admin config, OIDC config, audit runtime config, and dynamic KMS config storage access through current AppContext-aware owners before legacy fallbacks. | | Migration preservation | pass | Existing admin config reload, OIDC restart detection, audit config writes, and dynamic KMS config load/save behavior stay unchanged because context lookup falls back to the same root object-store, notification, and server-config owners. | | Testing/verification | pass | Focused RustFS compile/tests, resolver residual scan, formatting, architecture guard, diff hygiene, Rust risk scan, and full `make pre-pr` passed before PR. | @@ -6408,6 +6417,20 @@ Status values: `[ ]` not started, `[~]` in progress, `[x]` complete, `[!]` block Passed before push: +- Issue #660 GLOB-007 admin context consumer slice: + - Branch freshness check: rebased onto `origin/main` after PR #3942 merged. + - `cargo fmt --all --check`: passed. + - `git diff --check`: passed. + - `./scripts/check_architecture_migration_rules.sh`: passed. + - Admin resolver residual scan: passed. + - Diff-added Rust risk scan: passed; no new production unwrap/expect, + unchecked narrow casts, stringly errors, or ad-hoc stdout/stderr. + - `cargo check -p rustfs --lib`: passed. + - `cargo test -p rustfs --lib admin --no-run`: passed. + - Three-expert review: passed. + - `make pre-pr`: passed, including 6911 nextest tests passed, 112 skipped, + and doctests. + - Issue #660 GLOB-007 current slice: - Branch freshness check: rebased onto `origin/main` after PR #3941 merged. - `cargo fmt --all --check`: passed. diff --git a/rustfs/src/admin/handlers/account_info.rs b/rustfs/src/admin/handlers/account_info.rs index 9adf1c49a..9f389d4c8 100644 --- a/rustfs/src/admin/handlers/account_info.rs +++ b/rustfs/src/admin/handlers/account_info.rs @@ -14,7 +14,7 @@ use crate::admin::auth::authenticate_request; use crate::admin::router::{AdminOperation, Operation, S3Router}; -use crate::admin::runtime_sources::{resolve_action_credentials, resolve_object_store_handle}; +use crate::admin::runtime_sources::{current_object_store_handle, resolve_action_credentials}; use crate::admin::storage_api::bucket::versioning_sys::BucketVersioningSys; use crate::admin::storage_api::contract::admin::StorageAdminApi; use crate::admin::storage_api::contract::bucket::{BucketOperations, BucketOptions}; @@ -60,7 +60,7 @@ fn resolve_bucket_access(can_list_bucket: bool, can_get_bucket_location: bool, c #[async_trait::async_trait] impl Operation for AccountInfoHandler { async fn call(&self, req: S3Request, _params: Params<'_, '_>) -> S3Result> { - let Some(store) = resolve_object_store_handle() else { + let Some(store) = current_object_store_handle() else { return Err(S3Error::with_message(S3ErrorCode::InternalError, "Not init".to_string())); }; diff --git a/rustfs/src/admin/handlers/bucket_meta.rs b/rustfs/src/admin/handlers/bucket_meta.rs index 2cd59f046..c94fdf671 100644 --- a/rustfs/src/admin/handlers/bucket_meta.rs +++ b/rustfs/src/admin/handlers/bucket_meta.rs @@ -26,7 +26,7 @@ use crate::admin::storage_api::bucket::{ use crate::admin::storage_api::contract::bucket::{BucketOperations, BucketOptions, MakeBucketOptions}; use crate::admin::storage_api::error::StorageError; use crate::{ - admin::runtime_sources::resolve_object_store_handle, + admin::runtime_sources::current_object_store_handle, admin::{ auth::validate_admin_request, router::{AdminOperation, Operation, S3Router}, @@ -131,7 +131,7 @@ impl Operation for ExportBucketMetadata { ) .await?; - let Some(store) = resolve_object_store_handle() else { + let Some(store) = current_object_store_handle() else { return Err(s3_error!(InternalError, "object store is not initialized")); }; @@ -517,7 +517,7 @@ impl Operation for ImportBucketMetadata { }; } - let Some(store) = resolve_object_store_handle() else { + let Some(store) = current_object_store_handle() else { return Err(s3_error!(InternalError, "object store is not initialized")); }; diff --git a/rustfs/src/admin/handlers/heal.rs b/rustfs/src/admin/handlers/heal.rs index 11b69e560..35111333c 100644 --- a/rustfs/src/admin/handlers/heal.rs +++ b/rustfs/src/admin/handlers/heal.rs @@ -14,7 +14,7 @@ use crate::admin::auth::{authenticate_request, validate_admin_request}; use crate::admin::router::{AdminOperation, Operation, S3Router}; -use crate::admin::runtime_sources::resolve_object_store_handle; +use crate::admin::runtime_sources::current_object_store_handle; use crate::admin::storage_api::access::spawn_traced; use crate::admin::storage_api::bucket::is_reserved_or_invalid_bucket; use crate::admin::storage_api::bucket::utils::is_valid_object_prefix; @@ -500,7 +500,7 @@ impl Operation for HealHandler { // The heal channel currently models bucket/object work. Root heal reuses the // existing format-heal path directly so `/v3/heal/` is accepted intentionally. if should_handle_root_heal_directly(&hip) { - let Some(store) = resolve_object_store_handle() else { + let Some(store) = current_object_store_handle() else { warn!( event = EVENT_ADMIN_REQUEST_FAILED, component = LOG_COMPONENT_ADMIN_API, @@ -736,7 +736,7 @@ impl Operation for BackgroundHealStatusHandler { async fn call(&self, req: S3Request, _params: Params<'_, '_>) -> S3Result> { validate_heal_admin_request(&req).await?; - let Some(store) = resolve_object_store_handle() else { + let Some(store) = current_object_store_handle() else { warn!( event = EVENT_ADMIN_REQUEST_FAILED, component = LOG_COMPONENT_ADMIN_API, diff --git a/rustfs/src/admin/handlers/object_zip_download.rs b/rustfs/src/admin/handlers/object_zip_download.rs index 5ab14dd82..d19cea22b 100644 --- a/rustfs/src/admin/handlers/object_zip_download.rs +++ b/rustfs/src/admin/handlers/object_zip_download.rs @@ -13,7 +13,7 @@ // limitations under the License. use crate::admin::router::{ADMIN_OBJECT_ZIP_DOWNLOADS_PATH, AdminOperation, Operation, S3Router}; -use crate::admin::runtime_sources::{resolve_action_credentials, resolve_object_store_handle, resolve_region}; +use crate::admin::runtime_sources::{current_object_store_handle, resolve_action_credentials, resolve_region}; use crate::admin::storage_api::access::{ReqInfo, authorize_request}; use crate::admin::storage_api::contract::bucket::{BucketOperations, BucketOptions}; use crate::admin::storage_api::contract::list::ListOperations as _; @@ -638,7 +638,7 @@ fn validate_zip_entry_name(entry_name: &str) -> S3Result<()> { } async fn preflight_zip_items(request: &CreateObjectZipDownloadRequest, items: &[ZipDownloadItem]) -> S3Result<()> { - let store = resolve_object_store_handle().ok_or_else(|| s3_error!(InternalError, "object store not initialized"))?; + let store = current_object_store_handle().ok_or_else(|| s3_error!(InternalError, "object store not initialized"))?; for item in items { store .get_object_info(&request.bucket, &item.key, &ObjectOptions::default()) @@ -653,7 +653,7 @@ fn storage_error_to_s3(err: crate::admin::storage_api::error::Error) -> s3s::S3E } async fn validate_zip_download_request(record: &ObjectZipDownloadToken) -> S3Result<()> { - let store = resolve_object_store_handle().ok_or_else(|| s3_error!(InternalError, "object store not initialized"))?; + let store = current_object_store_handle().ok_or_else(|| s3_error!(InternalError, "object store not initialized"))?; store .get_bucket_info(&record.request.bucket, &BucketOptions::default()) .await @@ -778,7 +778,7 @@ async fn prepare_zip_download_archive(record: &ObjectZipDownloadToken) -> S3Resu async fn generate_zip_archive(record: &ObjectZipDownloadToken, file: &mut File) -> io::Result<()> { let mut zip = ZipFileWriter::with_tokio(file).force_zip64(); - let store = resolve_object_store_handle().ok_or_else(|| io::Error::other("object store not initialized"))?; + let store = current_object_store_handle().ok_or_else(|| io::Error::other("object store not initialized"))?; let explicit_items = collect_explicit_zip_items(&record.request) .map_err(|err| io::Error::other(format!("failed to prepare explicit ZIP items: {err}")))?; @@ -865,7 +865,7 @@ async fn write_zip_item( where W: tokio::io::AsyncWrite + Unpin, { - let store = resolve_object_store_handle().ok_or_else(|| io::Error::other("object store not initialized"))?; + let store = current_object_store_handle().ok_or_else(|| io::Error::other("object store not initialized"))?; let mut reader = store .get_object_reader(bucket, &item.key, None, HeaderMap::new(), &ObjectOptions::default()) .await diff --git a/rustfs/src/admin/handlers/pools.rs b/rustfs/src/admin/handlers/pools.rs index ebd0bb3c4..f50b6af9d 100644 --- a/rustfs/src/admin/handlers/pools.rs +++ b/rustfs/src/admin/handlers/pools.rs @@ -26,8 +26,8 @@ use tracing::{error, info, warn}; use crate::{ admin::runtime_sources::{ - AdminPoolStatus, QueryPoolStatusRequest, default_admin_usecase, resolve_endpoints_handle, resolve_notification_system, - resolve_object_store_handle, + AdminPoolStatus, QueryPoolStatusRequest, current_notification_system, current_object_store_handle, default_admin_usecase, + resolve_endpoints_handle, }, admin::{ auth::validate_admin_request, @@ -279,7 +279,7 @@ fn decommission_peer_target( } let grid_host = endpoint.grid_host(); - let Some(notification_sys) = resolve_notification_system() else { + let Some(notification_sys) = current_notification_system() else { log_pool_request_rejected_with_index_audit( operation_to_event(operation), "notification_sys_not_initialized", @@ -741,7 +741,7 @@ impl Operation for StartDecommission { return Err(s3_error!(NotImplemented)); } - let Some(store) = resolve_object_store_handle() else { + let Some(store) = current_object_store_handle() else { return Err(decommission_admin_not_initialized_error_with_audit("start decommission", audit)); }; @@ -929,7 +929,7 @@ impl Operation for CancelDecommission { .map_err(ApiError::from) .map_err(|err| contextualize_admin_pool_api_error(err, "cancel decommission", format!("pool {idx}")))?; } else { - let Some(store) = resolve_object_store_handle() else { + let Some(store) = current_object_store_handle() else { return Err(decommission_admin_not_initialized_error_with_audit("cancel decommission", audit)); }; @@ -1042,7 +1042,7 @@ impl Operation for ClearDecommission { .map_err(ApiError::from) .map_err(|err| contextualize_admin_pool_api_error(err, "clear decommission", format!("pool {idx}")))?; } else { - let Some(store) = resolve_object_store_handle() else { + let Some(store) = current_object_store_handle() else { return Err(decommission_admin_not_initialized_error_with_audit("clear decommission", audit)); }; diff --git a/rustfs/src/admin/handlers/quota.rs b/rustfs/src/admin/handlers/quota.rs index a75a36bb3..4e08d0728 100644 --- a/rustfs/src/admin/handlers/quota.rs +++ b/rustfs/src/admin/handlers/quota.rs @@ -16,7 +16,7 @@ use crate::admin::auth::{validate_admin_request, validate_admin_request_with_bucket}; use crate::admin::router::{AdminOperation, Operation, S3Router}; -use crate::admin::runtime_sources::{resolve_bucket_metadata_handle, resolve_object_store_handle}; +use crate::admin::runtime_sources::{current_object_store_handle, resolve_bucket_metadata_handle}; use crate::admin::storage_api::bucket::metadata_sys::BucketMetadataSys; use crate::admin::storage_api::bucket::quota::checker::QuotaChecker; use crate::admin::storage_api::bucket::quota::{BucketQuota, QuotaError, QuotaOperation}; @@ -171,7 +171,7 @@ fn bucket_metadata_from_context() -> Option>> { } async fn current_usage_from_context(bucket: &str) -> u64 { - let Some(store) = resolve_object_store_handle() else { + let Some(store) = current_object_store_handle() else { return 0; }; diff --git a/rustfs/src/admin/handlers/rebalance.rs b/rustfs/src/admin/handlers/rebalance.rs index 7a4a4b406..db6904132 100644 --- a/rustfs/src/admin/handlers/rebalance.rs +++ b/rustfs/src/admin/handlers/rebalance.rs @@ -21,7 +21,7 @@ use crate::admin::storage_api::rebalance::{ }; use crate::admin::storage_api::runtime::{ECStore, NotificationSys}; use crate::{ - admin::runtime_sources::{resolve_notification_system, resolve_object_store_handle}, + admin::runtime_sources::{current_notification_system, current_object_store_handle}, admin::{ auth::validate_admin_request, router::{AdminOperation, Operation, S3Router}, @@ -446,7 +446,7 @@ impl Operation for RebalanceStart { return Err(s3_error!(InvalidArgument, "rebalance start does not accept query parameters")); } - let Some(store) = resolve_object_store_handle() else { + let Some(store) = current_object_store_handle() else { return Err(s3_error!(InternalError, "object layer is not initialized")); }; @@ -499,7 +499,7 @@ impl Operation for RebalanceStart { rebalance_id = %id, "admin rebalance state" ); - if let Some(notification_sys) = resolve_notification_system() { + if let Some(notification_sys) = current_notification_system() { info!( event = EVENT_ADMIN_REBALANCE_STATE, component = LOG_COMPONENT_ADMIN, @@ -630,7 +630,7 @@ impl Operation for RebalanceStatus { ) .await?; - let Some(store) = resolve_object_store_handle() else { + let Some(store) = current_object_store_handle() else { return Err(s3_error!(InternalError, "object layer is not initialized")); }; @@ -735,7 +735,7 @@ impl Operation for RebalanceStop { return Err(s3_error!(InvalidArgument, "rebalance stop does not accept query parameters")); } - let Some(store) = resolve_object_store_handle() else { + let Some(store) = current_object_store_handle() else { return Err(s3_error!(InternalError, "object layer is not initialized")); }; @@ -750,7 +750,7 @@ impl Operation for RebalanceStop { return Err(s3_error!(NoSuchResource, "pool rebalance is not started")); } - let notification_sys = resolve_notification_system(); + let notification_sys = current_notification_system(); let stop_attempt_at = OffsetDateTime::now_utc(); let mut stop_failures = Vec::new(); if let Some(notification_sys) = notification_sys { diff --git a/rustfs/src/admin/handlers/replication.rs b/rustfs/src/admin/handlers/replication.rs index fed0c2c74..cf6b1688e 100644 --- a/rustfs/src/admin/handlers/replication.rs +++ b/rustfs/src/admin/handlers/replication.rs @@ -15,7 +15,7 @@ use crate::admin::auth::validate_admin_request; use crate::admin::handlers::site_replication::site_replication_peer_deployment_id_for_endpoint; use crate::admin::router::{AdminOperation, Operation, S3Router}; -use crate::admin::runtime_sources::{resolve_object_store_handle, resolve_replication_stats_handle, resolve_runtime_port}; +use crate::admin::runtime_sources::{current_object_store_handle, resolve_replication_stats_handle, resolve_runtime_port}; use crate::admin::storage_api::bucket::metadata::BUCKET_TARGETS_FILE; use crate::admin::storage_api::bucket::metadata_sys; use crate::admin::storage_api::bucket::metadata_sys::get_replication_config; @@ -151,7 +151,7 @@ impl Operation for GetReplicationMetricsHandler { return Err(s3_error!(InvalidRequest, "bucket is required")); } - let Some(store) = resolve_object_store_handle() else { + let Some(store) = current_object_store_handle() else { return Err(S3Error::with_message(S3ErrorCode::InternalError, "Not init".to_string())); }; @@ -209,7 +209,7 @@ impl Operation for SetRemoteTargetHandler { return Err(s3_error!(InvalidRequest, "bucket is required")); } - let Some(store) = resolve_object_store_handle() else { + let Some(store) = current_object_store_handle() else { return Err(S3Error::with_message(S3ErrorCode::InternalError, "Not init".to_string())); }; @@ -355,7 +355,7 @@ impl Operation for ListRemoteTargetHandler { return Err(s3_error!(InvalidRequest, "bucket is required")); } - let Some(store) = resolve_object_store_handle() else { + let Some(store) = current_object_store_handle() else { return Err(S3Error::with_message(S3ErrorCode::InternalError, "Not initialized".to_string())); }; @@ -416,7 +416,7 @@ impl Operation for RemoveRemoteTargetHandler { return Err(s3_error!(InvalidRequest, "arn is required")); }; - let Some(store) = resolve_object_store_handle() else { + let Some(store) = current_object_store_handle() else { return Err(S3Error::with_message(S3ErrorCode::InternalError, "Not initialized".to_string())); }; diff --git a/rustfs/src/admin/handlers/site_replication.rs b/rustfs/src/admin/handlers/site_replication.rs index 690f8b197..c50fbfc02 100644 --- a/rustfs/src/admin/handlers/site_replication.rs +++ b/rustfs/src/admin/handlers/site_replication.rs @@ -15,9 +15,9 @@ use crate::admin::auth::validate_admin_request; use crate::admin::router::{AdminOperation, Operation, S3Router}; use crate::admin::runtime_sources::{ - resolve_deployment_id, resolve_endpoints_handle, resolve_iam_handle, resolve_object_store_handle, resolve_oidc_handle, - resolve_outbound_tls_generation, resolve_outbound_tls_state, resolve_region, resolve_replication_pool_handle, - resolve_replication_stats_handle, resolve_runtime_port, resolve_server_config, resolve_token_signing_key, + current_object_store_handle, current_server_config, resolve_deployment_id, resolve_endpoints_handle, resolve_iam_handle, + resolve_oidc_handle, resolve_outbound_tls_generation, resolve_outbound_tls_state, resolve_region, + resolve_replication_pool_handle, resolve_replication_stats_handle, resolve_runtime_port, resolve_token_signing_key, }; use crate::admin::site_replication_identity::{ canonical_endpoint, deployment_id_for_endpoint, normalize_peer_map_by_identity_with, same_identity_endpoint, @@ -597,7 +597,7 @@ async fn read_site_replication_json( } async fn load_site_replication_state() -> S3Result { - let Some(store) = resolve_object_store_handle() else { + let Some(store) = current_object_store_handle() else { return Err(S3Error::with_message(S3ErrorCode::InternalError, "Not init".to_string())); }; @@ -617,7 +617,7 @@ async fn load_site_replication_state() -> S3Result { } async fn save_site_replication_state(state: &SiteReplicationState) -> S3Result<()> { - let Some(store) = resolve_object_store_handle() else { + let Some(store) = current_object_store_handle() else { return Err(S3Error::with_message(S3ErrorCode::InternalError, "Not init".to_string())); }; @@ -633,7 +633,7 @@ async fn save_site_replication_state(state: &SiteReplicationState) -> S3Result<( } async fn clear_site_replication_state() -> S3Result<()> { - let Some(store) = resolve_object_store_handle() else { + let Some(store) = current_object_store_handle() else { return Err(S3Error::with_message(S3ErrorCode::InternalError, "Not init".to_string())); }; @@ -843,7 +843,7 @@ fn ldap_settings_from_kvs(kvs: &rustfs_config::server_config::KVS) -> (LDAPSetti } fn load_ldap_idp_settings() -> (LDAPSettings, LDAPConfigSettings) { - let Some(config) = resolve_server_config() else { + let Some(config) = current_server_config() else { return (LDAPSettings::default(), LDAPConfigSettings::default()); }; @@ -2070,7 +2070,7 @@ pub async fn site_replication_make_bucket_hook(bucket: &str, lock_enabled: bool) ) .await?; - let created_at = resolve_object_store_handle() + let created_at = current_object_store_handle() .ok_or_else(|| S3Error::with_message(S3ErrorCode::InternalError, "Not init".to_string()))? .get_bucket_info(bucket, &BucketOptions::default()) .await @@ -2180,7 +2180,7 @@ fn maybe_time(value: OffsetDateTime) -> Option { } async fn build_sr_info(state: &SiteReplicationState, local_peer: &PeerInfo) -> S3Result { - let Some(store) = resolve_object_store_handle() else { + let Some(store) = current_object_store_handle() else { return Err(S3Error::with_message(S3ErrorCode::InternalError, "Not init".to_string())); }; @@ -4015,7 +4015,7 @@ async fn cleanup_removed_site_replication_buckets(removed_deployment_ids: &HashS return Ok(0); } - let Some(store) = resolve_object_store_handle() else { + let Some(store) = current_object_store_handle() else { return Ok(0); }; let buckets = store.list_bucket(&BucketOptions::default()).await.map_err(ApiError::from)?; @@ -4058,7 +4058,7 @@ async fn backfill_existing_buckets_after_add( local_peer: &PeerInfo, service_account_secret_key: &str, ) { - let Some(store) = resolve_object_store_handle() else { + let Some(store) = current_object_store_handle() else { return; }; let buckets = match store.list_bucket(&BucketOptions::default()).await { @@ -4174,7 +4174,7 @@ async fn refresh_bucket_targets_after_service_account_rotation( local_peer: &PeerInfo, service_account_secret_key: &str, ) { - let Some(store) = resolve_object_store_handle() else { + let Some(store) = current_object_store_handle() else { return; }; let buckets = match store.list_bucket(&BucketOptions::default()).await { @@ -4440,7 +4440,7 @@ fn bucket_meta_local_updated_at( } async fn apply_bucket_meta_item(item: SRBucketMeta) -> S3Result<()> { - let Some(store) = resolve_object_store_handle() else { + let Some(store) = current_object_store_handle() else { return Err(S3Error::with_message(S3ErrorCode::InternalError, "Not init".to_string())); }; @@ -5196,7 +5196,7 @@ impl Operation for SRPeerBucketOpsHandler { .cloned() .ok_or_else(|| s3_error!(InvalidRequest, "operation is required"))?; - let Some(store) = resolve_object_store_handle() else { + let Some(store) = current_object_store_handle() else { return Err(S3Error::with_message(S3ErrorCode::InternalError, "Not init".to_string())); }; @@ -5458,7 +5458,7 @@ impl Operation for SiteReplicationResyncOpHandler { if !state.peers.contains_key(&peer.deployment_id) { return Err(s3_error!(InvalidRequest, "site replication peer not found")); } - let Some(store) = resolve_object_store_handle() else { + let Some(store) = current_object_store_handle() else { return Err(S3Error::with_message(S3ErrorCode::InternalError, "Not init".to_string())); }; let buckets = store.list_bucket(&BucketOptions::default()).await.map_err(ApiError::from)?; diff --git a/rustfs/src/admin/handlers/table_catalog.rs b/rustfs/src/admin/handlers/table_catalog.rs index 8b0f88c9f..d370d8edb 100644 --- a/rustfs/src/admin/handlers/table_catalog.rs +++ b/rustfs/src/admin/handlers/table_catalog.rs @@ -13,7 +13,7 @@ // limitations under the License. use crate::admin::runtime_sources::default_admin_usecase; -use crate::admin::runtime_sources::{resolve_object_store_handle, resolve_token_signing_key}; +use crate::admin::runtime_sources::{current_object_store_handle, resolve_token_signing_key}; use crate::admin::storage_api::bucket::{metadata::table_catalog_path_hash, metadata_sys}; use crate::admin::storage_api::runtime::ECStore; use crate::admin::{ @@ -1258,7 +1258,7 @@ fn job_id_from_params(params: &Params<'_, '_>) -> S3Result { } fn table_catalog_backend() -> S3Result> { - let store = resolve_object_store_handle().ok_or_else(|| s3_error!(InternalError, "object store not initialized"))?; + let store = current_object_store_handle().ok_or_else(|| s3_error!(InternalError, "object store not initialized"))?; Ok(crate::table_catalog::EcStoreTableCatalogObjectBackend::new(store)) } diff --git a/rustfs/src/admin/handlers/tier.rs b/rustfs/src/admin/handlers/tier.rs index dcd8c1012..f96b38b31 100644 --- a/rustfs/src/admin/handlers/tier.rs +++ b/rustfs/src/admin/handlers/tier.rs @@ -20,7 +20,7 @@ use crate::admin::storage_api::tier::{ }; use crate::{ admin::runtime_sources::{ - resolve_daily_tier_stats, resolve_notification_system, resolve_object_store_handle, resolve_tier_config_handle, + current_notification_system, current_object_store_handle, resolve_daily_tier_stats, resolve_tier_config_handle, }, admin::{ auth::validate_admin_request, @@ -81,7 +81,7 @@ pub struct AddTierQuery { pub struct AddTier {} fn spawn_transition_tier_config_propagation(action: &'static str) { - if let Some(notification_sys) = resolve_notification_system() { + if let Some(notification_sys) = current_notification_system() { spawn_traced(async move { for peer_result in notification_sys.load_transition_tier_config().await { if let Some(err) = peer_result.err { @@ -292,7 +292,7 @@ impl Operation for AddTier { &_ => (), } - let Some(store) = resolve_object_store_handle() else { + let Some(store) = current_object_store_handle() else { return Err(s3_error!(InternalError, "object store is not initialized")); }; @@ -439,7 +439,7 @@ impl Operation for EditTier { "admin tier state" ); - let Some(store) = resolve_object_store_handle() else { + let Some(store) = current_object_store_handle() else { return Err(s3_error!(InternalError, "object store is not initialized")); }; @@ -609,7 +609,7 @@ impl Operation for RemoveTier { let tier_name = params.get("tiername").map(|s| s.to_string()).unwrap_or_default(); - let Some(store) = resolve_object_store_handle() else { + let Some(store) = current_object_store_handle() else { return Err(s3_error!(InternalError, "object store is not initialized")); }; diff --git a/rustfs/src/admin/router.rs b/rustfs/src/admin/router.rs index 1bfa4266a..eb928a2d8 100644 --- a/rustfs/src/admin/router.rs +++ b/rustfs/src/admin/router.rs @@ -28,9 +28,9 @@ use super::storage_api::runtime::PeerRestClient; use crate::admin::console::{is_console_path, make_console_server}; use crate::admin::handlers::oidc::is_oidc_path; use crate::admin::runtime_sources::{ - default_object_usecase, resolve_boot_time, resolve_bucket_monitor_handle, resolve_deployment_id, resolve_notification_system, - resolve_object_store_handle, resolve_region, resolve_replication_pool_handle, resolve_replication_stats_handle, - resolve_server_config, + current_notification_system, current_object_store_handle, current_server_config, default_object_usecase, resolve_boot_time, + resolve_bucket_monitor_handle, resolve_deployment_id, resolve_region, resolve_replication_pool_handle, + resolve_replication_stats_handle, }; use crate::admin::storage_api::access::{ReqInfo, authorize_request, spawn_traced}; use crate::admin::storage_api::contract::bucket::{BucketOperations, BucketOptions}; @@ -631,7 +631,7 @@ async fn load_current_server_config() -> S3Result { return Ok(system.config.read().await.clone()); } - if let Some(store) = resolve_object_store_handle() { + if let Some(store) = current_object_store_handle() { match read_admin_config_without_migrate(store).await { Ok(config) => return Ok(config), Err(err) => { @@ -647,7 +647,7 @@ async fn load_current_server_config() -> S3Result { } } - let config = resolve_server_config().ok_or_else(|| s3_error!(InternalError, "server config is not initialized"))?; + let config = current_server_config().ok_or_else(|| s3_error!(InternalError, "server config is not initialized"))?; Ok(config) } @@ -1189,7 +1189,7 @@ fn serialize_listen_notification_event(event: &NotificationEvent) -> S3Result Vec { - resolve_notification_system() + current_notification_system() .map(|system| { system .peer_clients @@ -1401,7 +1401,7 @@ fn build_listen_notification_response(uri: &Uri, bucket: Option<&str>) -> S3Resu } async fn ensure_replication_bucket_exists(bucket: &str) -> S3Result<()> { - let Some(store) = resolve_object_store_handle() else { + let Some(store) = current_object_store_handle() else { return Err(S3Error::with_message(S3ErrorCode::InternalError, "Not init")); }; @@ -2277,7 +2277,7 @@ async fn handle_misc_extension_request(req: &mut S3Request, route: &MiscEx } MiscExtRoute::ListenNotification { bucket } => { if let Some(bucket_name) = bucket { - let Some(store) = resolve_object_store_handle() else { + let Some(store) = current_object_store_handle() else { return Err(S3Error::with_message(S3ErrorCode::InternalError, "Not init")); }; store diff --git a/rustfs/src/admin/runtime_sources.rs b/rustfs/src/admin/runtime_sources.rs index 8c3520f4a..665b63a20 100644 --- a/rustfs/src/admin/runtime_sources.rs +++ b/rustfs/src/admin/runtime_sources.rs @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +use crate::admin::storage_api::runtime::{ECStore, NotificationSys}; pub(crate) use crate::app::admin_usecase::{ AdminPoolStatus, DefaultAdminUsecase, QueryPoolStatusRequest, QueryServerInfoRequest, }; @@ -19,13 +20,13 @@ use crate::app::object_usecase::DefaultObjectUsecase; pub(crate) use crate::runtime_sources::{ AppContext, publish_server_config, publish_storage_class_config, resolve_action_credentials, resolve_boot_time, resolve_bucket_metadata_handle, resolve_bucket_monitor_handle, resolve_daily_tier_stats, resolve_deployment_id, - resolve_endpoints_handle, resolve_iam_handle, resolve_kms_runtime_service_manager, resolve_notification_system, - resolve_notification_system_for_context, resolve_object_store_handle, resolve_object_store_handle_for_context, - resolve_oidc_handle, resolve_or_init_kms_runtime_service_manager, resolve_outbound_tls_generation, - resolve_outbound_tls_state, resolve_ready_iam_handle, resolve_region, resolve_replication_pool_handle, - resolve_replication_stats_handle, resolve_runtime_port, resolve_scanner_metrics_report, resolve_server_config, + resolve_endpoints_handle, resolve_iam_handle, resolve_kms_runtime_service_manager, resolve_notification_system_for_context, + resolve_object_store_handle_for_context, resolve_oidc_handle, resolve_or_init_kms_runtime_service_manager, + resolve_outbound_tls_generation, resolve_outbound_tls_state, resolve_ready_iam_handle, resolve_region, + resolve_replication_pool_handle, resolve_replication_stats_handle, resolve_runtime_port, resolve_scanner_metrics_report, resolve_server_config_for_context, resolve_tier_config_handle, resolve_token_signing_key, }; +use rustfs_config::server_config::Config; use std::sync::Arc; #[cfg(test)] @@ -42,3 +43,18 @@ pub(crate) fn default_object_usecase() -> DefaultObjectUsecase { pub(crate) fn current_app_context() -> Option> { crate::runtime_sources::current_app_context() } + +pub(crate) fn current_object_store_handle() -> Option> { + let context = current_app_context(); + resolve_object_store_handle_for_context(context.as_deref()) +} + +pub(crate) fn current_notification_system() -> Option<&'static NotificationSys> { + let context = current_app_context(); + resolve_notification_system_for_context(context.as_deref()) +} + +pub(crate) fn current_server_config() -> Option { + let context = current_app_context(); + resolve_server_config_for_context(context.as_deref()) +}