From 9afb36078c82b9b068245f0973693a225984217a Mon Sep 17 00:00:00 2001 From: jordan Date: Sat, 7 Mar 2026 03:14:53 -0700 Subject: [PATCH] fix: resolve DNS hostnames in STEMEDB_SEED_NODES for k8s headless service SocketAddr::parse() doesn't resolve DNS names. Use tokio::net::lookup_host for k8s pod DNS (stemedb-{0,1,2}.stemedb-headless.stemedb.svc:18182). --- crates/stemedb-cluster/src/bin/node.rs | 33 +++++++++++++++++++------- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/crates/stemedb-cluster/src/bin/node.rs b/crates/stemedb-cluster/src/bin/node.rs index edcac7b..060ef80 100644 --- a/crates/stemedb-cluster/src/bin/node.rs +++ b/crates/stemedb-cluster/src/bin/node.rs @@ -38,7 +38,8 @@ struct NodeConfig { } impl NodeConfig { - fn from_env() -> Self { + /// Load config from env, resolving DNS hostnames in seed nodes. + async fn from_env() -> Self { let api_addr = std::env::var("STEMEDB_NODE_API_ADDR") .unwrap_or_else(|_| "127.0.0.1:18181".to_string()) .parse() @@ -49,12 +50,28 @@ impl NodeConfig { .parse() .unwrap_or_else(|_| SocketAddr::from(([127, 0, 0, 1], 18182))); - let seed_nodes = std::env::var("STEMEDB_SEED_NODES") - .unwrap_or_default() - .split(',') - .filter(|s| !s.trim().is_empty()) - .filter_map(|s| s.trim().parse().ok()) - .collect(); + let raw_seeds = std::env::var("STEMEDB_SEED_NODES").unwrap_or_default(); + let mut seed_nodes = Vec::new(); + for entry in raw_seeds.split(',').filter(|s| !s.trim().is_empty()) { + let entry = entry.trim(); + // Try direct SocketAddr parse first (e.g., "10.0.0.1:18182") + if let Ok(addr) = entry.parse::() { + seed_nodes.push(addr); + } else { + // DNS hostname (e.g., "stemedb-0.stemedb-headless.stemedb.svc:18182") + match tokio::net::lookup_host(entry).await { + Ok(mut addrs) => { + if let Some(addr) = addrs.next() { + info!(seed = entry, resolved = %addr, "Resolved seed node"); + seed_nodes.push(addr); + } + } + Err(e) => { + info!(seed = entry, error = %e, "Failed to resolve seed (may not be up yet)"); + } + } + } + } let num_shards = std::env::var("STEMEDB_NUM_SHARDS").ok().and_then(|s| s.parse().ok()).unwrap_or(4); @@ -80,7 +97,7 @@ async fn main() -> Result<(), Box> { tracing_subscriber::registry().with(env_filter).with(tracing_subscriber::fmt::layer()).init(); - let config = NodeConfig::from_env(); + let config = NodeConfig::from_env().await; // Use stable NodeId (env var → hostname → random fallback) let node_id = stable_node_id();