mirror of
https://github.com/rustfs/rustfs.git
synced 2026-08-12 16:16:55 +00:00
refactor(iam): hand the built IAM system to the AppContext explicitly (#4624)
backlog#1052 S3, fourth slice. The AppContext's IamHandle already owned an Arc<IamSys>, but the value it held was read back from the process singleton after init — so a future second server's context would silently bind to the first server's IAM domain (credentials, policies, users all belong to a specific store's .rustfs.sys). - rustfs_iam gains build_iam_sys(store): construct an IAM system bound to a store without touching the singleton. init_iam_sys wraps it (build, publish first-wins, return the handle — previously Result<()>). - Startup threads the built handle: the inline bootstrap path passes the Arc it just created into ensure_startup_after_iam, which constructs the AppContext from the passed value instead of re-resolving the global. The deferred-recovery path resolves the freshly published global directly (context-first resolution cannot be used there: the AppContext does not exist yet — creating it is the finalizer's job; caught by the embedded deferred-IAM e2e). - IamHandle::is_ready() reports the held system's readiness instead of consulting the process singleton; the dead global re-resolver is removed. token_signing_key stays on the credentials global until S4. 157 iam tests + embedded e2e (basic + deferred recovery) green.
This commit is contained in:
+23
-15
@@ -163,9 +163,25 @@ pub(crate) async fn notify_iam_load_policy_mapping(
|
||||
static IAM_SYS: OnceLock<Arc<IamSys<ObjectStore>>> = OnceLock::new();
|
||||
static OIDC_SYS: OnceLock<Arc<OidcSys>> = OnceLock::new();
|
||||
|
||||
/// Build an IAM system bound to the given store without touching the process
|
||||
/// singleton (backlog#1052 S3): a per-server context can own the returned
|
||||
/// handle while the singleton keeps serving ambient readers.
|
||||
#[instrument(skip(ecstore))]
|
||||
pub async fn init_iam_sys(ecstore: Arc<IamStore>) -> Result<()> {
|
||||
if IAM_SYS.get().is_some() {
|
||||
pub async fn build_iam_sys(ecstore: Arc<IamStore>) -> Result<Arc<IamSys<ObjectStore>>> {
|
||||
// 1. Create the persistent storage adapter
|
||||
let storage_adapter = ObjectStore::new(ecstore);
|
||||
|
||||
// 2. Create the cache manager.
|
||||
// The `new` method now performs a blocking initial load from disk.
|
||||
let cache_manager = IamCache::new(storage_adapter).await?;
|
||||
|
||||
// 3. Construct the system interface
|
||||
Ok(Arc::new(IamSys::new(cache_manager)))
|
||||
}
|
||||
|
||||
#[instrument(skip(ecstore))]
|
||||
pub async fn init_iam_sys(ecstore: Arc<IamStore>) -> Result<Arc<IamSys<ObjectStore>>> {
|
||||
if let Some(existing) = IAM_SYS.get() {
|
||||
info!(
|
||||
event = EVENT_IAM_STATE,
|
||||
component = LOG_COMPONENT_IAM,
|
||||
@@ -173,7 +189,7 @@ pub async fn init_iam_sys(ecstore: Arc<IamStore>) -> Result<()> {
|
||||
state = "already_initialized",
|
||||
"IAM runtime already initialized"
|
||||
);
|
||||
return Ok(());
|
||||
return Ok(existing.clone());
|
||||
}
|
||||
|
||||
info!(
|
||||
@@ -184,18 +200,10 @@ pub async fn init_iam_sys(ecstore: Arc<IamStore>) -> Result<()> {
|
||||
"IAM runtime starting"
|
||||
);
|
||||
|
||||
// 1. Create the persistent storage adapter
|
||||
let storage_adapter = ObjectStore::new(ecstore);
|
||||
let iam_instance = build_iam_sys(ecstore).await?;
|
||||
|
||||
// 2. Create the cache manager.
|
||||
// The `new` method now performs a blocking initial load from disk.
|
||||
let cache_manager = IamCache::new(storage_adapter).await?;
|
||||
|
||||
// 3. Construct the system interface
|
||||
let iam_instance = Arc::new(IamSys::new(cache_manager));
|
||||
|
||||
// 4. Securely set the global singleton
|
||||
if IAM_SYS.set(iam_instance).is_err() {
|
||||
// Securely set the global singleton
|
||||
if IAM_SYS.set(iam_instance.clone()).is_err() {
|
||||
error!(
|
||||
event = EVENT_IAM_STATE,
|
||||
component = LOG_COMPONENT_IAM,
|
||||
@@ -213,7 +221,7 @@ pub async fn init_iam_sys(ecstore: Arc<IamStore>) -> Result<()> {
|
||||
state = "ready",
|
||||
"IAM runtime ready"
|
||||
);
|
||||
Ok(())
|
||||
Ok(iam_instance)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
||||
Reference in New Issue
Block a user