diff --git a/Cargo.lock b/Cargo.lock
index ad3076094f17..bf72d45a941f 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -6499,6 +6499,7 @@ dependencies = [
"humantime-serde",
"itertools 0.10.5",
"lazy_static",
+ "local-ip-address",
"once_cell",
"parking_lot 0.12.3",
"prometheus",
@@ -10892,6 +10893,7 @@ dependencies = [
"json5",
"jsonb",
"lazy_static",
+ "local-ip-address",
"log-query",
"loki-api",
"mime_guess",
diff --git a/Cargo.toml b/Cargo.toml
index 91b05578d101..f478eca843d3 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -135,6 +135,7 @@ humantime-serde = "1.1"
itertools = "0.10"
jsonb = { git = "https://github.com/databendlabs/jsonb.git", rev = "8c8d2fc294a39f3ff08909d60f718639cfba3875", default-features = false }
lazy_static = "1.4"
+local-ip-address = "0.6"
meter-core = { git = "https://github.com/GreptimeTeam/greptime-meter.git", rev = "a10facb353b41460eeb98578868ebf19c2084fac" }
mockall = "0.11.4"
moka = "0.12"
diff --git a/config/config.md b/config/config.md
index 759d34364c2c..a1f8b1e36230 100644
--- a/config/config.md
+++ b/config/config.md
@@ -214,7 +214,7 @@
| `http.body_limit` | String | `64MB` | HTTP request body limit.
The following units are supported: `B`, `KB`, `KiB`, `MB`, `MiB`, `GB`, `GiB`, `TB`, `TiB`, `PB`, `PiB`.
Set to 0 to disable limit. |
| `grpc` | -- | -- | The gRPC server options. |
| `grpc.addr` | String | `127.0.0.1:4001` | The address to bind the gRPC server. |
-| `grpc.hostname` | String | `127.0.0.1` | The hostname advertised to the metasrv,
and used for connections from outside the host |
+| `grpc.hostname` | String | `127.0.0.1:4001` | The hostname advertised to the metasrv,
and used for connections from outside the host |
| `grpc.runtime_size` | Integer | `8` | The number of server worker threads. |
| `grpc.tls` | -- | -- | gRPC server TLS options, see `mysql.tls` section. |
| `grpc.tls.mode` | String | `disable` | TLS mode. |
@@ -378,7 +378,7 @@
| `http.body_limit` | String | `64MB` | HTTP request body limit.
The following units are supported: `B`, `KB`, `KiB`, `MB`, `MiB`, `GB`, `GiB`, `TB`, `TiB`, `PB`, `PiB`.
Set to 0 to disable limit. |
| `grpc` | -- | -- | The gRPC server options. |
| `grpc.addr` | String | `127.0.0.1:3001` | The address to bind the gRPC server. |
-| `grpc.hostname` | String | `127.0.0.1` | The hostname advertised to the metasrv,
and used for connections from outside the host |
+| `grpc.hostname` | String | `127.0.0.1:3001` | The hostname advertised to the metasrv,
and used for connections from outside the host |
| `grpc.runtime_size` | Integer | `8` | The number of server worker threads. |
| `grpc.max_recv_message_size` | String | `512MB` | The maximum receive message size for gRPC server. |
| `grpc.max_send_message_size` | String | `512MB` | The maximum send message size for gRPC server. |
diff --git a/config/datanode.example.toml b/config/datanode.example.toml
index a329cb4f3aba..9d9ff5925dc5 100644
--- a/config/datanode.example.toml
+++ b/config/datanode.example.toml
@@ -59,7 +59,7 @@ body_limit = "64MB"
addr = "127.0.0.1:3001"
## The hostname advertised to the metasrv,
## and used for connections from outside the host
-hostname = "127.0.0.1"
+hostname = "127.0.0.1:3001"
## The number of server worker threads.
runtime_size = 8
## The maximum receive message size for gRPC server.
diff --git a/config/frontend.example.toml b/config/frontend.example.toml
index b8e6c5cd8b9e..ade1b9169a04 100644
--- a/config/frontend.example.toml
+++ b/config/frontend.example.toml
@@ -38,7 +38,7 @@ body_limit = "64MB"
addr = "127.0.0.1:4001"
## The hostname advertised to the metasrv,
## and used for connections from outside the host
-hostname = "127.0.0.1"
+hostname = "127.0.0.1:4001"
## The number of server worker threads.
runtime_size = 8
diff --git a/src/cmd/src/datanode.rs b/src/cmd/src/datanode.rs
index 3737b9266a7b..bb5948edfa61 100644
--- a/src/cmd/src/datanode.rs
+++ b/src/cmd/src/datanode.rs
@@ -276,7 +276,8 @@ impl StartCommand {
info!("Datanode options: {:#?}", opts);
let plugin_opts = opts.plugins;
- let opts = opts.component;
+ let mut opts = opts.component;
+ opts.grpc.detect_hostname();
let mut plugins = Plugins::new();
plugins::setup_datanode_plugins(&mut plugins, &plugin_opts, &opts)
.await
diff --git a/src/cmd/src/flownode.rs b/src/cmd/src/flownode.rs
index e629edf2510d..04950975549a 100644
--- a/src/cmd/src/flownode.rs
+++ b/src/cmd/src/flownode.rs
@@ -222,7 +222,8 @@ impl StartCommand {
info!("Flownode start command: {:#?}", self);
info!("Flownode options: {:#?}", opts);
- let opts = opts.component;
+ let mut opts = opts.component;
+ opts.grpc.detect_hostname();
// TODO(discord9): make it not optionale after cluster id is required
let cluster_id = opts.cluster_id.unwrap_or(0);
diff --git a/src/cmd/src/frontend.rs b/src/cmd/src/frontend.rs
index 36bd37a51980..264411943fea 100644
--- a/src/cmd/src/frontend.rs
+++ b/src/cmd/src/frontend.rs
@@ -268,7 +268,8 @@ impl StartCommand {
info!("Frontend options: {:#?}", opts);
let plugin_opts = opts.plugins;
- let opts = opts.component;
+ let mut opts = opts.component;
+ opts.grpc.detect_hostname();
let mut plugins = Plugins::new();
plugins::setup_frontend_plugins(&mut plugins, &plugin_opts, &opts)
.await
diff --git a/src/cmd/src/metasrv.rs b/src/cmd/src/metasrv.rs
index b97d0710a582..6af4e599e08f 100644
--- a/src/cmd/src/metasrv.rs
+++ b/src/cmd/src/metasrv.rs
@@ -272,7 +272,8 @@ impl StartCommand {
info!("Metasrv options: {:#?}", opts);
let plugin_opts = opts.plugins;
- let opts = opts.component;
+ let mut opts = opts.component;
+ opts.detect_server_addr();
let mut plugins = Plugins::new();
plugins::setup_metasrv_plugins(&mut plugins, &plugin_opts, &opts)
.await
diff --git a/src/cmd/src/standalone.rs b/src/cmd/src/standalone.rs
index e3675a7db7c1..d72ec5ef43fd 100644
--- a/src/cmd/src/standalone.rs
+++ b/src/cmd/src/standalone.rs
@@ -461,7 +461,8 @@ impl StartCommand {
let mut plugins = Plugins::new();
let plugin_opts = opts.plugins;
- let opts = opts.component;
+ let mut opts = opts.component;
+ opts.grpc.detect_hostname();
let fe_opts = opts.frontend_options();
let dn_opts = opts.datanode_options();
diff --git a/src/cmd/tests/load_config_test.rs b/src/cmd/tests/load_config_test.rs
index e142a0b4a689..c590e1965a7e 100644
--- a/src/cmd/tests/load_config_test.rs
+++ b/src/cmd/tests/load_config_test.rs
@@ -85,7 +85,9 @@ fn test_load_datanode_example_config() {
remote_write: Some(Default::default()),
..Default::default()
},
- grpc: GrpcOptions::default().with_addr("127.0.0.1:3001"),
+ grpc: GrpcOptions::default()
+ .with_addr("127.0.0.1:3001")
+ .with_hostname("127.0.0.1:3001"),
rpc_addr: Some("127.0.0.1:3001".to_string()),
rpc_hostname: Some("127.0.0.1".to_string()),
rpc_runtime_size: Some(8),
@@ -137,6 +139,7 @@ fn test_load_frontend_example_config() {
remote_write: Some(Default::default()),
..Default::default()
},
+ grpc: GrpcOptions::default().with_hostname("127.0.0.1:4001"),
..Default::default()
},
..Default::default()
@@ -154,6 +157,7 @@ fn test_load_metasrv_example_config() {
component: MetasrvOptions {
selector: SelectorType::default(),
data_home: "/tmp/metasrv/".to_string(),
+ server_addr: "127.0.0.1:3002".to_string(),
logging: LoggingOptions {
dir: "/tmp/greptimedb/logs".to_string(),
level: Some("info".to_string()),
diff --git a/src/meta-srv/Cargo.toml b/src/meta-srv/Cargo.toml
index b383607afe66..4804b3ba7186 100644
--- a/src/meta-srv/Cargo.toml
+++ b/src/meta-srv/Cargo.toml
@@ -45,6 +45,7 @@ humantime.workspace = true
humantime-serde.workspace = true
itertools.workspace = true
lazy_static.workspace = true
+local-ip-address.workspace = true
once_cell.workspace = true
parking_lot.workspace = true
prometheus.workspace = true
diff --git a/src/meta-srv/src/metasrv.rs b/src/meta-srv/src/metasrv.rs
index e688b25e04bd..93921cbdd6c8 100644
--- a/src/meta-srv/src/metasrv.rs
+++ b/src/meta-srv/src/metasrv.rs
@@ -142,11 +142,14 @@ pub struct MetasrvOptions {
pub backend: BackendImpl,
}
+const DEFAULT_METASRV_ADDR_PORT: &str = "3002";
+
impl Default for MetasrvOptions {
fn default() -> Self {
Self {
- bind_addr: "127.0.0.1:3002".to_string(),
- server_addr: "127.0.0.1:3002".to_string(),
+ bind_addr: format!("127.0.0.1:{}", DEFAULT_METASRV_ADDR_PORT),
+ // If server_addr is not set, the server will use the local ip address as the server address.
+ server_addr: String::new(),
store_addrs: vec!["127.0.0.1:2379".to_string()],
selector: SelectorType::default(),
use_memory_store: false,
@@ -184,6 +187,31 @@ impl Configurable for MetasrvOptions {
}
}
+impl MetasrvOptions {
+ /// Detect server address if `auto_server_addr` is true.
+ pub fn detect_server_addr(&mut self) {
+ if self.server_addr.is_empty() {
+ match local_ip_address::local_ip() {
+ Ok(ip) => {
+ let detected_addr = format!(
+ "{}:{}",
+ ip,
+ self.bind_addr
+ .split(':')
+ .nth(1)
+ .unwrap_or(DEFAULT_METASRV_ADDR_PORT)
+ );
+ info!("Using detected: {} as server address", detected_addr);
+ self.server_addr = detected_addr;
+ }
+ Err(e) => {
+ error!("Failed to detect local ip address: {}", e);
+ }
+ }
+ }
+ }
+}
+
pub struct MetasrvInfo {
pub server_addr: String,
}
diff --git a/src/meta-srv/src/mocks.rs b/src/meta-srv/src/mocks.rs
index 9611fcdd13df..2a621814f2d7 100644
--- a/src/meta-srv/src/mocks.rs
+++ b/src/meta-srv/src/mocks.rs
@@ -44,12 +44,32 @@ pub struct MockInfo {
pub async fn mock_with_memstore() -> MockInfo {
let kv_backend = Arc::new(MemoryKvBackend::new());
let in_memory = Arc::new(MemoryKvBackend::new());
- mock(Default::default(), kv_backend, None, None, Some(in_memory)).await
+ mock(
+ MetasrvOptions {
+ server_addr: "127.0.0.1:3002".to_string(),
+ ..Default::default()
+ },
+ kv_backend,
+ None,
+ None,
+ Some(in_memory),
+ )
+ .await
}
pub async fn mock_with_etcdstore(addr: &str) -> MockInfo {
let kv_backend = EtcdStore::with_endpoints([addr], 128).await.unwrap();
- mock(Default::default(), kv_backend, None, None, None).await
+ mock(
+ MetasrvOptions {
+ server_addr: "127.0.0.1:3002".to_string(),
+ ..Default::default()
+ },
+ kv_backend,
+ None,
+ None,
+ None,
+ )
+ .await
}
pub async fn mock(
diff --git a/src/meta-srv/src/service/heartbeat.rs b/src/meta-srv/src/service/heartbeat.rs
index 489afe41e8c2..ef3d30b4d933 100644
--- a/src/meta-srv/src/service/heartbeat.rs
+++ b/src/meta-srv/src/service/heartbeat.rs
@@ -194,6 +194,7 @@ mod tests {
use super::get_node_id;
use crate::metasrv::builder::MetasrvBuilder;
+ use crate::metasrv::MetasrvOptions;
#[tokio::test]
async fn test_ask_leader() {
@@ -201,6 +202,10 @@ mod tests {
let metasrv = MetasrvBuilder::new()
.kv_backend(kv_backend)
+ .options(MetasrvOptions {
+ server_addr: "127.0.0.1:3002".to_string(),
+ ..Default::default()
+ })
.build()
.await
.unwrap();
diff --git a/src/meta-srv/src/service/store.rs b/src/meta-srv/src/service/store.rs
index f9a970bca731..acbc090e5c89 100644
--- a/src/meta-srv/src/service/store.rs
+++ b/src/meta-srv/src/service/store.rs
@@ -306,6 +306,7 @@ mod tests {
#[tokio::test]
async fn test_batch_put() {
+ common_telemetry::init_default_ut_logging();
let metasrv = new_metasrv().await;
let mut req = BatchPutRequest::default();
diff --git a/src/servers/Cargo.toml b/src/servers/Cargo.toml
index 674cd3f7df05..75c68e7a76de 100644
--- a/src/servers/Cargo.toml
+++ b/src/servers/Cargo.toml
@@ -65,6 +65,7 @@ influxdb_line_protocol = { git = "https://github.com/evenyag/influxdb_iox", bran
itertools.workspace = true
jsonb.workspace = true
lazy_static.workspace = true
+local-ip-address.workspace = true
log-query.workspace = true
loki-api = "0.1"
mime_guess = "2.0"
diff --git a/src/servers/src/grpc.rs b/src/servers/src/grpc.rs
index d3198b46a83c..8225f7cd8cdd 100644
--- a/src/servers/src/grpc.rs
+++ b/src/servers/src/grpc.rs
@@ -65,11 +65,39 @@ pub struct GrpcOptions {
pub tls: TlsOption,
}
+impl GrpcOptions {
+ /// Detect hostname if `auto_hostname` is true.
+ pub fn detect_hostname(&mut self) {
+ if self.hostname.is_empty() {
+ match local_ip_address::local_ip() {
+ Ok(ip) => {
+ let detected_addr = format!(
+ "{}:{}",
+ ip,
+ self.addr
+ .split(':')
+ .nth(1)
+ .unwrap_or(DEFAULT_GRPC_ADDR_PORT)
+ );
+ info!("Using detected: {} as server address", detected_addr);
+ self.hostname = detected_addr;
+ }
+ Err(e) => {
+ error!("Failed to detect local ip address: {}", e);
+ }
+ }
+ }
+ }
+}
+
+const DEFAULT_GRPC_ADDR_PORT: &str = "4001";
+
impl Default for GrpcOptions {
fn default() -> Self {
Self {
- addr: "127.0.0.1:4001".to_string(),
- hostname: "127.0.0.1".to_string(),
+ addr: format!("127.0.0.1:{}", DEFAULT_GRPC_ADDR_PORT),
+ // If hostname is not set, the server will use the local ip address as the hostname.
+ hostname: String::new(),
max_recv_message_size: DEFAULT_MAX_GRPC_RECV_MESSAGE_SIZE,
max_send_message_size: DEFAULT_MAX_GRPC_SEND_MESSAGE_SIZE,
runtime_size: 8,
@@ -83,6 +111,11 @@ impl GrpcOptions {
self.addr = addr.to_string();
self
}
+
+ pub fn with_hostname(mut self, hostname: &str) -> Self {
+ self.hostname = hostname.to_string();
+ self
+ }
}
pub struct GrpcServer {
diff --git a/tests-integration/src/cluster.rs b/tests-integration/src/cluster.rs
index 83778da5bbc4..93664c2f19cd 100644
--- a/tests-integration/src/cluster.rs
+++ b/tests-integration/src/cluster.rs
@@ -185,6 +185,7 @@ impl GreptimeDbClusterBuilder {
max_metadata_value_size: None,
},
wal: self.metasrv_wal_config.clone(),
+ server_addr: "127.0.0.1:3002".to_string(),
..Default::default()
};
diff --git a/tests-integration/src/standalone.rs b/tests-integration/src/standalone.rs
index cc2458fa99cb..0b6a3774187c 100644
--- a/tests-integration/src/standalone.rs
+++ b/tests-integration/src/standalone.rs
@@ -45,6 +45,7 @@ use frontend::instance::builder::FrontendBuilder;
use frontend::instance::{FrontendInstance, Instance, StandaloneDatanodeManager};
use meta_srv::metasrv::{FLOW_ID_SEQ, TABLE_ID_SEQ};
use query::stats::StatementStatistics;
+use servers::grpc::GrpcOptions;
use servers::Mode;
use snafu::ResultExt;
@@ -291,6 +292,7 @@ impl GreptimeDbStandaloneBuilder {
procedure: procedure_config,
metadata_store: kv_backend_config,
wal: self.metasrv_wal_config.clone().into(),
+ grpc: GrpcOptions::default().with_hostname("127.0.0.1:4001"),
..StandaloneOptions::default()
};
diff --git a/tests-integration/src/test_util.rs b/tests-integration/src/test_util.rs
index 57ec7f6f86f9..3ac0332b50a7 100644
--- a/tests-integration/src/test_util.rs
+++ b/tests-integration/src/test_util.rs
@@ -349,7 +349,9 @@ pub(crate) fn create_datanode_opts(
providers,
store: default_store,
},
- grpc: GrpcOptions::default().with_addr(PEER_PLACEHOLDER_ADDR),
+ grpc: GrpcOptions::default()
+ .with_addr(PEER_PLACEHOLDER_ADDR)
+ .with_hostname(PEER_PLACEHOLDER_ADDR),
mode,
wal: wal_config,
..Default::default()
diff --git a/tests-integration/tests/http.rs b/tests-integration/tests/http.rs
index 8b252e71e48c..d2b469f8e4a8 100644
--- a/tests-integration/tests/http.rs
+++ b/tests-integration/tests/http.rs
@@ -850,7 +850,7 @@ is_strict_mode = false
[grpc]
addr = "127.0.0.1:4001"
-hostname = "127.0.0.1"
+hostname = "127.0.0.1:4001"
max_recv_message_size = "512MiB"
max_send_message_size = "512MiB"
runtime_size = 8
diff --git a/tests/conf/datanode-test.toml.template b/tests/conf/datanode-test.toml.template
index 3c999635d91c..d820babf5c7b 100644
--- a/tests/conf/datanode-test.toml.template
+++ b/tests/conf/datanode-test.toml.template
@@ -1,8 +1,6 @@
node_id = 1
mode = 'distributed'
require_lease_before_startup = true
-rpc_addr = '127.0.0.1:29410'
-rpc_hostname = '127.0.0.1'
rpc_runtime_size = 8
[wal]
diff --git a/tests/conf/frontend-test.toml.template b/tests/conf/frontend-test.toml.template
new file mode 100644
index 000000000000..983754e5894b
--- /dev/null
+++ b/tests/conf/frontend-test.toml.template
@@ -0,0 +1,3 @@
+[grpc]
+addr = "127.0.0.1:29401"
+hostname = "127.0.0.1:29401"
\ No newline at end of file
diff --git a/tests/runner/src/env.rs b/tests/runner/src/env.rs
index 7c35e79fbafa..7ca65b3a5f56 100644
--- a/tests/runner/src/env.rs
+++ b/tests/runner/src/env.rs
@@ -356,6 +356,8 @@ impl Env {
"--log-dir={}/greptimedb-frontend/logs",
self.sqlness_home.display()
),
+ "-c".to_string(),
+ self.generate_config_file(subcommand, db_ctx),
];
(
args,
@@ -456,6 +458,7 @@ impl Env {
"start".to_string(),
];
args.push(format!("--rpc-addr=127.0.0.1:2941{id}"));
+ args.push(format!("--rpc-hostname=127.0.0.1:2941{id}"));
args.push(format!("--http-addr=127.0.0.1:2943{id}"));
args.push(format!("--data-home={}", data_home.display()));
args.push(format!("--log-dir={}/logs", data_home.display()));
@@ -480,6 +483,7 @@ impl Env {
"start".to_string(),
];
args.push(format!("--rpc-addr=127.0.0.1:2968{id}"));
+ args.push(format!("--rpc-hostname=127.0.0.1:2968{id}"));
args.push(format!("--node-id={id}"));
args.push(format!(
"--log-dir={}/greptimedb-flownode/logs",