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())
+}