feat: add local IP address retrieval and update console address default

This commit is contained in:
DamonXue
2025-03-02 17:40:36 +08:00
parent 68a9936566
commit 79eabe4e4c
7 changed files with 214 additions and 119 deletions
+1
View File
@@ -74,6 +74,7 @@ jsonwebtoken = "9.3.0"
tower-http = { version = "0.6.2", features = ["cors"] }
mime_guess = "2.0.5"
rust-embed = { version = "8.5.0", features = ["interpolate-folder-path"] }
local-ip-address = "0.6.3"
[build-dependencies]
prost-build.workspace = true
+1 -1
View File
@@ -60,6 +60,6 @@ pub struct Opt {
#[arg(long, default_value_t = false, env = "RUSTFS_CONSOLE_ENABLE")]
pub console_enable: bool,
#[arg(long, default_value_t = format!("127.0.0.1:{}", 0), env = "RUSTFS_CONSOLE_ADDRESS")]
#[arg(long, default_value_t = format!("127.0.0.1:{}", 9002), env = "RUSTFS_CONSOLE_ADDRESS")]
pub console_address: String,
}
+29 -16
View File
@@ -6,11 +6,13 @@ use axum::{
Router,
};
use const_str::concat;
use mime_guess::from_path;
use rust_embed::RustEmbed;
use serde::Serialize;
use shadow_rs::shadow;
use tracing::info;
use std::net::Ipv4Addr;
use std::sync::OnceLock;
shadow!(build);
@@ -103,19 +105,27 @@ struct License {
url: String,
}
#[allow(clippy::const_is_empty)]
async fn config_handler(axum::extract::Extension(fs_addr): axum::extract::Extension<String>) -> impl IntoResponse {
let ver = {
if !build::TAG.is_empty() {
build::TAG
} else if !build::SHORT_COMMIT.is_empty() {
concat!("@", build::SHORT_COMMIT)
} else {
build::PKG_VERSION
}
};
static CONSOLE_CONFIG: OnceLock<Config> = OnceLock::new();
let cfg = Config::new(&fs_addr, ver, build::COMMIT_DATE_3339).to_json();
fn initialize_config(fs_addr: &str) {
CONSOLE_CONFIG.get_or_init(|| {
let ver = {
if !build::TAG.is_empty() {
build::TAG.to_string()
} else if !build::SHORT_COMMIT.is_empty() {
format!("@{}", build::SHORT_COMMIT)
} else {
build::PKG_VERSION.to_string()
}
};
Config::new(fs_addr, ver.as_str(), build::COMMIT_DATE_3339)
});
}
#[allow(clippy::const_is_empty)]
async fn config_handler() -> impl IntoResponse {
let cfg = CONSOLE_CONFIG.get().unwrap().to_json();
Response::builder()
.header("content-type", "application/json")
@@ -124,15 +134,18 @@ async fn config_handler(axum::extract::Extension(fs_addr): axum::extract::Extens
.unwrap()
}
pub async fn start_static_file_server(addrs: &str, fs_addr: &str) {
pub async fn start_static_file_server(addrs: &str, local_ip: Ipv4Addr, server_port: u16) {
let srv_addr = format!("http://{}:{}", local_ip, server_port);
initialize_config(&srv_addr);
// 创建路由
let app = Router::new()
.route("/config.json", get(config_handler).layer(axum::extract::Extension(fs_addr.to_owned())))
.route("/config.json", get(config_handler))
.nest_service("/", get(static_handler));
let listener = tokio::net::TcpListener::bind(addrs).await.unwrap();
let local_addr = listener.local_addr().unwrap();
println!("console running on: http://{} with s3 api {}", listener.local_addr().unwrap(), fs_addr);
info!("console running on: http://{}:{} with s3 api {}", local_ip, local_addr.port(), srv_addr);
axum::serve(listener, app).await.unwrap();
}
+38 -15
View File
@@ -5,6 +5,7 @@ mod console;
mod grpc;
mod service;
mod storage;
mod utils;
use crate::auth::IAMAuth;
use clap::Parser;
use common::{
@@ -42,13 +43,17 @@ use tracing_subscriber::{fmt, layer::SubscriberExt, util::SubscriberInitExt};
fn setup_tracing() {
use tracing_subscriber::EnvFilter;
let env_filter = EnvFilter::from_default_env();
let env_filter = EnvFilter::try_from_default_env()
.unwrap_or_else(|_| EnvFilter::new("info"));
let enable_color = std::io::stdout().is_terminal();
let subscriber = fmt()
.pretty()
// .pretty()
.with_env_filter(env_filter)
.with_ansi(enable_color)
// Remove file and line number information from log output
.with_file(false)
.with_line_number(false)
.finish()
.with(ErrorLayer::default());
@@ -100,13 +105,39 @@ async fn run(opt: config::Opt) -> Result<()> {
let listener = TcpListener::bind(server_address.clone()).await?;
//获取监听地址
let local_addr: SocketAddr = listener.local_addr()?;
let local_ip = utils::get_local_ip().ok_or(local_addr.ip()).unwrap();
// 用于rpc
let (endpoint_pools, setup_type) = EndpointServerPools::from_volumes(server_address.clone().as_str(), opt.volumes.clone())
.map_err(|err| Error::from_string(err.to_string()))?;
// Print RustFS-style logging for pool formatting
for (i, eps) in endpoint_pools.as_ref().iter().enumerate() {
debug!(
info!(
"Formatting {}st pool, {} set(s), {} drives per set.",
i + 1, eps.set_count, eps.drives_per_set
);
// Add warning for host with multiple drives in a set (similar to RustFS)
if eps.drives_per_set > 1 {
warn!(
"WARNING: Host local has more than 0 drives of set. A host failure will result in data becoming unavailable."
);
}
}
// Print RustFS-style server information
info!("RustFS Object Storage Server");
// Detailed endpoint information (showing all API endpoints)
let api_endpoints = format!("http://{}:{}", local_ip, server_port);
let localhost_endpoint = format!("http://127.0.0.1:{}", server_port);
info!("API: {} {}", api_endpoints, localhost_endpoint);
info!(" RootUser: {}", opt.access_key);
info!(" RootPass: {}", opt.secret_key);
for (i, eps) in endpoint_pools.as_ref().iter().enumerate() {
info!(
"created endpoints {}, set_count:{}, drives_per_set: {}, cmd: {:?}",
i, eps.set_count, eps.drives_per_set, eps.cmd_line
);
@@ -131,6 +162,7 @@ async fn run(opt: config::Opt) -> Result<()> {
//显示info信息
info!("authentication is enabled {}, {}", &opt.access_key, &opt.secret_key);
b.set_auth(IAMAuth::new(opt.access_key, opt.secret_key));
b.set_access(store.clone());
@@ -173,11 +205,10 @@ async fn run(opt: config::Opt) -> Result<()> {
let http_server = ConnBuilder::new(TokioExecutor::new());
let mut ctrl_c = std::pin::pin!(tokio::signal::ctrl_c());
let graceful = hyper_util::server::graceful::GracefulShutdown::new();
println!("server is running at http://{local_addr}");
loop {
let (socket, _) = tokio::select! {
res = listener.accept() => {
res = listener.accept() => {
match res {
Ok(conn) => conn,
Err(err) => {
@@ -234,18 +265,10 @@ async fn run(opt: config::Opt) -> Result<()> {
// init auto heal
init_auto_heal().await;
info!("server was started");
if opt.console_enable {
info!("console is enabled");
debug!("console is enabled");
tokio::spawn(async move {
let ep = if !opt.server_domains.is_empty() {
format!("http://{}", opt.server_domains[0].clone())
} else {
format!("http://127.0.0.1:{}", server_port)
};
console::start_static_file_server(&opt.console_address, &ep).await;
console::start_static_file_server(&opt.console_address, local_ip, server_port).await;
});
}
+10
View File
@@ -0,0 +1,10 @@
use local_ip_address;
use std::net::IpAddr;
pub(crate) fn get_local_ip() -> Option<std::net::Ipv4Addr> {
match local_ip_address::local_ip() {
Ok(IpAddr::V4(ip)) => Some(ip),
Err(_) => None,
Ok(IpAddr::V6(_)) => todo!()
}
}