fix: GET: /config return all configurations when running standalone (#2630)

* fix: config api return all configurations when running standalone

* chore: follow same style

* fix: avoid panic
This commit is contained in:
Niwaka
2023-11-08 12:22:19 +09:00
committed by GitHub
parent b382900c5c
commit 06d273b75a
13 changed files with 163 additions and 34 deletions

View File

@@ -61,6 +61,7 @@ snafu.workspace = true
substrait = { workspace = true }
table = { workspace = true }
tokio.workspace = true
toml.workspace = true
[target.'cfg(not(windows))'.dependencies]
tikv-jemallocator = "0.5"
@@ -69,7 +70,6 @@ tikv-jemallocator = "0.5"
common-test-util = { workspace = true }
serde.workspace = true
temp-env = "0.3"
toml.workspace = true
[target.'cfg(not(windows))'.dev-dependencies]
rexpect = "0.5"

View File

@@ -201,7 +201,7 @@ impl StartCommand {
.context(StartFrontendSnafu)?;
instance
.build_servers(&opts)
.build_servers(opts)
.await
.context(StartFrontendSnafu)?;

View File

@@ -16,7 +16,8 @@ use common_config::KvBackendConfig;
use common_telemetry::logging::LoggingOptions;
use config::{Config, Environment, File, FileFormat};
use datanode::config::{DatanodeOptions, ProcedureConfig};
use frontend::frontend::FrontendOptions;
use frontend::error::{Result as FeResult, TomlFormatSnafu};
use frontend::frontend::{FrontendOptions, TomlSerializable};
use meta_srv::metasrv::MetaSrvOptions;
use serde::{Deserialize, Serialize};
use snafu::ResultExt;
@@ -27,6 +28,7 @@ pub const ENV_VAR_SEP: &str = "__";
pub const ENV_LIST_SEP: &str = ",";
/// Options mixed up from datanode, frontend and metasrv.
#[derive(Serialize)]
pub struct MixOptions {
pub data_home: String,
pub procedure: ProcedureConfig,
@@ -36,6 +38,18 @@ pub struct MixOptions {
pub logging: LoggingOptions,
}
impl From<MixOptions> for FrontendOptions {
fn from(value: MixOptions) -> Self {
value.frontend
}
}
impl TomlSerializable for MixOptions {
fn to_toml(&self) -> FeResult<String> {
toml::to_string(self).context(TomlFormatSnafu)
}
}
pub enum Options {
Datanode(Box<DatanodeOptions>),
Frontend(Box<FrontendOptions>),

View File

@@ -316,13 +316,13 @@ impl StartCommand {
#[allow(unused_variables)]
#[allow(clippy::diverging_sub_expression)]
async fn build(self, opts: MixOptions) -> Result<Instance> {
let mut fe_opts = opts.frontend;
#[allow(clippy::unnecessary_mut_passed)]
let fe_plugins = plugins::setup_frontend_plugins(&mut fe_opts)
let fe_opts = opts.frontend.clone();
let fe_plugins = plugins::setup_frontend_plugins(&fe_opts)
.await
.context(StartFrontendSnafu)?;
let dn_opts = opts.datanode;
let dn_opts = opts.datanode.clone();
info!("Standalone start command: {:#?}", self);
info!(
@@ -338,8 +338,8 @@ impl StartCommand {
let metadata_dir = metadata_store_dir(&opts.data_home);
let (kv_backend, procedure_manager) = FeInstance::try_build_standalone_components(
metadata_dir,
opts.metadata_store,
opts.procedure,
opts.metadata_store.clone(),
opts.procedure.clone(),
)
.await
.context(StartFrontendSnafu)?;
@@ -377,7 +377,7 @@ impl StartCommand {
.await?;
frontend
.build_servers(&fe_opts)
.build_servers(opts)
.await
.context(StartFrontendSnafu)?;

View File

@@ -272,6 +272,12 @@ pub enum Error {
#[snafu(display("Invalid auth config"))]
IllegalAuthConfig { source: auth::error::Error },
#[snafu(display("Failed to serialize options to TOML"))]
TomlFormat {
#[snafu(source)]
error: toml::ser::Error,
},
}
pub type Result<T> = std::result::Result<T, Error>;
@@ -279,7 +285,8 @@ pub type Result<T> = std::result::Result<T, Error>;
impl ErrorExt for Error {
fn status_code(&self) -> StatusCode {
match self {
Error::ParseAddr { .. }
Error::TomlFormat { .. }
| Error::ParseAddr { .. }
| Error::InvalidSql { .. }
| Error::InvalidInsertRequest { .. }
| Error::InvalidDeleteRequest { .. }

View File

@@ -18,7 +18,9 @@ use serde::{Deserialize, Serialize};
use servers::heartbeat_options::HeartbeatOptions;
use servers::http::HttpOptions;
use servers::Mode;
use snafu::prelude::*;
use crate::error::{Result, TomlFormatSnafu};
use crate::service_config::{
DatanodeOptions, GrpcOptions, InfluxdbOptions, MysqlOptions, OpentsdbOptions, OtlpOptions,
PostgresOptions, PromStoreOptions,
@@ -76,6 +78,16 @@ impl FrontendOptions {
}
}
pub trait TomlSerializable {
fn to_toml(&self) -> Result<String>;
}
impl TomlSerializable for FrontendOptions {
fn to_toml(&self) -> Result<String> {
toml::to_string(&self).context(TomlFormatSnafu)
}
}
#[cfg(test)]
mod tests {
use super::*;

View File

@@ -88,7 +88,7 @@ use crate::error::{
ParseSqlSnafu, PermissionSnafu, PlanStatementSnafu, Result, SqlExecInterceptedSnafu,
TableOperationSnafu,
};
use crate::frontend::FrontendOptions;
use crate::frontend::{FrontendOptions, TomlSerializable};
use crate::heartbeat::handler::invalidate_table_cache::InvalidateTableCacheHandler;
use crate::heartbeat::HeartbeatTask;
use crate::metrics;
@@ -358,7 +358,10 @@ impl Instance {
})
}
pub async fn build_servers(&mut self, opts: &FrontendOptions) -> Result<()> {
pub async fn build_servers(
&mut self,
opts: impl Into<FrontendOptions> + TomlSerializable,
) -> Result<()> {
let servers = Services::build(opts, Arc::new(self.clone()), self.plugins.clone()).await?;
self.servers = Arc::new(servers);

View File

@@ -33,7 +33,7 @@ use servers::server::Server;
use snafu::ResultExt;
use crate::error::{self, Result, StartServerSnafu};
use crate::frontend::FrontendOptions;
use crate::frontend::{FrontendOptions, TomlSerializable};
use crate::instance::FrontendInstance;
pub(crate) struct Services;
@@ -43,14 +43,17 @@ pub type ServerHandlers = HashMap<String, ServerHandler>;
pub type ServerHandler = (Box<dyn Server>, SocketAddr);
impl Services {
pub(crate) async fn build<T>(
opts: &FrontendOptions,
instance: Arc<T>,
pub(crate) async fn build<T, U>(
opts: T,
instance: Arc<U>,
plugins: Plugins,
) -> Result<ServerHandlers>
where
T: FrontendInstance,
T: Into<FrontendOptions> + TomlSerializable,
U: FrontendInstance,
{
let toml = opts.to_toml()?;
let opts: FrontendOptions = opts.into();
let mut result = Vec::<ServerHandler>::with_capacity(plugins.len());
let user_provider = plugins.get::<UserProviderRef>();
@@ -120,7 +123,7 @@ impl Services {
.with_metrics_handler(MetricsHandler)
.with_script_handler(instance.clone())
.with_plugins(plugins)
.with_greptime_config_options(opts.to_toml_string())
.with_greptime_config_options(toml)
.build();
result.push((Box::new(http_server), http_addr));
}