diff --git a/crates/ecstore/src/bucket/lifecycle/bucket_lifecycle_ops.rs b/crates/ecstore/src/bucket/lifecycle/bucket_lifecycle_ops.rs index f0d325207..da445a219 100644 --- a/crates/ecstore/src/bucket/lifecycle/bucket_lifecycle_ops.rs +++ b/crates/ecstore/src/bucket/lifecycle/bucket_lifecycle_ops.rs @@ -891,7 +891,7 @@ impl TransitionState { tokio::spawn(async move { Self::inc_counter(&state.compensation_running_tasks); state.record_scanner_transition_state(); - let Some(api) = crate::global::resolve_object_store_handle() else { + let Some(api) = runtime_sources::object_store_handle() else { scheduled.lock().unwrap().remove(&bucket); Self::add_counter(&state.compensation_running_tasks, -1); state.record_scanner_transition_state(); @@ -1919,7 +1919,7 @@ pub async fn enqueue_immediate_expiry(oi: &ObjectInfo, src: LcEventSrc) { let Some(lifecycle) = runtime_sources::bucket_lifecycle_config(&oi.bucket).await else { return; }; - let Some(api) = crate::global::resolve_object_store_handle() else { + let Some(api) = runtime_sources::object_store_handle() else { return; }; diff --git a/crates/ecstore/src/bucket/metadata.rs b/crates/ecstore/src/bucket/metadata.rs index bc32a36fb..194153eb3 100644 --- a/crates/ecstore/src/bucket/metadata.rs +++ b/crates/ecstore/src/bucket/metadata.rs @@ -20,7 +20,7 @@ use crate::bucket::utils::deserialize; use crate::config::com::{read_config, save_config}; use crate::disk::BUCKET_META_PREFIX; use crate::error::{Error, Result}; -use crate::global::resolve_object_store_handle; +use crate::runtime_sources; use crate::store::ECStore; use byteorder::{BigEndian, ByteOrder, LittleEndian}; use rustfs_policy::policy::BucketPolicy; @@ -765,7 +765,7 @@ impl BucketMetadata { } pub async fn save(&mut self) -> Result<()> { - let Some(store) = resolve_object_store_handle() else { + let Some(store) = runtime_sources::object_store_handle() else { return Err(Error::other("errServerNotInitialized")); }; diff --git a/crates/ecstore/src/bucket/metadata_sys.rs b/crates/ecstore/src/bucket/metadata_sys.rs index 3a25ae382..8e7b5ec29 100644 --- a/crates/ecstore/src/bucket/metadata_sys.rs +++ b/crates/ecstore/src/bucket/metadata_sys.rs @@ -19,7 +19,7 @@ use crate::bucket::bucket_target_sys::BucketTargetSys; use crate::bucket::metadata::{BUCKET_LIFECYCLE_CONFIG, load_bucket_metadata_parse}; use crate::bucket::utils::{deserialize, is_meta_bucketname}; use crate::error::{Error, Result, is_err_bucket_not_found}; -use crate::global::{GLOBAL_Endpoints, is_dist_erasure, is_erasure, resolve_object_store_handle}; +use crate::runtime_sources; use crate::store::ECStore; use futures::future::join_all; use lazy_static::lazy_static; @@ -263,13 +263,9 @@ impl BucketMetadataSys { let _ = self.init_internal(buckets).await; } async fn init_internal(&self, buckets: Vec) -> Result<()> { - let count = { - if let Some(endpoints) = GLOBAL_Endpoints.get() { - endpoints.es_count() * 10 - } else { - return Err(Error::other("GLOBAL_Endpoints not init")); - } - }; + let count = runtime_sources::endpoint_erasure_set_count() + .map(|count| count * 10) + .ok_or_else(|| Error::other("GLOBAL_Endpoints not init"))?; let mut failed_buckets: HashSet = HashSet::new(); let mut buckets = buckets.as_slice(); @@ -288,7 +284,7 @@ impl BucketMetadataSys { let mut initialized = self.initialized.write().await; *initialized = true; - if is_dist_erasure().await { + if runtime_sources::setup_is_dist_erasure().await { // TODO: refresh_buckets_metadata_loop } @@ -406,7 +402,7 @@ impl BucketMetadataSys { } async fn update_and_parse(&mut self, bucket: &str, config_file: &str, data: Vec, parse: bool) -> Result { - let Some(store) = resolve_object_store_handle() else { + let Some(store) = runtime_sources::object_store_handle() else { return Err(Error::other("errServerNotInitialized")); }; @@ -417,7 +413,10 @@ impl BucketMetadataSys { let mut bm = match load_bucket_metadata_parse(store, bucket, parse).await { Ok(res) => res, Err(err) => { - if !is_erasure().await && !is_dist_erasure().await && is_err_bucket_not_found(&err) { + if !runtime_sources::setup_is_erasure().await + && !runtime_sources::setup_is_dist_erasure().await + && is_err_bucket_not_found(&err) + { BucketMetadata::new(bucket) } else { error!("load bucket metadata failed: {}", err); diff --git a/crates/ecstore/src/bucket/replication/replication_resyncer.rs b/crates/ecstore/src/bucket/replication/replication_resyncer.rs index 5fb014ec9..ea4b26396 100644 --- a/crates/ecstore/src/bucket/replication/replication_resyncer.rs +++ b/crates/ecstore/src/bucket/replication/replication_resyncer.rs @@ -28,7 +28,6 @@ use crate::config::com::save_config; use crate::disk::{BUCKET_META_PREFIX, RUSTFS_META_BUCKET}; use crate::error::{Error, Result, is_err_object_not_found, is_err_version_not_found}; use crate::event_notification::{EventArgs, send_event}; -use crate::global::resolve_object_store_handle; use crate::object_api::{GetObjectReader, ObjectInfo, ObjectOptions, PutObjReader}; use crate::runtime_sources; use crate::set_disk::get_lock_acquire_timeout; @@ -1758,7 +1757,7 @@ impl ObjectInfoExt for ObjectInfo { } pub async fn must_replicate(bucket: &str, object: &str, mopts: MustReplicateOptions) -> ReplicateDecision { - if resolve_object_store_handle().is_none() { + if runtime_sources::object_store_handle().is_none() { return ReplicateDecision::default(); } diff --git a/crates/ecstore/src/runtime_sources.rs b/crates/ecstore/src/runtime_sources.rs index 31ebb6525..dd4392e27 100644 --- a/crates/ecstore/src/runtime_sources.rs +++ b/crates/ecstore/src/runtime_sources.rs @@ -28,8 +28,8 @@ use crate::{ GLOBAL_BOOT_TIME, GLOBAL_EventNotifier, GLOBAL_IsErasureSD, GLOBAL_LOCAL_DISK_ID_MAP, GLOBAL_LOCAL_DISK_MAP, GLOBAL_LOCAL_DISK_SET_DRIVES, GLOBAL_LifecycleSys, GLOBAL_LocalNodeName, GLOBAL_RootDiskThreshold, GLOBAL_TierConfigMgr, TypeLocalDiskSetDrives, get_global_bucket_monitor, get_global_deployment_id, get_global_endpoints, - get_global_endpoints_opt, init_global_bucket_monitor, is_first_cluster_node_local, resolve_object_store_handle, - set_global_deployment_id, + get_global_endpoints_opt, init_global_bucket_monitor, is_dist_erasure, is_erasure, is_first_cluster_node_local, + resolve_object_store_handle, set_global_deployment_id, }, notification_sys::{NotificationSys, get_global_notification_sys}, store::ECStore, @@ -59,6 +59,10 @@ pub(crate) fn endpoint_pools() -> Option { get_global_endpoints_opt() } +pub(crate) fn endpoint_erasure_set_count() -> Option { + endpoint_pools().map(|endpoints| endpoints.es_count()) +} + pub(crate) fn endpoint_pool_is_local(pool_index: usize) -> bool { get_global_endpoints() .as_ref() @@ -70,6 +74,14 @@ pub(crate) async fn first_cluster_node_is_local() -> bool { is_first_cluster_node_local().await } +pub(crate) async fn setup_is_erasure() -> bool { + is_erasure().await +} + +pub(crate) async fn setup_is_dist_erasure() -> bool { + is_dist_erasure().await +} + pub(crate) async fn local_node_name() -> String { GLOBAL_LOCAL_NODE_NAME.read().await.clone() } diff --git a/crates/policy/src/policy/opa.rs b/crates/policy/src/policy/opa.rs index 5c90112dd..be2e033a8 100644 --- a/crates/policy/src/policy/opa.rs +++ b/crates/policy/src/policy/opa.rs @@ -77,7 +77,11 @@ fn check() -> Result<(), OpaConfigError> { Ok(()) } async fn validate(config: &Args) -> Result<(), OpaConfigError> { - let client = reqwest::Client::new(); + let client = reqwest::Client::builder() + .timeout(Duration::from_secs(5)) + .connect_timeout(Duration::from_secs(1)) + .build() + .map_err(OpaConfigError::Connection)?; match client.post(&config.url).send().await { Ok(resp) => { diff --git a/docs/architecture/migration-progress.md b/docs/architecture/migration-progress.md index 1fc38b1a9..03e936968 100644 --- a/docs/architecture/migration-progress.md +++ b/docs/architecture/migration-progress.md @@ -5,9 +5,9 @@ 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-owner-root-facade-source-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`. -- Based on: latest default branch after merge 3806. +- Branch: `overtrue/arch-ecstore-remaining-runtime-sources-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`. +- Based on: latest default branch after merge 3808. - PR type for this branch: `consumer-migration` - Runtime behavior changes: none. - Rust code changes: route replication pool, outbound TLS generation, runtime @@ -23,7 +23,9 @@ Status values: `[ ]` not started, `[~]` in progress, `[x]` complete, `[!]` block plus ECStore replication pool, replication stats, and event-host reads, plus ECStore lifecycle queue state, tier config, lifecycle config, deployment id, event-host reads, bucket monitor reads, replication worker pool reads, - config/tier first-node checks, and rebalance endpoint-locality checks, + config/tier first-node checks, rebalance endpoint-locality checks, bucket + metadata object-store reads, metadata endpoint/setup reads, lifecycle + object-store reads, and replication object-store readiness checks, 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 @@ -33,7 +35,7 @@ Status values: `[ ]` not started, `[~]` in progress, `[x]` complete, `[!]` block and storage owner thin bridge regressions, plus app context and notify event-bridge thin module regressions; accept the reviewed AppContext resolver reverse dependencies in the layer baseline. -- Docs changes: record the API-136 through API-192 owner facade cleanup. +- Docs changes: record the API-136 through API-193 owner facade cleanup. ## Phase 0 Tasks @@ -4794,6 +4796,21 @@ Status values: `[ ]` not started, `[~]` in progress, `[x]` complete, `[!]` block Rust risk scan, migration/layer guards, PR-before-push pre-commit quality gate, and three-expert review. +- [x] `API-193` Centralize remaining ECStore bucket runtime source reads. + - Do: route bucket metadata save/update, metadata system endpoint/setup + checks, lifecycle object-store lookups, and replication object-store + readiness checks through the ECStore-owned runtime-source module. + - Acceptance: bucket metadata, metadata system, lifecycle, and replication + resync code no longer import these runtime globals directly outside the + runtime-source boundary. + - Must preserve: metadata initialization fan-out, standalone bucket metadata + fallback, lifecycle compensation and immediate expiry behavior, and + replication readiness defaults. + - Verification: ECStore compile coverage, focused bucket/lifecycle scans, + formatting, diff hygiene, residual runtime-source scan, Rust risk scan, + migration/layer guards, PR-before-push quality gate, and three-expert + review. + ## Next PRs 1. `consumer-migration`: continue reducing direct global reads behind AppContext resolver boundaries. @@ -4802,6 +4819,9 @@ Status values: `[ ]` not started, `[~]` in progress, `[x]` complete, `[!]` block | Expert | Status | Notes | |---|---|---| +| Quality/architecture | pass | API-193 keeps remaining ECStore bucket metadata, lifecycle, and replication runtime reads behind the runtime-source boundary. | +| Migration preservation | pass | Metadata fan-out, standalone fallback, lifecycle compensation/expiry, and replication readiness defaults preserve existing behavior. | +| Testing/verification | pass | ECStore compile, focused scans, formatting, migration/layer guards, residual scan, Rust risk scan, and PR gate are planned for API-193. | | Quality/architecture | pass | API-192 keeps ECStore locality reads behind the runtime-source boundary without adding new public APIs. | | Migration preservation | pass | Rebalance local-pool selection plus config and tier first-node behavior preserve existing fallback semantics. | | Testing/verification | pass | ECStore compile, focused config/tier/rebalance tests, formatting, migration/layer guards, residual scan, Rust risk scan, and pre-commit planned before PR. |