docs/architecture/config-model-boundary-adr.md
Related issue: rustfs/backlog#660
Task: CFG-002
Use the existing crates/config package (rustfs-config) as the target owner
for the pure server-config model. Do not create a new config-model crate for
the first extraction.
The next model extraction PR should introduce the model under:
crates/config/src/server_config.rs
The exported path should be:
rustfs_config::server_config::{Config, KV, KVS}
The extraction kept the existing path available through a temporary compatibility re-export:
rustfs_ecstore::config::{Config, KV, KVS}
That re-export included RUSTFS_COMPAT_TODO(CFG-004) and a matching entry in
compat-cleanup-register.md until the model
consumers were migrated. The CFG-004 cleanup removed this old model path after
code scans showed consumers import the model directly from rustfs-config.
Follow-up CFG-008 moved the process-global server-config snapshot accessors
to rustfs_config::server_config after the model path stabilized. Its temporary
rustfs_ecstore::config::{get_global_server_config, set_global_server_config}
compatibility re-export was removed after in-repo runtime consumers migrated to
the rustfs-config owner.
rustfs-configrustfs-config is already the lowest RustFS crate for configuration constants
and subsystem identifiers used by ECStore, notify, audit, targets, scanner, IAM,
and admin code. The current ecstore::config::{Config, KV, KVS} model already
uses rustfs-config constants, so moving the pure model upward to
rustfs-config cuts the wrong dependency direction without adding another crate.
Creating a new crate now would add a second config namespace before consumers are migrated. That would increase re-export and compatibility surface while not removing any storage or runtime dependency by itself.
The server-config model module may use only:
std::collections::HashMapstd::sync::{LazyLock, OnceLock, RwLock} for the default KVS registration
surface and process-global server-config snapshotserde for KV and KVS serialization compatibilityserde_json for Config::marshal and Config::unmarshalrustfs-config constants and subsystem modulesIf serde and serde_json are added to rustfs-config, they should be attached
only to a model feature such as server-config-model unless the implementation
PR proves that making them non-optional is simpler and harmless for downstream
builds.
The model module must not depend on:
rustfs-ecstorerustfsStorageAPI or object persistence helpersConfigSys, read_config_without_migrate, save_server_config, or any
com.rs persistence helperMove in the first extraction:
KVKVSConfigDEFAULT_KVSregister_default_kvsConfig::newConfig::get_valueConfig::set_defaultsConfig::marshalConfig::unmarshalConfig::mergeKeep in ecstore:
ConfigSysinit_global_config_systry_migrate_server_configread_config_without_migratesave_server_configcom.rs config-object helpersKeep default registration wiring in ecstore::config::init until a later PR
extracts a dedicated default-registration contract. The values may be registered
through the moved rustfs_config::server_config::register_default_kvs, but the
startup order and caller remain unchanged.
Move in CFG-008:
GLOBAL_SERVER_CONFIGget_global_server_configset_global_server_configThe temporary ECStore compatibility re-export for these accessors was removed
after code scans showed in-repo consumers use rustfs_config::server_config
directly.
The extraction PR must preserve:
KV { key, value, hidden_if_empty }#[serde(default, alias = "hiddenIfEmpty")] on KV::hidden_if_emptyKVS(pub Vec<KV>)Config(pub HashMap<String, HashMap<String, KVS>>)KVS::new, get, lookup, is_empty, keys, insert, and extendConfig::new, get_value, set_defaults, marshal, unmarshal, and
mergeConfig::new() default application after ecstore::config::init()Config and KVSCFG-003 should be a pure model extraction or narrow api-extraction PR. It
must not migrate consumers, change persistence helpers, or alter runtime
behavior.
CFG-004 kept the old rustfs_ecstore::config::* path as a temporary
compatibility shim, registered its removal condition, and removed the shim after
all in-repo consumers migrated.
CFG-005 should migrate external consumers one group at a time after the model
and compatibility path are stable.
CFG-008 moves only the global server-config snapshot accessors to
rustfs-config and migrates in-repo direct consumers. It must not move
ConfigSys, storage-class global state, persistence helpers, default
registration wiring, startup order, or storage behavior.
Before pushing an extraction PR, run:
hiddenIfEmpty alias compatibilityKVS insertion, lookup, extension, and keys behaviorConfig::new, set_defaults, marshal, unmarshal, and mergerustfs_ecstore::config::{Config, KV, KVS} model path before removing the
compatibility shimcargo tree -p rustfs-config --edges normalcargo tree -p rustfs-ecstore --edges normal./scripts/check_layer_dependencies.sh./scripts/check_architecture_migration_rules.shcargo fmt --all --checkmake pre-commitCFG-002.CFG-002.CFG-002.com.rs or StorageAPI movement in the first model extraction.