Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,6 @@ TOML_KEY_ENVVAR: Dict[str, Dict[str, str]] = {
"http-bind": "INFLUXDB3_HTTP_BIND_ADDR",
"node-id": "INFLUXDB3_NODE_IDENTIFIER_PREFIX",
"node-id-from-env": "INFLUXDB3_NODE_IDENTIFIER_FROM_ENV",
# Logging (no INFLUXDB3_ prefix)
"log-destination": "LOG_DESTINATION",
"log-filter": "LOG_FILTER",
"log-format": "LOG_FORMAT",
# Admin token recovery
"admin-token-recovery-http-bind": "INFLUXDB3_ADMIN_TOKEN_RECOVERY_HTTP_BIND_ADDR",
# Authorization
Expand All @@ -68,29 +64,29 @@ TOML_KEY_ENVVAR: Dict[str, Dict[str, str]] = {
"azure-storage-account": "AZURE_STORAGE_ACCOUNT",
# Google Cloud (GOOGLE_ prefix, not INFLUXDB3_)
"google-service-account": "GOOGLE_SERVICE_ACCOUNT",
# Object store (OBJECT_STORE_ prefix, not INFLUXDB3_)
"object-store-cache-endpoint": "OBJECT_STORE_CACHE_ENDPOINT",
"object-store-connection-limit": "OBJECT_STORE_CONNECTION_LIMIT",
"object-store-http2-only": "OBJECT_STORE_HTTP2_ONLY",
"object-store-http2-max-frame-size": "OBJECT_STORE_HTTP2_MAX_FRAME_SIZE",
"object-store-max-retries": "OBJECT_STORE_MAX_RETRIES",
"object-store-retry-timeout": "OBJECT_STORE_RETRY_TIMEOUT",
"object-store-tls-allow-insecure": "OBJECT_STORE_TLS_ALLOW_INSECURE",
"object-store-tls-ca": "OBJECT_STORE_TLS_CA",
# Object store
"object-store-cache-endpoint": "INFLUXDB3_OBJECT_STORE_CACHE_ENDPOINT",
"object-store-connection-limit": "INFLUXDB3_OBJECT_STORE_CONNECTION_LIMIT",
"object-store-http2-only": "INFLUXDB3_OBJECT_STORE_HTTP2_ONLY",
"object-store-http2-max-frame-size": "INFLUXDB3_OBJECT_STORE_HTTP2_MAX_FRAME_SIZE",
"object-store-max-retries": "INFLUXDB3_OBJECT_STORE_MAX_RETRIES",
"object-store-retry-timeout": "INFLUXDB3_OBJECT_STORE_RETRY_TIMEOUT",
"object-store-tls-allow-insecure": "INFLUXDB3_OBJECT_STORE_TLS_ALLOW_INSECURE",
"object-store-tls-ca": "INFLUXDB3_OBJECT_STORE_TLS_CA",
# Processing engine
"virtual-env-location": "VIRTUAL_ENV",
# WAL
"snapshotted-wal-files-to-keep": "INFLUXDB3_NUM_WAL_FILES_TO_KEEP",
# Tracing (TRACES_ prefix, not INFLUXDB3_)
"traces-exporter": "TRACES_EXPORTER",
"traces-exporter-jaeger-agent-host": "TRACES_EXPORTER_JAEGER_AGENT_HOST",
"traces-exporter-jaeger-agent-port": "TRACES_EXPORTER_JAEGER_AGENT_PORT",
"traces-exporter-jaeger-debug-name": "TRACES_EXPORTER_JAEGER_DEBUG_NAME",
"traces-exporter-jaeger-service-name": "TRACES_EXPORTER_JAEGER_SERVICE_NAME",
"traces-exporter-jaeger-trace-context-header-name": "TRACES_EXPORTER_JAEGER_TRACE_CONTEXT_HEADER_NAME",
"traces-jaeger-debug-name": "TRACES_EXPORTER_JAEGER_DEBUG_NAME",
"traces-jaeger-max-msgs-per-second": "TRACES_JAEGER_MAX_MSGS_PER_SECOND",
"traces-jaeger-tags": "TRACES_EXPORTER_JAEGER_TAGS",
# Tracing
"traces-exporter": "INFLUXDB3_TRACES_EXPORTER",
"traces-exporter-jaeger-agent-host": "INFLUXDB3_TRACES_EXPORTER_JAEGER_AGENT_HOST",
"traces-exporter-jaeger-agent-port": "INFLUXDB3_TRACES_EXPORTER_JAEGER_AGENT_PORT",
"traces-exporter-jaeger-debug-name": "INFLUXDB3_TRACES_EXPORTER_JAEGER_DEBUG_NAME",
"traces-exporter-jaeger-service-name": "INFLUXDB3_TRACES_EXPORTER_JAEGER_SERVICE_NAME",
"traces-exporter-jaeger-trace-context-header-name": "INFLUXDB3_TRACES_EXPORTER_JAEGER_TRACE_CONTEXT_HEADER_NAME",
"traces-jaeger-debug-name": "INFLUXDB3_TRACES_EXPORTER_JAEGER_DEBUG_NAME",
"traces-jaeger-max-msgs-per-second": "INFLUXDB3_TRACES_JAEGER_MAX_MSGS_PER_SECOND",
"traces-jaeger-tags": "INFLUXDB3_TRACES_EXPORTER_JAEGER_TAGS",
},
"core": {
# Core-specific mappings (currently none - all are in common)
Expand Down
4 changes: 2 additions & 2 deletions .circleci/packages/test_influxdb3-launcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -304,15 +304,15 @@ def test_core_flavor_mappings(self):
config_path = self._write_toml_config(
'object-store = "file"\n'
'http-bind = "0.0.0.0:8086"\n'
'log-filter = "info"\n'
'virtual-env-location = "/path/to/venv"\n'
)
env_vars = self.launcher.read_config_toml(config_path, "core")
self.assertEqual(
env_vars,
{
"INFLUXDB3_OBJECT_STORE": "file",
"INFLUXDB3_HTTP_BIND_ADDR": "0.0.0.0:8086",
"LOG_FILTER": "info",
"VIRTUAL_ENV": "/path/to/venv",
},
)

Expand Down
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ COPY docker/entrypoint.sh /usr/bin/entrypoint.sh

EXPOSE 8181

ENV LOG_FILTER=info
ENV INFLUXDB3_LOG_FILTER=info

ENTRYPOINT ["/usr/bin/entrypoint.sh"]

Expand Down
183 changes: 183 additions & 0 deletions influxdb3/src/env_compat.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
//! Backwards compatibility for environment variable names.
//!
//! This module provides aliasing from new INFLUXDB3_ prefixed environment
//! variables to their legacy unprefixed names, enabling backwards compatibility
//! while encouraging migration to the new naming convention.

use chrono::Utc;
use std::io::IsTerminal;

/// Print a warning message formatted like the logging system output.
///
/// This is used because these warnings are emitted before the logging system
/// is initialized, but we want consistent-looking output.
fn warn(message: &str) {
let now = Utc::now().format("%Y-%m-%dT%H:%M:%S%.6fZ");
if std::io::stderr().is_terminal() {
// Yellow WARN for TTY output
eprintln!("{now} \x1b[33m WARN\x1b[0m influxdb3::env_compat: {message}");
} else {
eprintln!("{now} WARN influxdb3::env_compat: {message}");
}
}

/// Mapping of (new_name, old_name) for environment variable aliases.
///
/// When the old name is set but the new name is not, we copy the value
/// to the new name and emit a deprecation warning.
const ENV_ALIASES: &[(&str, &str)] = &[
// Object Store generic
(
"INFLUXDB3_OBJECT_STORE_CONNECTION_LIMIT",
"OBJECT_STORE_CONNECTION_LIMIT",
),
(
"INFLUXDB3_OBJECT_STORE_HTTP2_ONLY",
"OBJECT_STORE_HTTP2_ONLY",
),
(
"INFLUXDB3_OBJECT_STORE_HTTP2_MAX_FRAME_SIZE",
"OBJECT_STORE_HTTP2_MAX_FRAME_SIZE",
),
(
"INFLUXDB3_OBJECT_STORE_REQUEST_TIMEOUT",
"OBJECT_STORE_REQUEST_TIMEOUT",
),
(
"INFLUXDB3_OBJECT_STORE_MAX_RETRIES",
"OBJECT_STORE_MAX_RETRIES",
),
(
"INFLUXDB3_OBJECT_STORE_RETRY_TIMEOUT",
"OBJECT_STORE_RETRY_TIMEOUT",
),
(
"INFLUXDB3_OBJECT_STORE_CACHE_ENDPOINT",
"OBJECT_STORE_CACHE_ENDPOINT",
),
(
"INFLUXDB3_OBJECT_STORE_TLS_ALLOW_INSECURE",
"OBJECT_STORE_TLS_ALLOW_INSECURE",
),
("INFLUXDB3_OBJECT_STORE_TLS_CA", "OBJECT_STORE_TLS_CA"),
// Logging (external crate: trogging)
("INFLUXDB3_LOG_FILTER", "LOG_FILTER"),
("INFLUXDB3_LOG_DESTINATION", "LOG_DESTINATION"),
("INFLUXDB3_LOG_FORMAT", "LOG_FORMAT"),
// Tracing (external crate: trace_exporters)
("INFLUXDB3_TRACES_EXPORTER", "TRACES_EXPORTER"),
(
"INFLUXDB3_TRACES_EXPORTER_JAEGER_AGENT_HOST",
"TRACES_EXPORTER_JAEGER_AGENT_HOST",
),
(
"INFLUXDB3_TRACES_EXPORTER_JAEGER_AGENT_PORT",
"TRACES_EXPORTER_JAEGER_AGENT_PORT",
),
(
"INFLUXDB3_TRACES_EXPORTER_JAEGER_SERVICE_NAME",
"TRACES_EXPORTER_JAEGER_SERVICE_NAME",
),
(
"INFLUXDB3_TRACES_EXPORTER_JAEGER_TRACE_CONTEXT_HEADER_NAME",
"TRACES_EXPORTER_JAEGER_TRACE_CONTEXT_HEADER_NAME",
),
(
"INFLUXDB3_TRACES_EXPORTER_JAEGER_DEBUG_NAME",
"TRACES_EXPORTER_JAEGER_DEBUG_NAME",
),
(
"INFLUXDB3_TRACES_EXPORTER_JAEGER_TAGS",
"TRACES_EXPORTER_JAEGER_TAGS",
),
(
"INFLUXDB3_TRACES_JAEGER_MAX_MSGS_PER_SECOND",
"TRACES_JAEGER_MAX_MSGS_PER_SECOND",
),
];

/// Copy deprecated environment variable values to their new prefixed names.
///
/// This function should be called BEFORE clap parsing to ensure backwards
/// compatibility. If both old and new names are set, the new name takes
/// precedence and a warning is emitted.
///
/// # Note
///
/// This function uses `eprintln!` for warnings because it runs before the
/// logging system is initialized.
pub(crate) fn copy_deprecated_env_aliases() {
for (new_name, old_name) in ENV_ALIASES {
let old_value = std::env::var(old_name);
let new_value = std::env::var(new_name);

match (old_value, new_value) {
(Ok(old_val), Err(_)) => {
// Old name is set, new name is not - copy and warn
warn(&format!(
"environment variable {old_name} is deprecated, use {new_name} instead"
));
// SAFETY: This is called single-threaded during startup in lib.rs::startup()
// before any threads are spawned (tokio runtime not yet initialized).
unsafe {
std::env::set_var(new_name, old_val);
}
}
(Ok(_), Ok(new_val)) => {
// Both are set - use new name, warn about old being ignored
warn(&format!(
"both {old_name} and {new_name} are set; using {new_name}, as {old_name} is deprecated"
));
// Copy new value to old name so external crates see it
unsafe {
std::env::set_var(old_name, new_val);
}
}
(Err(_), Ok(new_val)) => {
// Only new name is set - copy to old name so external crates see it
unsafe {
std::env::set_var(old_name, new_val);
}
}
(Err(_), Err(_)) => {
// Neither is set - no action needed
}
}
}
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn test_env_aliases_count() {
// Ensure we have all expected aliases:
// - 9 object store generic vars
// - 3 logging vars (trogging crate)
// - 8 tracing vars (trace_exporters crate)
assert_eq!(ENV_ALIASES.len(), 20);
}

#[test]
fn test_env_aliases_all_have_influxdb3_prefix() {
for (new_name, _old_name) in ENV_ALIASES {
assert!(
new_name.starts_with("INFLUXDB3_"),
"New name {} should start with INFLUXDB3_",
new_name
);
}
}

#[test]
fn test_env_aliases_old_names_dont_have_influxdb3_prefix() {
for (_new_name, old_name) in ENV_ALIASES {
assert!(
!old_name.starts_with("INFLUXDB3_"),
"Old name {} should not start with INFLUXDB3_",
old_name
);
}
}
}
2 changes: 1 addition & 1 deletion influxdb3/src/help/serve.txt
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ Examples
[env: INFLUXDB3_HTTP_BIND_ADDR=]
--log-filter <FILTER> Logs: filter directive
[default: info,iox_query::query_log=warn,influxdb3_query_executor::query_planner=warn]
[env: LOG_FILTER=]
[env: INFLUXDB3_LOG_FILTER=]
--tls-key <KEY_FILE> The path to the key file for TLS to be enabled
[env: INFLUXDB3_TLS_KEY=]
--tls-cert <CERT_FILE> The path to the cert file for TLS to be enabled
Expand Down
40 changes: 20 additions & 20 deletions influxdb3/src/help/serve_all.txt
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ Examples:
[env: INFLUXDB3_HTTP_BIND_ADDR=]
--log-filter <FILTER> Logs: filter directive
[default: info,iox_query::query_log=warn,
influxdb3_query_executor::enterprise=warn]
[env: LOG_FILTER=]
influxdb3_query_executor::query_planner=warn]
[env: INFLUXDB3_LOG_FILTER=]

{}
--tls-key <KEY_FILE> The path to the key file for TLS to be enabled
Expand Down Expand Up @@ -120,23 +120,23 @@ Examples:

{}
--object-store-connection-limit <LIMIT> Connection limit for network object stores [default: 16]
[env: OBJECT_STORE_CONNECTION_LIMIT=]
[env: INFLUXDB3_OBJECT_STORE_CONNECTION_LIMIT=]
--object-store-http2-only Force HTTP/2 for object stores
[env: OBJECT_STORE_HTTP2_ONLY=]
[env: INFLUXDB3_OBJECT_STORE_HTTP2_ONLY=]
--object-store-http2-max-frame-size <SIZE> HTTP/2 max frame size
[env: OBJECT_STORE_HTTP2_MAX_FRAME_SIZE=]
[env: INFLUXDB3_OBJECT_STORE_HTTP2_MAX_FRAME_SIZE=]
--object-store-max-retries <N> Max request retry attempts
[env: OBJECT_STORE_MAX_RETRIES=]
[env: INFLUXDB3_OBJECT_STORE_MAX_RETRIES=]
--object-store-retry-timeout <TIMEOUT> Max retry timeout
[env: OBJECT_STORE_RETRY_TIMEOUT=]
[env: INFLUXDB3_OBJECT_STORE_RETRY_TIMEOUT=]
--object-store-cache-endpoint <ENDPOINT> S3 compatible cache endpoint
[env: OBJECT_STORE_CACHE_ENDPOINT=]
[env: INFLUXDB3_OBJECT_STORE_CACHE_ENDPOINT=]
--object-store-tls-allow-insecure Skip TLS certificate verification for object storage.
WARNING: This is insecure and should only be used for testing
[env: OBJECT_STORE_TLS_ALLOW_INSECURE=]
[env: INFLUXDB3_OBJECT_STORE_TLS_ALLOW_INSECURE=]
--object-store-tls-ca <PATH> Path to custom CA certificate file (PEM format) for object storage.
Use when your object store uses a certificate signed by a private CA
[env: OBJECT_STORE_TLS_CA=]
[env: INFLUXDB3_OBJECT_STORE_TLS_CA=]

{}
--plugin-dir <DIR> Location of plugins
Expand Down Expand Up @@ -247,25 +247,25 @@ Examples:

{}
--log-destination <DEST> Logs: destination [default: stdout]
[env: LOG_DESTINATION=]
[env: INFLUXDB3_LOG_DESTINATION=]
--log-format <FORMAT> Logs: message format [default: full]
[env: LOG_FORMAT=]
[env: INFLUXDB3_LOG_FORMAT=]
--traces-exporter <TYPE> Tracing: exporter type [default: none]
[env: TRACES_EXPORTER=]
[env: INFLUXDB3_TRACES_EXPORTER=]
--traces-exporter-jaeger-agent-host <HOST> Jaeger agent hostname [default: 0.0.0.0]
[env: TRACES_EXPORTER_JAEGER_AGENT_HOST=]
[env: INFLUXDB3_TRACES_EXPORTER_JAEGER_AGENT_HOST=]
--traces-exporter-jaeger-agent-port <PORT> Jaeger agent port [default: 6831]
[env: TRACES_EXPORTER_JAEGER_AGENT_PORT=]
[env: INFLUXDB3_TRACES_EXPORTER_JAEGER_AGENT_PORT=]
--traces-exporter-jaeger-service-name <NAME> Jaeger service name [default: iox-conductor]
[env: TRACES_EXPORTER_JAEGER_SERVICE_NAME=]
[env: INFLUXDB3_TRACES_EXPORTER_JAEGER_SERVICE_NAME=]
--traces-exporter-jaeger-trace-context-header-name <NAME> Header for trace context [default: uber-trace-id]
[env: TRACES_EXPORTER_JAEGER_TRACE_CONTEXT_HEADER_NAME=]
[env: INFLUXDB3_TRACES_EXPORTER_JAEGER_TRACE_CONTEXT_HEADER_NAME=]
--traces-jaeger-debug-name <NAME> Header for force sampling [default: jaeger-debug-id]
[env: TRACES_EXPORTER_JAEGER_DEBUG_NAME=]
[env: INFLUXDB3_TRACES_EXPORTER_JAEGER_DEBUG_NAME=]
--traces-jaeger-tags <TAGS> Key-value pairs for tracing spans
[env: TRACES_EXPORTER_JAEGER_TAGS=]
[env: INFLUXDB3_TRACES_EXPORTER_JAEGER_TAGS=]
--traces-jaeger-max-msgs-per-second <N> Max messages per second [default: 1000]
[env: TRACES_JAEGER_MAX_MSGS_PER_SECOND=]
[env: INFLUXDB3_TRACES_JAEGER_MAX_MSGS_PER_SECOND=]


{}
Expand Down
6 changes: 6 additions & 0 deletions influxdb3/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ pub mod commands {
pub mod write;
}

mod env_compat;

enum ReturnCode {
Failure = 1,
}
Expand Down Expand Up @@ -148,6 +150,10 @@ pub fn startup(args: Vec<String>) -> Result<(), std::io::Error> {
// load all environment variables from .env before doing anything
load_dotenv();

// Copy deprecated environment variable aliases for backwards compatibility.
// Must be called BEFORE clap parsing so that old env var names still work.
env_compat::copy_deprecated_env_aliases();

// Handle printing help messages for each command so that we can have a custom
// output with both a help and help-all message. We have to disable the help
// flag and manually parse the os args here to check for both if the help flags
Expand Down
Loading