6.4 KiB
Config Model Boundary ADR
Related issue: rustfs/backlog#660
Task: CFG-002
Decision
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.
Why rustfs-config
rustfs-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.
Allowed Dependencies
The server-config model module may use only:
std::collections::HashMapstd::sync::{LazyLock, OnceLock, RwLock}for the defaultKVSregistration surface and process-global server-config snapshotserdeforKVandKVSserialization compatibilityserde_jsonforConfig::marshalandConfig::unmarshal- existing
rustfs-configconstants and subsystem modules
If 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.
Forbidden Dependencies
The model module must not depend on:
rustfs-ecstorerustfsStorageAPIor object persistence helpers- notify, audit, targets, IAM, scanner, KMS, or admin handler crates
- async runtimes, HTTP/router crates, object-store crates, or runtime lifecycle state
- unrelated runtime global state outside the process-global server-config snapshot
ConfigSys,read_config_without_migrate,save_server_config, or anycom.rspersistence helper
Boundary Split
Move in the first extraction:
KVKVSConfigDEFAULT_KVSregister_default_kvsConfig::newConfig::get_valueConfig::set_defaultsConfig::marshalConfig::unmarshalConfig::merge
Keep in ecstore:
ConfigSysinit_global_config_systry_migrate_server_configread_config_without_migratesave_server_config- generic
com.rsconfig-object helpers - storage-class runtime global state
Keep 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_config
The temporary ECStore compatibility re-export for these accessors was removed
after code scans showed in-repo consumers use rustfs_config::server_config
directly.
Required Shape Preservation
The extraction PR must preserve:
KV { key, value, hidden_if_empty }#[serde(default, alias = "hiddenIfEmpty")]onKV::hidden_if_emptyKVS(pub Vec<KV>)Config(pub HashMap<String, HashMap<String, KVS>>)KVS::new,get,lookup,is_empty,keys,insert, andextendConfig::new,get_value,set_defaults,marshal,unmarshal, andmergeConfig::new()default application afterecstore::config::init()- existing persisted server-config JSON shape
- existing target, notify, audit, scanner, OIDC, and admin interpretation of
ConfigandKVS
Next PR Requirements
CFG-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.
Verification Gate
Before pushing an extraction PR, run:
- serde roundtrip tests for old and new paths
- tests for
hiddenIfEmptyalias compatibility - tests for
KVSinsertion, lookup, extension, and keys behavior - tests for
Config::new,set_defaults,marshal,unmarshal, andmerge - a cleanup scan proving in-repo consumers no longer use the old
rustfs_ecstore::config::{Config, KV, KVS}model path before removing the compatibility shim cargo tree -p rustfs-config --edges normalcargo tree -p rustfs-ecstore --edges normal./scripts/check_layer_dependencies.sh./scripts/check_architecture_migration_rules.sh./scripts/check_metrics_migration_refs.shcargo fmt --all --checkmake pre-commit
Non-Goals
- No consumer migration in
CFG-002. - No code movement in
CFG-002. - No new crate in
CFG-002. - No
com.rsorStorageAPImovement in the first model extraction. - No global server-config state migration until the model path is stable.