Add env variable alias compatibility warnings (#2044)

This commit is contained in:
安正超
2026-03-02 15:34:19 +08:00
committed by GitHub
parent 2cb8db36a5
commit 01a75b5f58
9 changed files with 139 additions and 23 deletions
+18
View File
@@ -32,6 +32,24 @@
For comprehensive documentation, examples, and usage guides, please visit the main [RustFS repository](https://github.com/rustfs/rustfs).
## Environment Variable Naming Conventions
RustFS uses a flat naming style for top-level configuration: environment variables are `RUSTFS_*` without nested module segments.
Examples:
- `RUSTFS_REGION`
- `RUSTFS_ADDRESS`
- `RUSTFS_VOLUMES`
- `RUSTFS_LICENSE`
Current guidance:
- Prefer module-specific names only when they are not top-level product configuration.
- Renamed variables must keep backward-compatible aliases until before beta.
- Alias usage must emit deprecation warnings and be treated as transitional only.
- Deprecated example:
- `RUSTFS_ENABLE_SCANNER` -> `RUSTFS_SCANNER_ENABLED`
- `RUSTFS_ENABLE_HEAL` -> `RUSTFS_HEAL_ENABLED`
## 📄 License
This project is licensed under the Apache License 2.0 - see the [LICENSE](../../LICENSE) file for details.
+9
View File
@@ -128,6 +128,9 @@ pub const RUSTFS_LICENSE_URL: &str = "https://www.apache.org/licenses/LICENSE-2.
/// Example: RUSTFS_ADDRESS=":9000"
pub const ENV_RUSTFS_ADDRESS: &str = "RUSTFS_ADDRESS";
/// Environment variable for server volumes.
pub const ENV_RUSTFS_VOLUMES: &str = "RUSTFS_VOLUMES";
/// Default port for rustfs
/// This is the default port for rustfs.
/// This is used to bind the server to a specific port.
@@ -153,6 +156,12 @@ pub const DEFAULT_CONSOLE_ADDRESS: &str = concat!(":", DEFAULT_CONSOLE_PORT);
/// Default value: us-east-1
pub const RUSTFS_REGION: &str = "us-east-1";
/// Environment variable for server region.
pub const ENV_RUSTFS_REGION: &str = "RUSTFS_REGION";
/// Environment variable for server license.
pub const ENV_RUSTFS_LICENSE: &str = "RUSTFS_LICENSE";
/// Default log filename for rustfs
/// This is the default log filename for rustfs.
/// It is used to store the logs of the application.
@@ -13,7 +13,8 @@
// limitations under the License.
//! Disabled lock manager that bypasses all locking operations
//! Used when RUSTFS_ENABLE_LOCKS environment variable is set to false
//! Used when the lock feature is disabled via RUSTFS_LOCK_ENABLED
//! (or deprecated RUSTFS_ENABLE_LOCKS).
use std::sync::Arc;
+25 -5
View File
@@ -69,8 +69,12 @@ pub const BUILD_TIMESTAMP: &str = "unknown";
/// Maximum number of items in delete list
pub const MAX_DELETE_LIST: usize = 1000;
/// Default setting for RUSTFS_ENABLE_LOCKS environment variable
/// Default setting for lock enablement.
/// Canonical variable: RUSTFS_LOCK_ENABLED
/// Deprecated compatibility alias: RUSTFS_ENABLE_LOCKS
const DEFAULT_RUSTFS_LOCKS_ENABLED: bool = true;
const ENV_LOCK_ENABLED: &str = "RUSTFS_LOCK_ENABLED";
const ENV_LOCK_ENABLED_DEPRECATED: &str = "RUSTFS_ENABLE_LOCKS";
// ============================================================================
// Global FastLock Manager
@@ -97,10 +101,26 @@ impl Default for GlobalLockManager {
impl GlobalLockManager {
/// Create a lock manager based on environment variable configuration
pub fn new() -> Self {
// Check RUSTFS_ENABLE_LOCKS environment variable
let locks_enabled = rustfs_utils::get_env_bool("RUSTFS_ENABLE_LOCKS", DEFAULT_RUSTFS_LOCKS_ENABLED);
// Check lock enablement env vars with deprecated compatibility support.
let locks_enabled = rustfs_utils::get_env_bool_with_aliases(
ENV_LOCK_ENABLED,
&[ENV_LOCK_ENABLED_DEPRECATED],
DEFAULT_RUSTFS_LOCKS_ENABLED,
);
if !locks_enabled {
tracing::info!("Lock system disabled via RUSTFS_ENABLE_LOCKS environment variable");
let disabled_by = if std::env::var(ENV_LOCK_ENABLED).is_ok() {
ENV_LOCK_ENABLED
} else if std::env::var(ENV_LOCK_ENABLED_DEPRECATED).is_ok() {
ENV_LOCK_ENABLED_DEPRECATED
} else {
"default setting"
};
if disabled_by == "default setting" {
tracing::info!("Lock system disabled via default setting");
} else {
tracing::info!("Lock system disabled via {} environment variable", disabled_by);
}
return Self::Disabled(DisabledLockManager::new());
}
tracing::info!("Lock system enabled");
@@ -248,7 +268,7 @@ static GLOBAL_LOCK_MANAGER: OnceLock<Arc<GlobalLockManager>> = OnceLock::new();
/// Get the global shared lock manager instance
///
/// Returns either FastObjectLockManager or DisabledLockManager based on
/// the RUSTFS_ENABLE_LOCKS environment variable.
/// the RUSTFS_LOCK_ENABLED environment variable.
pub fn get_global_lock_manager() -> Arc<GlobalLockManager> {
GLOBAL_LOCK_MANAGER.get_or_init(|| Arc::new(GlobalLockManager::new())).clone()
}
+65 -4
View File
@@ -12,7 +12,12 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use std::env;
use std::{
collections::HashSet,
env,
sync::{Mutex, OnceLock},
};
use tracing::warn;
/// Retrieve an environment variable as a specific type, with a default value if not set or parsing fails.
/// 8-bit type: signed i8
@@ -68,6 +73,56 @@ pub fn get_env_opt_u8(key: &str) -> Option<u8> {
env::var(key).ok().and_then(|v| v.parse().ok())
}
static WARNED_ENV_MESSAGES: OnceLock<Mutex<HashSet<String>>> = OnceLock::new();
fn log_once(key: &str, message: impl FnOnce() -> String) {
let seen = WARNED_ENV_MESSAGES.get_or_init(|| Mutex::new(HashSet::new()));
let mut seen = match seen.lock() {
Ok(seen) => seen,
Err(poisoned) => poisoned.into_inner(),
};
if seen.insert(key.to_string()) {
warn!("{}", message());
}
}
fn resolve_env_with_aliases(key: &str, deprecated: &[&str]) -> Option<(String, String)> {
if let Ok(value) = env::var(key) {
return Some((key.to_string(), value));
}
let (alias, value) = deprecated
.iter()
.find_map(|alias| env::var(alias).ok().map(|value| (*alias, value)))?;
let deprecated_key = format!("env_alias:{alias}->{key}");
log_once(&deprecated_key, || {
format!("Environment variable {alias} is deprecated, use {key} instead")
});
Some((alias.to_string(), value))
}
pub fn get_env_str_with_aliases(key: &str, deprecated: &[&str], default: &str) -> String {
resolve_env_with_aliases(key, deprecated).map_or_else(|| default.to_string(), |(_, value)| value)
}
pub fn get_env_bool_with_aliases(key: &str, deprecated: &[&str], default: bool) -> bool {
let Some((used_key, value)) = resolve_env_with_aliases(key, deprecated) else {
return default;
};
parse_bool_str(&value).unwrap_or_else(|| {
log_once(
&format!("env_invalid_bool:{used_key}"),
|| {
format!(
"Invalid bool value for {used_key}: {value}. Supported values are true/false,1/0,yes/no,on/off. Treating as unset."
)
},
);
default
})
}
/// Retrieve an environment variable as a specific type, with a default value if not set or parsing fails.
/// 16-bit type: signed i16
///
@@ -338,7 +393,7 @@ pub fn get_env_opt_usize(key: &str) -> Option<usize> {
/// - `String`: The environment variable value if set, otherwise the default value.
///
pub fn get_env_str(key: &str, default: &str) -> String {
env::var(key).unwrap_or_else(|_| default.to_string())
get_env_str_with_aliases(key, &[], default)
}
/// Retrieve an environment variable as a String, returning None if not set.
@@ -363,7 +418,7 @@ pub fn get_env_opt_str(key: &str) -> Option<String> {
/// - `bool`: The parsed boolean value if successful, otherwise the default value.
///
pub fn get_env_bool(key: &str, default: bool) -> bool {
env::var(key).ok().and_then(|v| parse_bool_str(&v)).unwrap_or(default)
get_env_bool_with_aliases(key, &[], default)
}
/// Parse a string into a boolean value.
@@ -391,5 +446,11 @@ fn parse_bool_str(s: &str) -> Option<bool> {
/// - `Option<bool>`: The parsed boolean value if successful, otherwise None.
///
pub fn get_env_opt_bool(key: &str) -> Option<bool> {
env::var(key).ok().and_then(|v| parse_bool_str(&v))
let (used_key, value) = resolve_env_with_aliases(key, &[])?;
parse_bool_str(&value).or_else(|| {
log_once(&format!("env_invalid_bool_optional:{used_key}"), || {
format!("Invalid bool value for {used_key}: {value}. Supported values are true/false,1/0,yes/no,on/off.")
});
None
})
}