diff --git a/docs/architecture/migration-progress.md b/docs/architecture/migration-progress.md index e93cb63fd..54e8cddc4 100644 --- a/docs/architecture/migration-progress.md +++ b/docs/architecture/migration-progress.md @@ -5,8 +5,8 @@ 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-startup-runtime-sources` -- 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`. +- Branch: `overtrue/arch-server-storage-runtime-source-readers` +- 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`. - Based on: stacked on PR #3828 head after PR #3827. - PR type for this branch: `consumer-migration` - Runtime behavior changes: none. @@ -43,7 +43,8 @@ Status values: `[ ]` not started, `[~]` in progress, `[x]` complete, `[!]` block source helpers, plus AppContext fallback KMS/IAM/ECStore/config/metrics/TLS runtime source helpers, plus startup/root KMS, credentials, region, readiness-time, observability, metrics, buffer, and TLS runtime source - helpers, + helpers, plus server readiness/audit/event/module-switch runtime source + helpers and storage request/RPC/SSE runtime source helpers, through AppContext-first or owner-crate resolver boundaries. - CI/script changes: lock completed owner and test/fuzz boundaries against bare/glob imports, scattered raw ECStore facade subpaths, and startup @@ -54,7 +55,7 @@ Status values: `[ ]` not started, `[~]` in progress, `[x]` complete, `[!]` block event-bridge thin module regressions, plus IAM runtime-source bypasses; accept the reviewed AppContext resolver reverse dependencies in the layer baseline. -- Docs changes: record the API-136 through API-203 owner facade and lifecycle +- Docs changes: record the API-136 through API-204 owner facade and lifecycle runtime-source cleanup. ## Phase 0 Tasks @@ -4920,6 +4921,23 @@ Status values: `[ ]` not started, `[~]` in progress, `[x]` complete, `[!]` block global scan, migration/layer guards, fast PR gate, and full PR gate before PR. +- [x] `API-204` Centralize server and storage runtime source readers. + - Do: route server audit/event/module-switch/readiness/KMS health reads, + startup bucket replication-pool reads, and storage request/RPC/SSE runtime + reads through owner runtime-source boundaries. + - Acceptance: the migrated server/startup/storage files no longer import + AppContext resolvers directly, and migration rules reject reintroducing + those direct resolver reads outside the owner runtime-source modules. + - Must preserve: audit/notify module switch behavior, public health KMS + readiness behavior, dependency readiness cache behavior, bucket metadata + replication resync startup, buffer profile lookup, object-store lookup, + internode metrics recording, local-node naming, request credential/notify + dispatch, performance metrics, encryption service lookup, region lookup, + and IAM authorization behavior. + - Verification: focused RustFS storage/server compile and tests, formatting, + migration/layer guards, diff hygiene, residual direct AppContext scan, Rust + risk scan, fast PR gate, and full PR gate before PR. + ## Next PRs 1. `consumer-migration`: continue reducing direct global reads behind AppContext resolver boundaries. diff --git a/rustfs/src/server/audit.rs b/rustfs/src/server/audit.rs index e72ad29c2..466dfd4f8 100644 --- a/rustfs/src/server/audit.rs +++ b/rustfs/src/server/audit.rs @@ -12,8 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use super::{module_switch::resolve_audit_module_state, refresh_persisted_module_switches_from_store}; -use crate::app::context::resolve_server_config; +use super::{module_switch::resolve_audit_module_state, refresh_persisted_module_switches_from_store, runtime_sources}; use rustfs_audit::{AuditError, AuditResult, audit_system, init_audit_system, system::AuditSystemState}; use std::sync::atomic::{AtomicBool, Ordering}; use tracing::{info, warn}; @@ -21,7 +20,7 @@ use tracing::{info, warn}; static AUDIT_MODULE_ENABLED: AtomicBool = AtomicBool::new(rustfs_config::DEFAULT_AUDIT_ENABLE); fn server_config_from_context() -> Option { - resolve_server_config() + runtime_sources::server_config() } pub fn refresh_audit_module_enabled() -> bool { diff --git a/rustfs/src/server/event.rs b/rustfs/src/server/event.rs index 00f91dce5..21b067b3d 100644 --- a/rustfs/src/server/event.rs +++ b/rustfs/src/server/event.rs @@ -12,8 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use super::{module_switch::resolve_notify_module_state, refresh_persisted_module_switches_from_store}; -use crate::app::context::{resolve_notify_interface, resolve_server_config}; +use super::{module_switch::resolve_notify_module_state, refresh_persisted_module_switches_from_store, runtime_sources}; use crate::storage::{EventArgs as EcstoreEventArgs, StorageObjectInfo, register_event_dispatch_hook}; use chrono::{DateTime, Utc}; use rustfs_notify::{EventArgs as NotifyEventArgs, NotifyObjectInfo}; @@ -26,7 +25,7 @@ use tracing::{error, info, instrument, warn}; static NOTIFY_MODULE_ENABLED: AtomicBool = AtomicBool::new(rustfs_config::DEFAULT_NOTIFY_ENABLE); fn server_config_from_context() -> Option { - resolve_server_config() + runtime_sources::server_config() } pub fn refresh_notify_module_enabled() -> bool { @@ -118,7 +117,7 @@ fn install_ecstore_event_dispatch_hook() { return; }; spawn(async move { - resolve_notify_interface().notify(notify_args).await; + runtime_sources::notify_interface().notify(notify_args).await; }); }); diff --git a/rustfs/src/server/layer.rs b/rustfs/src/server/layer.rs index 3983b6198..12c983393 100644 --- a/rustfs/src/server/layer.rs +++ b/rustfs/src/server/layer.rs @@ -12,9 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. +use super::runtime_sources; use crate::admin::console::is_console_path; use crate::admin::handlers::health::{HealthProbe, build_health_response_parts}; -use crate::app::context::resolve_kms_runtime_service_manager; use crate::error::ApiError; use crate::server::RemoteAddr; use crate::server::cors; @@ -905,7 +905,7 @@ fn is_public_health_endpoint_request(method: &Method, path: &str) -> bool { } async fn health_kms_ready() -> bool { - let Some(service_manager) = resolve_kms_runtime_service_manager() else { + let Some(service_manager) = runtime_sources::kms_runtime_service_manager() else { return true; }; diff --git a/rustfs/src/server/mod.rs b/rustfs/src/server/mod.rs index b8566e80f..d3ba1bc46 100644 --- a/rustfs/src/server/mod.rs +++ b/rustfs/src/server/mod.rs @@ -23,6 +23,7 @@ mod module_switch; mod prefix; mod readiness; mod runtime; +pub(crate) mod runtime_sources; mod service_state; pub mod tls_material; diff --git a/rustfs/src/server/module_switch.rs b/rustfs/src/server/module_switch.rs index 45e3178b9..824f31d81 100644 --- a/rustfs/src/server/module_switch.rs +++ b/rustfs/src/server/module_switch.rs @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::app::context::resolve_object_store_handle; +use super::runtime_sources; use crate::storage::{Error as StorageError, read_config, save_config}; use serde::{Deserialize, Serialize}; use std::sync::atomic::{AtomicBool, Ordering}; @@ -159,7 +159,7 @@ pub(crate) fn validate_module_switch_update(requested: PersistedModuleSwitches) } pub(crate) async fn refresh_persisted_module_switches_from_store() -> Result { - let Some(store) = resolve_object_store_handle() else { + let Some(store) = runtime_sources::object_store_handle() else { return Err("storage layer not initialized".to_string()); }; @@ -180,7 +180,7 @@ pub(crate) async fn refresh_persisted_module_switches_from_store() -> Result Result<(), String> { - let Some(store) = resolve_object_store_handle() else { + let Some(store) = runtime_sources::object_store_handle() else { return Err("storage layer not initialized".to_string()); }; diff --git a/rustfs/src/server/readiness.rs b/rustfs/src/server/readiness.rs index da6b6541b..4f0b80575 100644 --- a/rustfs/src/server/readiness.rs +++ b/rustfs/src/server/readiness.rs @@ -12,9 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::app::context::{ - resolve_endpoints_handle, resolve_iam_ready, resolve_lock_clients_handle, resolve_object_store_handle, -}; +use crate::server::runtime_sources; use crate::server::{ServiceState, ServiceStateManager}; use crate::server::{has_path_prefix, is_table_catalog_path}; use crate::storage::{Endpoint, EndpointServerPools, is_dist_erasure}; @@ -448,7 +446,7 @@ pub async fn collect_dependency_readiness() -> DependencyReadiness { } pub async fn collect_dependency_readiness_report() -> DependencyReadinessReport { - let iam_ready_raw = resolve_iam_ready(); + let iam_ready_raw = runtime_sources::iam_ready(); let storage_ready = if let Some(cached) = load_cached_storage_readiness().await { cached } else { @@ -471,7 +469,7 @@ pub async fn collect_dependency_readiness_report() -> DependencyReadinessReport pub(crate) async fn snapshot_dependency_readiness_report() -> DependencyReadinessReport { let readiness = DependencyReadiness { storage_ready: collect_storage_readiness_uncached().await, - iam_ready: resolve_iam_ready(), + iam_ready: runtime_sources::iam_ready(), lock_quorum_ready: collect_lock_quorum_status_uncached().await.ready, }; @@ -489,7 +487,7 @@ async fn collect_lock_quorum_status() -> LockQuorumStatus { } async fn collect_dependency_readiness_uncached() -> DependencyReadiness { - let iam_ready_raw = resolve_iam_ready(); + let iam_ready_raw = runtime_sources::iam_ready(); let storage_ready = collect_storage_readiness_uncached().await; let lock_quorum_status = collect_lock_quorum_status_uncached().await; @@ -504,7 +502,7 @@ async fn collect_dependency_readiness_uncached() -> DependencyReadiness { } async fn collect_storage_readiness_uncached() -> bool { - if let Some(store) = resolve_object_store_handle() { + if let Some(store) = runtime_sources::object_store_handle() { let storage_info = StorageAdminApi::storage_info(store.as_ref()).await; storage_ready_from_runtime_state(&storage_info) } else { @@ -595,10 +593,10 @@ async fn collect_lock_quorum_status_uncached() -> LockQuorumStatus { }; } - let Some(pool_endpoints) = resolve_endpoints_handle() else { + let Some(pool_endpoints) = runtime_sources::endpoints_handle() else { return LockQuorumStatus::default(); }; - let Some(lock_clients) = resolve_lock_clients_handle() else { + let Some(lock_clients) = runtime_sources::lock_clients_handle() else { return LockQuorumStatus::default(); }; diff --git a/rustfs/src/server/runtime_sources.rs b/rustfs/src/server/runtime_sources.rs new file mode 100644 index 000000000..d2094bae1 --- /dev/null +++ b/rustfs/src/server/runtime_sources.rs @@ -0,0 +1,48 @@ +// Copyright 2024 RustFS Team +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use crate::app::context; +use crate::storage::{ECStore, EndpointServerPools}; +use rustfs_kms::KmsServiceManager; +use rustfs_lock::LockClient; +use std::collections::HashMap; +use std::sync::Arc; + +pub(crate) fn kms_runtime_service_manager() -> Option> { + context::resolve_kms_runtime_service_manager() +} + +pub(crate) fn server_config() -> Option { + context::resolve_server_config() +} + +pub(crate) fn notify_interface() -> Arc { + context::resolve_notify_interface() +} + +pub(crate) fn object_store_handle() -> Option> { + context::resolve_object_store_handle() +} + +pub(crate) fn iam_ready() -> bool { + context::resolve_iam_ready() +} + +pub(crate) fn endpoints_handle() -> Option { + context::resolve_endpoints_handle() +} + +pub(crate) fn lock_clients_handle() -> Option>> { + context::resolve_lock_clients_handle() +} diff --git a/rustfs/src/startup_bucket_metadata.rs b/rustfs/src/startup_bucket_metadata.rs index f64aa61f3..85c99027c 100644 --- a/rustfs/src/startup_bucket_metadata.rs +++ b/rustfs/src/startup_bucket_metadata.rs @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::app::context::resolve_replication_pool_handle; +use crate::startup_runtime_sources; use crate::storage::{ECStore, init_bucket_metadata_sys, try_migrate_bucket_metadata, try_migrate_iam_config}; use rustfs_storage_api::{BucketOperations, BucketOptions}; use std::{ @@ -52,7 +52,7 @@ pub(crate) async fn init_bucket_metadata_runtime(store: Arc, ctx: Cance try_migrate_bucket_metadata(store.clone()).await; - if let Some(pool) = resolve_replication_pool_handle() { + if let Some(pool) = startup_runtime_sources::replication_pool_handle() { pool.init_resync(ctx, buckets.clone()).await?; } diff --git a/rustfs/src/startup_runtime_sources.rs b/rustfs/src/startup_runtime_sources.rs index a22080756..d73493b8d 100644 --- a/rustfs/src/startup_runtime_sources.rs +++ b/rustfs/src/startup_runtime_sources.rs @@ -13,7 +13,7 @@ // limitations under the License. use crate::config::RustFSBufferConfig; -use crate::storage::{set_global_region, set_global_rustfs_port}; +use crate::storage::{DynReplicationPool, set_global_region, set_global_rustfs_port}; use rustfs_kms::KmsServiceManager; use rustfs_obs::{GlobalError as ObservabilityError, OtelGuard}; use rustfs_tls_runtime::{OutboundTlsMaterial, TlsGeneration}; @@ -71,6 +71,10 @@ pub(crate) fn init_metrics_runtime(ctx: CancellationToken) { rustfs_obs::init_metrics_runtime(ctx); } +pub(crate) fn replication_pool_handle() -> Option> { + crate::app::context::resolve_replication_pool_handle() +} + pub(crate) fn set_put_stage_metrics_enabled(enabled: bool) { rustfs_io_metrics::set_put_stage_metrics_enabled(enabled); } diff --git a/rustfs/src/storage/access.rs b/rustfs/src/storage/access.rs index 6cc960c27..4432d469e 100644 --- a/rustfs/src/storage/access.rs +++ b/rustfs/src/storage/access.rs @@ -18,12 +18,12 @@ use super::resolve_object_store_handle; use super::{ PolicySys, StorageError, get_bucket_metadata, get_bucket_policy_raw, get_public_access_block_config, is_err_bucket_not_found, }; -use crate::app::context::resolve_region; use crate::auth::{check_key_valid, get_condition_values_with_query_and_client_info, get_session_token}; use crate::error::ApiError; use crate::license::license_check; use crate::server::RemoteAddr; use crate::storage::request_context::RequestContext; +use crate::storage::runtime_sources; use metrics::counter; use rustfs_iam::error::Error as IamError; use rustfs_policy::policy::action::{Action, AdminAction, S3Action}; @@ -328,7 +328,7 @@ pub async fn authorize_request(req: &mut S3Request, action: Action) -> S3R let version_id = req_info.version_id.clone(); if let Some(cred) = &cred { - let Ok(iam_store) = crate::app::context::resolve_ready_iam_handle() else { + let Ok(iam_store) = runtime_sources::ready_iam_handle() else { return Err(S3Error::with_message( S3ErrorCode::InternalError, format!("authorize_request {:?}", IamError::IamSysNotInitialized), @@ -841,7 +841,7 @@ async fn authorize_table_data_plane_if_needed( let Some(resource) = table_data_plane_resource_for_request(bucket, object).await? else { return Ok(()); }; - let Ok(iam_store) = crate::app::context::resolve_ready_iam_handle() else { + let Ok(iam_store) = runtime_sources::ready_iam_handle() else { return Err(s3_error!(InternalError, "iam not init")); }; @@ -931,7 +931,7 @@ impl S3Access for FS { let req_info = ReqInfo { cred, is_owner, - region: resolve_region(), + region: runtime_sources::region(), request_context, ..Default::default() }; diff --git a/rustfs/src/storage/concurrency/manager.rs b/rustfs/src/storage/concurrency/manager.rs index a294a1c63..94db26185 100644 --- a/rustfs/src/storage/concurrency/manager.rs +++ b/rustfs/src/storage/concurrency/manager.rs @@ -19,7 +19,7 @@ use super::io_schedule::{ get_advanced_buffer_size, }; use super::request_guard::{GetObjectGuard, PutObjectGuard}; -use crate::app::context::resolve_performance_metrics; +use crate::storage::runtime_sources; use rustfs_concurrency::{ AdmissionState, GetObjectQueueSnapshot, WorkloadAdmissionRegistrySnapshot, WorkloadAdmissionSnapshot, WorkloadAdmissionSnapshotProvider, WorkloadClass, @@ -118,7 +118,7 @@ impl ConcurrencyManager { // Use global performance metrics instance for consistent metrics tracking // This allows AutoTuner and other components to access the same metrics data - let performance_metrics = resolve_performance_metrics(); + let performance_metrics = runtime_sources::performance_metrics(); // Initialize metrics collector for I/O latency tracking // Keep 1000 samples for P95/P99 calculation @@ -235,7 +235,7 @@ impl ConcurrencyManager { /// /// Arc-wrapped PerformanceMetrics instance pub fn performance_metrics(&self) -> Arc { - resolve_performance_metrics() + runtime_sources::performance_metrics() } /// Calculate an adaptive I/O strategy based on disk permit wait time. diff --git a/rustfs/src/storage/ecfs.rs b/rustfs/src/storage/ecfs.rs index c1418bd27..978605fab 100644 --- a/rustfs/src/storage/ecfs.rs +++ b/rustfs/src/storage/ecfs.rs @@ -22,13 +22,13 @@ use super::{ }; use super::{StorageReplicationConfigExt as _, StorageVersioningConfigExt as _}; use crate::app::bucket_usecase::DefaultBucketUsecase; -use crate::app::context::resolve_object_store_handle; use crate::app::multipart_usecase::DefaultMultipartUsecase; use crate::app::object_usecase::DefaultObjectUsecase; use crate::error::ApiError; use crate::storage::access::has_bypass_governance_header; use crate::storage::helper::OperationHelper; use crate::storage::options::get_opts; +use crate::storage::runtime_sources; use crate::storage::s3_api::acl; use crate::storage::{parse_object_lock_legal_hold, parse_object_lock_retention, validate_bucket_object_lock_enabled}; use crate::table_catalog; @@ -97,7 +97,7 @@ impl FS { object: &str, version_id: Option<&str>, ) -> S3Result>> { - let Some(store) = resolve_object_store_handle() else { + let Some(store) = runtime_sources::object_store_handle() else { return Ok(std::collections::HashMap::new()); }; let opts = ObjectOptions { @@ -341,7 +341,7 @@ impl S3 for FS { &self, req: S3Request, ) -> S3Result> { - let Some(store) = resolve_object_store_handle() else { + let Some(store) = runtime_sources::object_store_handle() else { return Err(s3_error!(InternalError, "Not init")); }; @@ -390,7 +390,7 @@ impl S3 for FS { validate_table_catalog_object_mutation(&bucket, &object).await?; - let Some(store) = resolve_object_store_handle() else { + let Some(store) = runtime_sources::object_store_handle() else { error!( component = LOG_COMPONENT_STORAGE, subsystem = LOG_SUBSYSTEM_TAGGING, @@ -472,7 +472,7 @@ impl S3 for FS { record_s3_op(S3Operation::GetBucketAcl, &req.input.bucket); let GetBucketAclInput { bucket, .. } = req.input; - let Some(store) = resolve_object_store_handle() else { + let Some(store) = runtime_sources::object_store_handle() else { return Err(S3Error::with_message(S3ErrorCode::InternalError, "Not init".to_string())); }; @@ -488,7 +488,7 @@ impl S3 for FS { &self, req: S3Request, ) -> S3Result> { - let Some(store) = resolve_object_store_handle() else { + let Some(store) = runtime_sources::object_store_handle() else { return Err(s3_error!(InternalError, "Not init")); }; @@ -578,7 +578,7 @@ impl S3 for FS { &self, req: S3Request, ) -> S3Result> { - let Some(store) = resolve_object_store_handle() else { + let Some(store) = runtime_sources::object_store_handle() else { return Err(s3_error!(InternalError, "Not init")); }; @@ -626,7 +626,7 @@ impl S3 for FS { } async fn get_bucket_website(&self, req: S3Request) -> S3Result> { - let Some(store) = resolve_object_store_handle() else { + let Some(store) = runtime_sources::object_store_handle() else { return Err(s3_error!(InternalError, "Not init")); }; @@ -664,7 +664,7 @@ impl S3 for FS { bucket, key, version_id, .. } = req.input; - let Some(store) = resolve_object_store_handle() else { + let Some(store) = runtime_sources::object_store_handle() else { return Err(S3Error::with_message(S3ErrorCode::InternalError, "Not init".to_string())); }; @@ -694,7 +694,7 @@ impl S3 for FS { bucket, key, version_id, .. } = req.input.clone(); - let Some(store) = resolve_object_store_handle() else { + let Some(store) = runtime_sources::object_store_handle() else { return Err(S3Error::with_message(S3ErrorCode::InternalError, "Not init".to_string())); }; @@ -755,7 +755,7 @@ impl S3 for FS { record_s3_op(S3Operation::GetObjectLockConfiguration, &req.input.bucket); let GetObjectLockConfigurationInput { bucket, .. } = req.input; - let Some(store) = resolve_object_store_handle() else { + let Some(store) = runtime_sources::object_store_handle() else { return Err(S3Error::with_message(S3ErrorCode::InternalError, "Not init".to_string())); }; @@ -803,7 +803,7 @@ impl S3 for FS { bucket, key, version_id, .. } = req.input.clone(); - let Some(store) = resolve_object_store_handle() else { + let Some(store) = runtime_sources::object_store_handle() else { return Err(S3Error::with_message(S3ErrorCode::InternalError, "Not init".to_string())); }; @@ -855,7 +855,7 @@ impl S3 for FS { let bucket = req.input.bucket.as_str(); let object = req.input.key.as_str(); - let Some(store) = resolve_object_store_handle() else { + let Some(store) = runtime_sources::object_store_handle() else { error!( component = LOG_COMPONENT_STORAGE, subsystem = LOG_SUBSYSTEM_TAGGING, @@ -1013,7 +1013,7 @@ impl S3 for FS { } = req.input; record_s3_op(S3Operation::PutBucketAcl, &bucket); - let Some(store) = resolve_object_store_handle() else { + let Some(store) = runtime_sources::object_store_handle() else { return Err(S3Error::with_message(S3ErrorCode::InternalError, "Not init".to_string())); }; @@ -1036,7 +1036,7 @@ impl S3 for FS { &self, req: S3Request, ) -> S3Result> { - let Some(store) = resolve_object_store_handle() else { + let Some(store) = runtime_sources::object_store_handle() else { return Err(s3_error!(InternalError, "Not init")); }; store @@ -1061,7 +1061,7 @@ impl S3 for FS { async fn get_bucket_logging(&self, req: S3Request) -> S3Result> { record_s3_op(S3Operation::GetBucketLogging, &req.input.bucket); - let Some(store) = resolve_object_store_handle() else { + let Some(store) = runtime_sources::object_store_handle() else { return Err(s3_error!(InternalError, "Not init")); }; store @@ -1080,7 +1080,7 @@ impl S3 for FS { async fn put_bucket_logging(&self, req: S3Request) -> S3Result> { record_s3_op(S3Operation::PutBucketLogging, &req.input.bucket); - let Some(store) = resolve_object_store_handle() else { + let Some(store) = runtime_sources::object_store_handle() else { return Err(s3_error!(InternalError, "Not init")); }; store @@ -1139,7 +1139,7 @@ impl S3 for FS { &self, req: S3Request, ) -> S3Result> { - let Some(store) = resolve_object_store_handle() else { + let Some(store) = runtime_sources::object_store_handle() else { return Err(s3_error!(InternalError, "Not init")); }; store @@ -1181,7 +1181,7 @@ impl S3 for FS { } async fn put_bucket_website(&self, req: S3Request) -> S3Result> { - let Some(store) = resolve_object_store_handle() else { + let Some(store) = runtime_sources::object_store_handle() else { return Err(s3_error!(InternalError, "Not init")); }; store @@ -1211,7 +1211,7 @@ impl S3 for FS { let key = &req.input.key; let version_id = req.input.version_id.clone(); - let Some(store) = resolve_object_store_handle() else { + let Some(store) = runtime_sources::object_store_handle() else { return Err(S3Error::with_message(S3ErrorCode::InternalError, "Not init".to_string())); }; @@ -1253,7 +1253,7 @@ impl S3 for FS { validate_table_catalog_object_mutation(&bucket, &key).await?; - let Some(store) = resolve_object_store_handle() else { + let Some(store) = runtime_sources::object_store_handle() else { return Err(S3Error::with_message(S3ErrorCode::InternalError, "Not init".to_string())); }; @@ -1307,7 +1307,7 @@ impl S3 for FS { let Some(input_cfg) = object_lock_configuration else { return Err(s3_error!(InvalidArgument)) }; - let Some(store) = resolve_object_store_handle() else { + let Some(store) = runtime_sources::object_store_handle() else { return Err(S3Error::with_message(S3ErrorCode::InternalError, "Not init".to_string())); }; @@ -1379,7 +1379,7 @@ impl S3 for FS { validate_table_catalog_object_mutation(&bucket, &key).await?; - let Some(store) = resolve_object_store_handle() else { + let Some(store) = runtime_sources::object_store_handle() else { return Err(S3Error::with_message(S3ErrorCode::InternalError, "Not init".to_string())); }; @@ -1458,7 +1458,7 @@ impl S3 for FS { crate::storage::s3_api::tagging::validate_object_tag_set(&tagging.tag_set)?; - let Some(store) = resolve_object_store_handle() else { + let Some(store) = runtime_sources::object_store_handle() else { return Err(S3Error::with_message(S3ErrorCode::InternalError, "Not init".to_string())); }; diff --git a/rustfs/src/storage/ecfs_extend.rs b/rustfs/src/storage/ecfs_extend.rs index 3c0acbf17..349f49ac6 100644 --- a/rustfs/src/storage/ecfs_extend.rs +++ b/rustfs/src/storage/ecfs_extend.rs @@ -17,7 +17,6 @@ use super::{ StorageError, add_object_lock_years, get_bucket_cors_config, get_bucket_object_lock_config, get_bucket_replication_config, resolve_object_store_handle, }; -use crate::app::context::resolve_buffer_config; use crate::config::{RustFSBufferConfig, WorkloadProfile, is_buffer_profile_enabled}; use crate::error::ApiError; use crate::server::cors; @@ -47,6 +46,7 @@ use time::format_description::well_known::Rfc3339; use time::{format_description::FormatItem, macros::format_description}; use tracing::{debug, warn}; +use crate::storage::runtime_sources; use crate::storage::{StorageObjectInfo as ObjectInfo, StorageObjectToDelete as ObjectToDelete}; const LOG_COMPONENT_STORAGE: &str = "storage"; @@ -263,7 +263,7 @@ pub(crate) fn get_adaptive_buffer_size_with_profile(file_size: i64, profile: Opt pub(crate) fn get_buffer_size_opt_in(file_size: i64) -> usize { let buffer_size = if is_buffer_profile_enabled() { // Use the AppContext-owned profile when available, with global fallback during migration. - let config = resolve_buffer_config(); + let config = runtime_sources::buffer_config(); config.get_buffer_size(file_size) } else { // Opt-out mode: Use GeneralPurpose profile for consistent behavior diff --git a/rustfs/src/storage/helper.rs b/rustfs/src/storage/helper.rs index 98c4f94a4..92f6dacf2 100644 --- a/rustfs/src/storage/helper.rs +++ b/rustfs/src/storage/helper.rs @@ -12,10 +12,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::app::context::{resolve_action_credentials, resolve_notify_interface}; use crate::server::{convert_ecstore_object_info, is_audit_module_enabled, is_notify_module_enabled}; use crate::storage::access::{ReqInfo, request_context_from_req}; use crate::storage::request_context::{RequestContext, extract_request_id_from_headers}; +use crate::storage::runtime_sources; use hashbrown::HashMap; use http::StatusCode; use metrics::counter; @@ -312,7 +312,7 @@ impl OperationHelper { final_builder = final_builder.error(err); } - if let Some(cred) = resolve_action_credentials() { + if let Some(cred) = runtime_sources::action_credentials() { final_builder = final_builder.access_key(&cred.access_key); } @@ -383,7 +383,7 @@ impl Drop for OperationHelper { if !event_args.is_replication_request() { let ctx = state.request_context.clone(); spawn_background_with_context(ctx, async move { - resolve_notify_interface().notify(event_args).await; + runtime_sources::notify_interface().notify(event_args).await; }); } } diff --git a/rustfs/src/storage/mod.rs b/rustfs/src/storage/mod.rs index a63693856..be834afcc 100644 --- a/rustfs/src/storage/mod.rs +++ b/rustfs/src/storage/mod.rs @@ -44,6 +44,7 @@ mod ecfs_test; pub(crate) mod head_prefix; #[cfg(test)] mod multi_factor_scheduler_integration_test; +pub(crate) mod runtime_sources; #[cfg(test)] mod sse_test; diff --git a/rustfs/src/storage/rpc/disk.rs b/rustfs/src/storage/rpc/disk.rs index 02b2ab74c..13c09f9d6 100644 --- a/rustfs/src/storage/rpc/disk.rs +++ b/rustfs/src/storage/rpc/disk.rs @@ -13,7 +13,7 @@ // limitations under the License. use super::*; -use crate::app::context::resolve_internode_metrics; +use crate::storage::runtime_sources; use rustfs_io_metrics::internode_metrics::{ INTERNODE_OPERATION_GRPC_READ_ALL, INTERNODE_OPERATION_GRPC_WRITE_ALL, INTERNODE_TRANSPORT_BACKEND_GRPC, }; @@ -934,7 +934,7 @@ impl NodeService { pub(super) async fn handle_write_all(&self, request: Request) -> Result, Status> { let request = request.into_inner(); let data_len = request.data.len(); - let metrics = resolve_internode_metrics(); + let metrics = runtime_sources::internode_metrics(); metrics.record_incoming_request_for_operation_and_backend( INTERNODE_OPERATION_GRPC_WRITE_ALL, INTERNODE_TRANSPORT_BACKEND_GRPC, @@ -974,7 +974,7 @@ impl NodeService { debug!("read all"); let request = request.into_inner(); - let metrics = resolve_internode_metrics(); + let metrics = runtime_sources::internode_metrics(); metrics.record_incoming_request_for_operation_and_backend( INTERNODE_OPERATION_GRPC_READ_ALL, INTERNODE_TRANSPORT_BACKEND_GRPC, diff --git a/rustfs/src/storage/rpc/health.rs b/rustfs/src/storage/rpc/health.rs index 92582a57d..68573855b 100644 --- a/rustfs/src/storage/rpc/health.rs +++ b/rustfs/src/storage/rpc/health.rs @@ -13,8 +13,8 @@ // limitations under the License. use super::*; -use crate::app::context::resolve_local_node_name; use crate::storage::rpc::encode_msgpack_map; +use crate::storage::runtime_sources; use rustfs_storage_api::StorageAdminApi; impl NodeService { @@ -22,7 +22,7 @@ impl NodeService { &self, _request: Request, ) -> Result, Status> { - let addr = resolve_local_node_name().await; + let addr = runtime_sources::local_node_name().await; let info = get_proc_info(&addr); match encode_msgpack_map(&info) { Ok(buf) => Ok(Response::new(GetProcInfoResponse { @@ -42,7 +42,7 @@ impl NodeService { &self, _request: Request, ) -> Result, Status> { - let addr = resolve_local_node_name().await; + let addr = runtime_sources::local_node_name().await; let info = get_mem_info(&addr); match encode_msgpack_map(&info) { Ok(buf) => Ok(Response::new(GetMemInfoResponse { @@ -62,7 +62,7 @@ impl NodeService { &self, _request: Request, ) -> Result, Status> { - let addr = resolve_local_node_name().await; + let addr = runtime_sources::local_node_name().await; let info = get_sys_errors(&addr); match encode_msgpack_map(&info) { Ok(buf) => Ok(Response::new(GetSysErrorsResponse { @@ -82,7 +82,7 @@ impl NodeService { &self, _request: Request, ) -> Result, Status> { - let addr = resolve_local_node_name().await; + let addr = runtime_sources::local_node_name().await; let info = get_sys_config(&addr); match encode_msgpack_map(&info) { Ok(buf) => Ok(Response::new(GetSysConfigResponse { @@ -102,7 +102,7 @@ impl NodeService { &self, _request: Request, ) -> Result, Status> { - let addr = resolve_local_node_name().await; + let addr = runtime_sources::local_node_name().await; let info = get_sys_services(&addr); match encode_msgpack_map(&info) { Ok(buf) => Ok(Response::new(GetSeLinuxInfoResponse { @@ -160,7 +160,7 @@ impl NodeService { &self, _request: Request, ) -> Result, Status> { - let addr = resolve_local_node_name().await; + let addr = runtime_sources::local_node_name().await; let info = get_net_info(&addr, ""); match encode_msgpack_map(&info) { Ok(buf) => Ok(Response::new(GetNetInfoResponse { diff --git a/rustfs/src/storage/rpc/http_service.rs b/rustfs/src/storage/rpc/http_service.rs index f004983a4..247a19879 100644 --- a/rustfs/src/storage/rpc/http_service.rs +++ b/rustfs/src/storage/rpc/http_service.rs @@ -17,9 +17,9 @@ use super::super::StorageDiskRpcExt as _; use super::super::WalkDirOptions; use super::super::find_local_disk_by_ref; use super::super::verify_rpc_signature; -use crate::app::context::resolve_internode_metrics; use crate::server::RPC_PREFIX; use crate::storage::request_context::spawn_traced; +use crate::storage::runtime_sources; use bytes::{Bytes, BytesMut}; use futures_util::TryStreamExt; use http::{HeaderMap, Method, Request, Response, StatusCode, Uri}; @@ -302,7 +302,7 @@ async fn handle_internode_rpc(req: Request) -> Response { } if let Some(operation) = operation { - resolve_internode_metrics().record_duration_for_operation_and_backend( + runtime_sources::internode_metrics().record_duration_for_operation_and_backend( operation, INTERNODE_TRANSPORT_BACKEND_TCP_HTTP, started_at.elapsed(), @@ -322,7 +322,7 @@ fn internode_http_operation(path: &str) -> Option<&'static str> { } fn record_internode_rpc_error(operation: Option<&'static str>) { - let metrics = resolve_internode_metrics(); + let metrics = runtime_sources::internode_metrics(); match operation { Some(operation) => metrics.record_error_for_operation_and_backend(operation, INTERNODE_TRANSPORT_BACKEND_TCP_HTTP), None => metrics.record_error(), @@ -410,7 +410,7 @@ async fn handle_read_file(req: Request) -> Response { } }; - resolve_internode_metrics().record_incoming_request_for_operation_and_backend( + runtime_sources::internode_metrics().record_incoming_request_for_operation_and_backend( INTERNODE_OPERATION_READ_FILE_STREAM, INTERNODE_TRANSPORT_BACKEND_TCP_HTTP, ); @@ -430,7 +430,7 @@ fn read_file_body_stream( where R: tokio::io::AsyncRead + Unpin + Send + Sync + 'static, { - let metrics = resolve_internode_metrics(); + let metrics = runtime_sources::internode_metrics(); let stream = ReaderStream::with_capacity(reader, DEFAULT_READ_BUFFER_SIZE).map_ok(move |bytes| { metrics.record_sent_bytes_for_operation_and_backend(operation, INTERNODE_TRANSPORT_BACKEND_TCP_HTTP, bytes.len()); bytes @@ -545,9 +545,9 @@ async fn handle_walk_dir(req: Request) -> Response { } }); - resolve_internode_metrics() + runtime_sources::internode_metrics() .record_incoming_request_for_operation_and_backend(INTERNODE_OPERATION_WALK_DIR, INTERNODE_TRANSPORT_BACKEND_TCP_HTTP); - let metrics = resolve_internode_metrics(); + let metrics = runtime_sources::internode_metrics(); let stream = ReaderStream::with_capacity(rd, DEFAULT_READ_BUFFER_SIZE).map_ok(move |bytes| { metrics.record_sent_bytes_for_operation_and_backend( INTERNODE_OPERATION_WALK_DIR, @@ -614,7 +614,7 @@ async fn handle_put_file(req: Request) -> Response { } }; - let metrics = resolve_internode_metrics(); + let metrics = runtime_sources::internode_metrics(); metrics.record_incoming_request_for_operation_and_backend( INTERNODE_OPERATION_PUT_FILE_STREAM, INTERNODE_TRANSPORT_BACKEND_TCP_HTTP, diff --git a/rustfs/src/storage/runtime_sources.rs b/rustfs/src/storage/runtime_sources.rs new file mode 100644 index 000000000..87b7fd85f --- /dev/null +++ b/rustfs/src/storage/runtime_sources.rs @@ -0,0 +1,62 @@ +// Copyright 2024 RustFS Team +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use crate::app::context; +use crate::config::RustFSBufferConfig; +use crate::storage::ECStore; +use rustfs_credentials::Credentials; +use rustfs_iam::{error::Result as IamResult, store::object::ObjectStore, sys::IamSys}; +use rustfs_io_metrics::{PerformanceMetrics, internode_metrics::InternodeMetrics}; +use rustfs_kms::ObjectEncryptionService; +use std::sync::Arc; + +pub(crate) fn object_store_handle() -> Option> { + context::resolve_object_store_handle() +} + +pub(crate) fn buffer_config() -> RustFSBufferConfig { + context::resolve_buffer_config() +} + +pub(crate) fn internode_metrics() -> Arc { + context::resolve_internode_metrics() +} + +pub(crate) async fn local_node_name() -> String { + context::resolve_local_node_name().await +} + +pub(crate) fn action_credentials() -> Option { + context::resolve_action_credentials() +} + +pub(crate) fn notify_interface() -> Arc { + context::resolve_notify_interface() +} + +pub(crate) fn performance_metrics() -> Arc { + context::resolve_performance_metrics() +} + +pub(crate) async fn encryption_service() -> Option> { + context::resolve_encryption_service().await +} + +pub(crate) fn region() -> Option { + context::resolve_region() +} + +pub(crate) fn ready_iam_handle() -> IamResult>> { + context::resolve_ready_iam_handle() +} diff --git a/rustfs/src/storage/sse.rs b/rustfs/src/storage/sse.rs index 5d17715f7..305168b20 100644 --- a/rustfs/src/storage/sse.rs +++ b/rustfs/src/storage/sse.rs @@ -70,7 +70,7 @@ //! ``` use super::StorageError; -use crate::app::context::resolve_encryption_service; +use crate::storage::runtime_sources; #[cfg(feature = "rio-v2")] use aes_gcm::aead::Payload; use aes_gcm::{ @@ -1533,7 +1533,7 @@ async fn apply_managed_encryption_material( let mut kms_key_candidate = kms_key_id.clone(); if kms_key_candidate.is_none() { // Try to get default key from KMS service (if available) - if let Some(service) = resolve_encryption_service().await { + if let Some(service) = runtime_sources::encryption_service().await { kms_key_candidate = service.get_default_key_id().cloned(); } } @@ -1626,7 +1626,7 @@ async fn apply_managed_decryption_material( .cloned() .unwrap_or_else(|| "AES256".to_string()), ) - } else if let Some(service) = resolve_encryption_service().await { + } else if let Some(service) = runtime_sources::encryption_service().await { // Production mode: use service for metadata parsing let parsed = service .headers_to_metadata(&normalized_metadata) @@ -1804,7 +1804,7 @@ impl KmsSseDekProvider { } async fn current_service() -> Option> { - resolve_encryption_service().await + runtime_sources::encryption_service().await } } @@ -2082,7 +2082,7 @@ static GLOBAL_SSE_DEK_PROVIDER: LazyLock>> /// .await?; /// ``` pub async fn get_sse_dek_provider() -> Result, ApiError> { - if resolve_encryption_service().await.is_some() { + if runtime_sources::encryption_service().await.is_some() { debug!("Using KmsSseDekProvider (KMS configured)"); return Ok(Arc::new(KmsSseDekProvider::new().await?)); } diff --git a/scripts/check_architecture_migration_rules.sh b/scripts/check_architecture_migration_rules.sh index e4f60b2f7..12e73212c 100755 --- a/scripts/check_architecture_migration_rules.sh +++ b/scripts/check_architecture_migration_rules.sh @@ -154,6 +154,8 @@ RUSTFS_WORKLOAD_DIRECT_FOREGROUND_MAPPING_HITS_FILE="${TMP_DIR}/rustfs_workload_ IAM_RUNTIME_SOURCE_BYPASS_HITS_FILE="${TMP_DIR}/iam_runtime_source_bypass_hits.txt" RUSTFS_APP_CONTEXT_RUNTIME_SOURCE_BYPASS_HITS_FILE="${TMP_DIR}/rustfs_app_context_runtime_source_bypass_hits.txt" RUSTFS_STARTUP_RUNTIME_SOURCE_BYPASS_HITS_FILE="${TMP_DIR}/rustfs_startup_runtime_source_bypass_hits.txt" +RUSTFS_SERVER_RUNTIME_SOURCE_BYPASS_HITS_FILE="${TMP_DIR}/rustfs_server_runtime_source_bypass_hits.txt" +RUSTFS_STORAGE_RUNTIME_SOURCE_BYPASS_HITS_FILE="${TMP_DIR}/rustfs_storage_runtime_source_bypass_hits.txt" awk ' /^## PR Types$/ { @@ -1336,6 +1338,40 @@ if [[ -s "$RUSTFS_STARTUP_RUNTIME_SOURCE_BYPASS_HITS_FILE" ]]; then report_failure "RustFS startup runtime globals must stay behind rustfs/src/startup_runtime_sources.rs: $(paste -sd '; ' "$RUSTFS_STARTUP_RUNTIME_SOURCE_BYPASS_HITS_FILE")" fi +( + cd "$ROOT_DIR" + rg -n --with-filename 'crate::app::context::(?:\{[^}]*\b(?:resolve_server_config|resolve_notify_interface|resolve_object_store_handle|resolve_kms_runtime_service_manager|resolve_iam_ready|resolve_endpoints_handle|resolve_lock_clients_handle)\b|(?:resolve_server_config|resolve_notify_interface|resolve_object_store_handle|resolve_kms_runtime_service_manager|resolve_iam_ready|resolve_endpoints_handle|resolve_lock_clients_handle)\b)' \ + rustfs/src/server/audit.rs \ + rustfs/src/server/event.rs \ + rustfs/src/server/layer.rs \ + rustfs/src/server/module_switch.rs \ + rustfs/src/server/readiness.rs \ + --glob '*.rs' || true +) >"$RUSTFS_SERVER_RUNTIME_SOURCE_BYPASS_HITS_FILE" + +if [[ -s "$RUSTFS_SERVER_RUNTIME_SOURCE_BYPASS_HITS_FILE" ]]; then + report_failure "RustFS server runtime source reads must stay behind rustfs/src/server/runtime_sources.rs: $(paste -sd '; ' "$RUSTFS_SERVER_RUNTIME_SOURCE_BYPASS_HITS_FILE")" +fi + +( + cd "$ROOT_DIR" + rg -n --with-filename 'crate::app::context::(?:\{[^}]*\b(?:resolve_object_store_handle|resolve_buffer_config|resolve_internode_metrics|resolve_local_node_name|resolve_action_credentials|resolve_notify_interface|resolve_performance_metrics|resolve_encryption_service|resolve_region|resolve_ready_iam_handle)\b|(?:resolve_object_store_handle|resolve_buffer_config|resolve_internode_metrics|resolve_local_node_name|resolve_action_credentials|resolve_notify_interface|resolve_performance_metrics|resolve_encryption_service|resolve_region|resolve_ready_iam_handle)\b)' \ + rustfs/src/storage/access.rs \ + rustfs/src/storage/ecfs.rs \ + rustfs/src/storage/ecfs_extend.rs \ + rustfs/src/storage/helper.rs \ + rustfs/src/storage/concurrency/manager.rs \ + rustfs/src/storage/sse.rs \ + rustfs/src/storage/rpc/disk.rs \ + rustfs/src/storage/rpc/health.rs \ + rustfs/src/storage/rpc/http_service.rs \ + --glob '*.rs' || true +) >"$RUSTFS_STORAGE_RUNTIME_SOURCE_BYPASS_HITS_FILE" + +if [[ -s "$RUSTFS_STORAGE_RUNTIME_SOURCE_BYPASS_HITS_FILE" ]]; then + report_failure "RustFS storage runtime source reads must stay behind rustfs/src/storage/runtime_sources.rs: $(paste -sd '; ' "$RUSTFS_STORAGE_RUNTIME_SOURCE_BYPASS_HITS_FILE")" +fi + ( cd "$ROOT_DIR" rg -n --with-filename 'rustfs_ecstore::api::' \ diff --git a/scripts/layer-dependency-baseline.txt b/scripts/layer-dependency-baseline.txt index 38de3d57e..d03031faf 100644 --- a/scripts/layer-dependency-baseline.txt +++ b/scripts/layer-dependency-baseline.txt @@ -46,35 +46,18 @@ dep|rustfs/src/init.rs|infra->app|crate::app::context::resolve_region dep|rustfs/src/init.rs|infra->interface|crate::admin dep|rustfs/src/protocols/client.rs|infra->app|crate::app::context::resolve_action_credentials dep|rustfs/src/protocols/client.rs|infra->interface|crate::storage::ecfs::FS -dep|rustfs/src/server/audit.rs|infra->app|crate::app::context::resolve_server_config -dep|rustfs/src/server/module_switch.rs|infra->app|crate::app::context::resolve_object_store_handle -dep|rustfs/src/server/event.rs|infra->app|crate::app::context::resolve_notify_interface -dep|rustfs/src/server/event.rs|infra->app|crate::app::context::resolve_server_config dep|rustfs/src/server/http.rs|infra->interface|crate::admin -dep|rustfs/src/server/layer.rs|infra->app|crate::app::context::resolve_kms_runtime_service_manager dep|rustfs/src/server/layer.rs|infra->interface|crate::admin::console::is_console_path dep|rustfs/src/server/layer.rs|infra->interface|crate::admin::handlers::health::HealthProbe dep|rustfs/src/server/layer.rs|infra->interface|crate::admin::handlers::health::build_health_response_parts -dep|rustfs/src/server/readiness.rs|infra->app|crate::app::context::resolve_endpoints_handle -dep|rustfs/src/server/readiness.rs|infra->app|crate::app::context::resolve_iam_ready -dep|rustfs/src/server/readiness.rs|infra->app|crate::app::context::resolve_lock_clients_handle -dep|rustfs/src/server/readiness.rs|infra->app|crate::app::context::resolve_object_store_handle -dep|rustfs/src/startup_bucket_metadata.rs|infra->app|crate::app::context::resolve_replication_pool_handle +dep|rustfs/src/server/runtime_sources.rs|infra->app|crate::app::context dep|rustfs/src/startup_iam.rs|infra->app|crate::app::context::AppContext -dep|rustfs/src/storage/ecfs_extend.rs|infra->app|crate::app::context::resolve_buffer_config dep|rustfs/src/storage/ecfs_extend.rs|infra->interface|crate::storage::ecfs::ListObjectUnorderedQuery dep|rustfs/src/storage/ecfs_test.rs|infra->interface|crate::storage::ecfs::FS dep|rustfs/src/storage/ecfs_test.rs|infra->interface|crate::storage::ecfs::validate_object_lock_configuration_input dep|rustfs/src/storage/ecfs_test.rs|infra->interface|crate::storage::s3_api::common::rustfs_initiator dep|rustfs/src/storage/ecfs_test.rs|infra->interface|crate::storage::s3_api::common::rustfs_owner -dep|rustfs/src/storage/access.rs|infra->app|crate::app::context::resolve_region -dep|rustfs/src/storage/concurrency/manager.rs|infra->app|crate::app::context::resolve_performance_metrics -dep|rustfs/src/storage/sse.rs|infra->app|crate::app::context::resolve_encryption_service -dep|rustfs/src/storage/helper.rs|infra->app|crate::app::context::resolve_action_credentials -dep|rustfs/src/storage/helper.rs|infra->app|crate::app::context::resolve_notify_interface -dep|rustfs/src/storage/rpc/disk.rs|infra->app|crate::app::context::resolve_internode_metrics -dep|rustfs/src/storage/rpc/health.rs|infra->app|crate::app::context::resolve_local_node_name -dep|rustfs/src/storage/rpc/http_service.rs|infra->app|crate::app::context::resolve_internode_metrics +dep|rustfs/src/storage/runtime_sources.rs|infra->app|crate::app::context dep|rustfs/src/storage/rpc/node_service.rs|infra->app|crate::app::context::AppContext dep|rustfs/src/storage/rpc/node_service.rs|infra->app|crate::app::context::get_global_app_context dep|rustfs/src/storage/rpc/node_service.rs|infra->app|crate::app::context::resolve_iam_handle