feat: Add subcommands to server
parent
0ff527285c
commit
8029aa887d
|
@ -37,5 +37,4 @@ EXPOSE 8080 8082
|
|||
|
||||
ENTRYPOINT ["/usr/bin/influxdb_iox"]
|
||||
|
||||
CMD ["server"]
|
||||
|
||||
CMD ["server", "run"]
|
||||
|
|
|
@ -21,4 +21,4 @@ EXPOSE 8080 8082
|
|||
|
||||
ENTRYPOINT ["influxdb_iox"]
|
||||
|
||||
CMD ["server"]
|
||||
CMD ["server", "run"]
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
use tracing_subscriber::{prelude::*, EnvFilter};
|
||||
|
||||
use super::server::{Config, LogFormat};
|
||||
use super::server::{LogFormat, RunConfig};
|
||||
|
||||
/// Handles setting up logging levels
|
||||
#[derive(Debug)]
|
||||
|
@ -81,7 +81,7 @@ impl LoggingLevel {
|
|||
|
||||
/// Configures logging and tracing, based on the configuration
|
||||
/// values, for the IOx server (the whole enchalada)
|
||||
pub fn setup_logging(&self, config: &Config) -> Option<opentelemetry_jaeger::Uninstall> {
|
||||
pub fn setup_logging(&self, config: &RunConfig) -> Option<opentelemetry_jaeger::Uninstall> {
|
||||
// Copy anything from the config to the rust log environment
|
||||
self.set_rust_log_if_needed(config.rust_log.clone());
|
||||
|
||||
|
|
|
@ -20,15 +20,21 @@ pub const FALLBACK_AWS_REGION: &str = "us-east-1";
|
|||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum Error {
|
||||
#[error("Server error")]
|
||||
#[error("Server error: {0}")]
|
||||
ServerError(#[from] influxdb_ioxd::Error),
|
||||
}
|
||||
|
||||
pub type Result<T, E = Error> = std::result::Result<T, E>;
|
||||
|
||||
#[derive(Debug, StructOpt)]
|
||||
#[structopt(name = "server", about = "IOx server commands")]
|
||||
pub enum Config {
|
||||
Run(RunConfig),
|
||||
}
|
||||
|
||||
#[derive(Debug, StructOpt)]
|
||||
#[structopt(
|
||||
name = "server",
|
||||
name = "run",
|
||||
about = "Runs in server mode",
|
||||
long_about = "Run the IOx server.\n\nThe configuration options below can be \
|
||||
set either with the command line flags or with the specified environment \
|
||||
|
@ -41,7 +47,7 @@ Configuration is loaded from the following sources (highest precedence first):
|
|||
- .env file contents
|
||||
- pre-configured default values"
|
||||
)]
|
||||
pub struct Config {
|
||||
pub struct RunConfig {
|
||||
/// This controls the IOx server logging level, as described in
|
||||
/// https://crates.io/crates/env_logger.
|
||||
///
|
||||
|
@ -225,8 +231,10 @@ Possible values (case insensitive):
|
|||
pub jaeger_host: Option<String>,
|
||||
}
|
||||
|
||||
pub async fn command(logging_level: LoggingLevel, config: Box<Config>) -> Result<()> {
|
||||
Ok(influxdb_ioxd::main(logging_level, config).await?)
|
||||
pub async fn command(logging_level: LoggingLevel, config: Config) -> Result<()> {
|
||||
match config {
|
||||
Config::Run(config) => Ok(influxdb_ioxd::main(logging_level, config).await?),
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_socket_addr(s: &str) -> std::io::Result<SocketAddr> {
|
||||
|
@ -305,7 +313,7 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn test_socketaddr() -> Result<(), clap::Error> {
|
||||
let c = Config::from_iter_safe(
|
||||
let c = RunConfig::from_iter_safe(
|
||||
to_vec(&["server", "--api-bind", "127.0.0.1:1234"]).into_iter(),
|
||||
)?;
|
||||
assert_eq!(
|
||||
|
@ -313,7 +321,7 @@ mod tests {
|
|||
SocketAddr::from(([127, 0, 0, 1], 1234))
|
||||
);
|
||||
|
||||
let c = Config::from_iter_safe(
|
||||
let c = RunConfig::from_iter_safe(
|
||||
to_vec(&["server", "--api-bind", "localhost:1234"]).into_iter(),
|
||||
)?;
|
||||
// depending on where the test runs, localhost will either resolve to a ipv4 or
|
||||
|
@ -329,7 +337,7 @@ mod tests {
|
|||
};
|
||||
|
||||
assert_eq!(
|
||||
Config::from_iter_safe(
|
||||
RunConfig::from_iter_safe(
|
||||
to_vec(&["server", "--api-bind", "!@INv_a1d(ad0/resp_!"]).into_iter(),
|
||||
)
|
||||
.map_err(|e| e.kind)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::commands::{
|
||||
logging::LoggingLevel,
|
||||
server::{Config, ObjectStore as ObjStoreOpt},
|
||||
server::{ObjectStore as ObjStoreOpt, RunConfig},
|
||||
};
|
||||
use hyper::Server;
|
||||
use object_store::{
|
||||
|
@ -73,7 +73,7 @@ pub type Result<T, E = Error> = std::result::Result<T, E>;
|
|||
///
|
||||
/// The logging_level passed in is the global setting (e.g. if -v or
|
||||
/// -vv was passed in before 'server')
|
||||
pub async fn main(logging_level: LoggingLevel, config: Box<Config>) -> Result<()> {
|
||||
pub async fn main(logging_level: LoggingLevel, config: RunConfig) -> Result<()> {
|
||||
// Handle the case if -v/-vv is specified both before and after the server
|
||||
// command
|
||||
let logging_level = logging_level.combine(LoggingLevel::new(config.verbose_count));
|
||||
|
@ -98,7 +98,7 @@ pub async fn main(logging_level: LoggingLevel, config: Box<Config>) -> Result<()
|
|||
}
|
||||
}
|
||||
|
||||
let object_store = ObjectStore::try_from(&*config)?;
|
||||
let object_store = ObjectStore::try_from(&config)?;
|
||||
let object_storage = Arc::new(object_store);
|
||||
|
||||
let connection_manager = ConnectionManager {};
|
||||
|
@ -153,10 +153,10 @@ pub async fn main(logging_level: LoggingLevel, config: Box<Config>) -> Result<()
|
|||
Ok(())
|
||||
}
|
||||
|
||||
impl TryFrom<&Config> for ObjectStore {
|
||||
impl TryFrom<&RunConfig> for ObjectStore {
|
||||
type Error = Error;
|
||||
|
||||
fn try_from(config: &Config) -> Result<Self, Self::Error> {
|
||||
fn try_from(config: &RunConfig) -> Result<Self, Self::Error> {
|
||||
match config.object_store {
|
||||
Some(ObjStoreOpt::Memory) | None => {
|
||||
Ok(Self::new_in_memory(object_store::memory::InMemory::new()))
|
||||
|
@ -283,7 +283,7 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn default_object_store_is_memory() {
|
||||
let config = Config::from_iter_safe(&["server"]).unwrap();
|
||||
let config = RunConfig::from_iter_safe(&["server"]).unwrap();
|
||||
|
||||
let object_store = ObjectStore::try_from(&config).unwrap();
|
||||
|
||||
|
@ -295,7 +295,7 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn explicitly_set_object_store_to_memory() {
|
||||
let config = Config::from_iter_safe(&["server", "--object-store", "memory"]).unwrap();
|
||||
let config = RunConfig::from_iter_safe(&["server", "--object-store", "memory"]).unwrap();
|
||||
|
||||
let object_store = ObjectStore::try_from(&config).unwrap();
|
||||
|
||||
|
@ -307,7 +307,7 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn valid_s3_config() {
|
||||
let config = Config::from_iter_safe(&[
|
||||
let config = RunConfig::from_iter_safe(&[
|
||||
"server",
|
||||
"--object-store",
|
||||
"s3",
|
||||
|
@ -330,7 +330,7 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn s3_config_missing_params() {
|
||||
let config = Config::from_iter_safe(&["server", "--object-store", "s3"]).unwrap();
|
||||
let config = RunConfig::from_iter_safe(&["server", "--object-store", "s3"]).unwrap();
|
||||
|
||||
let err = ObjectStore::try_from(&config).unwrap_err().to_string();
|
||||
|
||||
|
@ -343,7 +343,7 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn valid_google_config() {
|
||||
let config = Config::from_iter_safe(&[
|
||||
let config = RunConfig::from_iter_safe(&[
|
||||
"server",
|
||||
"--object-store",
|
||||
"google",
|
||||
|
@ -364,7 +364,7 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn google_config_missing_params() {
|
||||
let config = Config::from_iter_safe(&["server", "--object-store", "google"]).unwrap();
|
||||
let config = RunConfig::from_iter_safe(&["server", "--object-store", "google"]).unwrap();
|
||||
|
||||
let err = ObjectStore::try_from(&config).unwrap_err().to_string();
|
||||
|
||||
|
@ -377,7 +377,7 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn valid_azure_config() {
|
||||
let config = Config::from_iter_safe(&[
|
||||
let config = RunConfig::from_iter_safe(&[
|
||||
"server",
|
||||
"--object-store",
|
||||
"azure",
|
||||
|
@ -400,7 +400,7 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn azure_config_missing_params() {
|
||||
let config = Config::from_iter_safe(&["server", "--object-store", "azure"]).unwrap();
|
||||
let config = RunConfig::from_iter_safe(&["server", "--object-store", "azure"]).unwrap();
|
||||
|
||||
let err = ObjectStore::try_from(&config).unwrap_err().to_string();
|
||||
|
||||
|
@ -415,7 +415,7 @@ mod tests {
|
|||
fn valid_file_config() {
|
||||
let root = TempDir::new().unwrap();
|
||||
|
||||
let config = Config::from_iter_safe(&[
|
||||
let config = RunConfig::from_iter_safe(&[
|
||||
"server",
|
||||
"--object-store",
|
||||
"file",
|
||||
|
@ -434,7 +434,7 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn file_config_missing_params() {
|
||||
let config = Config::from_iter_safe(&["server", "--object-store", "file"]).unwrap();
|
||||
let config = RunConfig::from_iter_safe(&["server", "--object-store", "file"]).unwrap();
|
||||
|
||||
let err = ObjectStore::try_from(&config).unwrap_err().to_string();
|
||||
|
||||
|
|
25
src/main.rs
25
src/main.rs
|
@ -83,11 +83,10 @@ struct Config {
|
|||
num_threads: Option<usize>,
|
||||
|
||||
#[structopt(subcommand)]
|
||||
command: Option<Command>,
|
||||
command: Command,
|
||||
}
|
||||
|
||||
#[derive(Debug, StructOpt)]
|
||||
#[structopt(setting = structopt::clap::AppSettings::SubcommandRequiredElseHelp)]
|
||||
enum Command {
|
||||
/// Convert one storage format to another
|
||||
Convert {
|
||||
|
@ -132,13 +131,12 @@ fn main() -> Result<(), std::io::Error> {
|
|||
let tokio_runtime = get_runtime(config.num_threads)?;
|
||||
tokio_runtime.block_on(async move {
|
||||
let host = config.host;
|
||||
|
||||
match config.command {
|
||||
Some(Command::Convert {
|
||||
Command::Convert {
|
||||
input,
|
||||
output,
|
||||
compression_level,
|
||||
}) => {
|
||||
} => {
|
||||
logging_level.setup_basic_logging();
|
||||
|
||||
let compression_level = CompressionLevel::from_str(&compression_level).unwrap();
|
||||
|
@ -150,7 +148,7 @@ fn main() -> Result<(), std::io::Error> {
|
|||
}
|
||||
}
|
||||
}
|
||||
Some(Command::Meta { input }) => {
|
||||
Command::Meta { input } => {
|
||||
logging_level.setup_basic_logging();
|
||||
match commands::meta::dump_meta(&input) {
|
||||
Ok(()) => debug!("Metadata dump completed successfully"),
|
||||
|
@ -160,7 +158,7 @@ fn main() -> Result<(), std::io::Error> {
|
|||
}
|
||||
}
|
||||
}
|
||||
Some(Command::Stats(config)) => {
|
||||
Command::Stats(config) => {
|
||||
logging_level.setup_basic_logging();
|
||||
match commands::stats::stats(&config).await {
|
||||
Ok(()) => debug!("Storage statistics dump completed successfully"),
|
||||
|
@ -170,33 +168,28 @@ fn main() -> Result<(), std::io::Error> {
|
|||
}
|
||||
}
|
||||
}
|
||||
Some(Command::Database(config)) => {
|
||||
Command::Database(config) => {
|
||||
logging_level.setup_basic_logging();
|
||||
if let Err(e) = commands::database::command(host, config).await {
|
||||
eprintln!("{}", e);
|
||||
std::process::exit(ReturnCode::Failure as _)
|
||||
}
|
||||
}
|
||||
Some(Command::Writer(config)) => {
|
||||
Command::Writer(config) => {
|
||||
logging_level.setup_basic_logging();
|
||||
if let Err(e) = commands::writer::command(host, config).await {
|
||||
eprintln!("{}", e);
|
||||
std::process::exit(ReturnCode::Failure as _)
|
||||
}
|
||||
}
|
||||
Some(Command::Server(config)) => {
|
||||
Command::Server(config) => {
|
||||
// Note don't set up basic logging here, different logging rules apply in server
|
||||
// mode
|
||||
if let Err(e) = commands::server::command(logging_level, config).await {
|
||||
if let Err(e) = commands::server::command(logging_level, *config).await {
|
||||
eprintln!("Server command failed: {}", e);
|
||||
std::process::exit(ReturnCode::Failure as _)
|
||||
}
|
||||
}
|
||||
None => {
|
||||
unreachable!(
|
||||
"SubcommandRequiredElseHelp will print help if there is no subcommand"
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -226,6 +226,7 @@ impl TestServer {
|
|||
let server_process = Command::cargo_bin("influxdb_iox")
|
||||
.unwrap()
|
||||
.arg("server")
|
||||
.arg("run")
|
||||
// Can enable for debugging
|
||||
//.arg("-vv")
|
||||
.env("INFLUXDB_IOX_BIND_ADDR", &addrs.http_bind_addr)
|
||||
|
@ -251,6 +252,7 @@ impl TestServer {
|
|||
self.server_process = Command::cargo_bin("influxdb_iox")
|
||||
.unwrap()
|
||||
.arg("server")
|
||||
.arg("run")
|
||||
// Can enable for debugging
|
||||
//.arg("-vv")
|
||||
.env("INFLUXDB_IOX_DB_DIR", self.dir.path())
|
||||
|
|
Loading…
Reference in New Issue