// 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::error::{Error, Result}; use manager::IamCache; use rustfs_ecstore::store::ECStore; use std::sync::{Arc, OnceLock}; use store::object::ObjectStore; use sys::IamSys; use tracing::{error, info, instrument}; pub mod cache; pub mod error; pub mod manager; pub mod store; pub mod sys; pub mod utils; static IAM_SYS: OnceLock>> = OnceLock::new(); #[instrument(skip(ecstore))] pub async fn init_iam_sys(ecstore: Arc) -> Result<()> { if IAM_SYS.get().is_some() { info!("IAM system already initialized, skipping."); return Ok(()); } info!("Starting IAM system initialization sequence..."); // 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 let iam_instance = Arc::new(IamSys::new(cache_manager)); // 4. Securely set the global singleton if IAM_SYS.set(iam_instance).is_err() { error!("Critical: Race condition detected during IAM initialization!"); return Err(Error::IamSysAlreadyInitialized); } info!("IAM system initialization completed successfully."); Ok(()) } #[inline] pub fn get() -> Result>> { let sys = IAM_SYS.get().map(Arc::clone).ok_or(Error::IamSysNotInitialized)?; // Double-check the internal readiness state. The OnceLock is only set // after initialization and data loading complete, so this is a defensive // guard to ensure callers never operate on a partially initialized system. if !sys.is_ready() { return Err(Error::IamSysNotInitialized); } Ok(sys) } pub fn get_global_iam_sys() -> Option>> { IAM_SYS.get().cloned() }