Improve help message generation and allow env var for password

next
Sayan Nandan 7 months ago
parent 8d8f1720d2
commit baaa36d336
No known key found for this signature in database
GPG Key ID: 0EBD769024B24F0A

3
Cargo.lock generated

@ -720,6 +720,9 @@ checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
[[package]]
name = "libsky"
version = "0.8.0-beta.4"
dependencies = [
"regex",
]
[[package]]
name = "linux-raw-sys"

@ -4,9 +4,13 @@ version = "0.8.0-beta.4"
authors = ["Sayan Nandan <ohsayan@outlook.com>"]
edition = "2021"
description = "The Skytable Shell (skysh)"
build = "build.rs"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[build-dependencies]
libsky = { path = "../libsky" }
[dependencies]
# internal deps
libsky = { path = "../libsky" }

@ -0,0 +1,3 @@
fn main() -> std::io::Result<()> {
libsky::build_scripts::format_help_txt("skysh", "help_text/help", Default::default())
}

@ -1,4 +1,4 @@
skysh 0.8.0-beta.4
skysh {version}
Sayan N. <ohsayan@outlook.com>
The Skytable interactive shell (skysh)
@ -16,14 +16,15 @@ OPTIONS:
--tls-cert Set the TLS certificate to use (for TLS endpoints)
NOTES:
- skysh will also look for the `{password_env_var}` environment variable
- When no endpoint is specified, skysh will attempt to connect to the default
TCP endpoint `tcp@127.0.0.1:2003`
TCP endpoint `{default_tcp_endpoint}`
- When no user is specified, skysh will attempt to authenticate as root
- All connections need an username and password. If this is not provided
via arguments, it will be asked for interactively
- Endpoints are specified using the Skytable endpoint syntax. For example,
the default TCP endpoint is `tcp@127.0.0.1:2003` while the default TLS
endpoint is `tls@127.0.0.1:2004`
the default TCP endpoint is `{default_tcp_endpoint}` while the default TLS
endpoint is `{default_tls_endpoint}`
- If you choose to use a TLS endpoint, you must provide a certificate.
Failing to do so will throw an error, as expected
- All history is stored in the `.sky_history` file. If you wish to delete

@ -30,16 +30,16 @@ use {
event::{self, Event, KeyCode, KeyEvent},
terminal,
},
libsky::CliAction,
libsky::{env_vars, CliAction},
std::{
collections::HashMap,
fs,
env, fs,
io::{self, Write},
process::exit,
},
};
const TXT_HELP: &str = include_str!("../help_text/help");
const TXT_HELP: &str = include_str!(concat!(env!("OUT_DIR"), "/skysh"));
#[derive(Debug)]
pub struct ClientConfig {
@ -148,7 +148,13 @@ pub fn parse() -> CliResult<Task> {
};
let password = match args.remove("--password") {
Some(p) => p,
None => read_password("Enter password: ")?,
None => {
// let us check the environment variable to see if anything was set
match env::var(env_vars::SKYDB_PASSWORD) {
Ok(v) => v,
Err(_) => read_password("Enter password: ")?,
}
}
};
if args.is_empty() {
Ok(Task::OpenShell(ClientConfig::new(

@ -7,3 +7,4 @@ version = "0.8.0-beta.4"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
regex = "1"

@ -36,6 +36,11 @@ pub const VERSION: &str = env!("CARGO_PKG_VERSION");
/// The URL
pub const URL: &str = "https://github.com/skytable/skytable";
pub mod env_vars {
/// the environment variable to set the password to use with any tool (skysh,sky-bench,..)
pub const SKYDB_PASSWORD: &str = "SKYDB_PASSWORD";
}
pub mod test_utils {
pub const DEFAULT_USER_NAME: &str = "root";
pub const DEFAULT_USER_PASS: &str = "mypassword12345678";
@ -170,3 +175,55 @@ fn extract_arg(
};
Ok((arg, value))
}
/*
formatting utils
*/
pub fn format(body: &str, arguments: HashMap<&'static str, &'static str>, auto: bool) -> String {
use regex::Regex;
let pattern = r"\{[a-zA-Z_][a-zA-Z_0-9]*\}|\{\}";
let re = Regex::new(pattern).unwrap();
re.replace_all(body, |caps: &regex::Captures| {
let capture: &str = &caps[0];
let capture = &capture[1..capture.len() - 1];
match capture {
"" => {
panic!("found an empty format")
}
"default_tcp_endpoint" if auto => "tcp@127.0.0.1:2003".to_owned(),
"default_tls_endpoint" if auto => "tls@127.0.0.1:2004".to_owned(),
"password_env_var" if auto => env_vars::SKYDB_PASSWORD.into(),
"version" if auto => format!("v{VERSION}"),
arbitrary => arguments
.get(arbitrary)
.expect(&format!("could not find value for argument {}", arbitrary))
.to_string(),
}
})
.to_string()
}
pub mod build_scripts {
use std::{
collections::HashMap,
env,
fs::{self, File},
io::{self, Write},
path::Path,
};
pub fn format_help_txt(
binary_name: &str,
help_text_path: &str,
arguments: HashMap<&'static str, &'static str>,
) -> io::Result<()> {
let help_msg = fs::read_to_string(help_text_path)?;
let content = super::format(&help_msg, arguments, true);
// write
let out_dir = env::var("OUT_DIR").unwrap();
let dest_path = Path::new(&out_dir).join(binary_name);
let mut f = File::create(&dest_path)?;
f.write_all(content.as_bytes())?;
Ok(())
}
}

@ -5,6 +5,10 @@ name = "skyd"
version = "0.8.0-beta.4"
description = "Skytable is a modern NoSQL database powered by BlueQL that aims to deliver performance, scalability and flexibility with data"
license = "AGPL-3.0"
build = "build.rs"
[build-dependencies]
libsky = { path = "../libsky" }
[dependencies]
# internal deps

@ -0,0 +1,3 @@
fn main() -> std::io::Result<()> {
libsky::build_scripts::format_help_txt("skyd", "help_text/help", Default::default())
}

@ -0,0 +1,40 @@
███████ ██  ██ ██  ██ ████████  █████  ██████  ██  ███████
██      ██  ██   ██  ██     ██    ██   ██ ██   ██ ██  ██
███████ █████    ████   ██  ███████ ██████  ██  █████
     ██ ██  ██   ██   ██  ██   ██ ██   ██ ██  ██
███████ ██  ██  ██  ██  ██  ██ ██████  ███████ ███████
Skytable {version} | https://github.com/skytable/skytable
Sayan N. <ohsayan@outlook.com>
Skytable database server
Usage: skyd [OPTION]...
skyd is the Skytable database server daemon and can be used to serve database requests.
Flags:
-h, --help Display this help menu and exit.
-v, --version Display the version number and exit.
Options:
--config <path> Set configuration options using the config file
--tlscert <path> Specify the path to the TLS certificate.
--tlskey <path> Specify the path to the TLS private key.
--endpoint <definition> Designate an endpoint. Format: protocol@host:port.
This option can be repeated to define multiple endpoints.
--service-window <seconds> Set the time window for the background service in seconds.
--auth <plugin_name> Identify the authentication plugin by name.
--mode <dev/prod> Set the operational mode. Note: This option is mandatory.
--auth-plugin <plugin> Set the auth plugin. `pwd` is a supported option
--auth-root-password <pass> Set the root password
Examples:
skyd --auth-root-password "password12345678"
Notes:
- If no `--mode` is provided, we default to `dev`
- You must provide `--auth-root-password` to set the default root password
- To use TLS, you must provide both `--tlscert` and `--tlskey`
For further assistance, refer to the official documentation here: https://docs.skytable.org

@ -333,7 +333,7 @@ impl fmt::Display for ConfigError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match &self.source {
Some(src) => write!(f, "config error in {}: ", src.as_str())?,
None => write!(f, "config error: ")?,
None => {}
}
match &self.kind {
ConfigErrorKind::Conflict => write!(
@ -640,37 +640,7 @@ fn arg_decode_rs_window<CS: ConfigurationSource>(
*/
/// CLI help message
pub(super) const CLI_HELP: &str = "\
Usage: skyd [OPTION]...
skyd is the Skytable database server daemon and can be used to serve database requests.
Flags:
-h, --help Display this help menu and exit.
-v, --version Display the version number and exit.
Options:
--config <path> Set configuration options using the config file
--tlscert <path> Specify the path to the TLS certificate.
--tlskey <path> Specify the path to the TLS private key.
--endpoint <definition> Designate an endpoint. Format: protocol@host:port.
This option can be repeated to define multiple endpoints.
--service-window <seconds> Establish the time window for the background service in seconds.
--auth <plugin_name> Identify the authentication plugin by name.
--mode <dev/prod> Set the operational mode. Note: This option is mandatory.
--auth-plugin <plugin> Set the auth plugin. `pwd` is a supported option
--auth-root-password <pass> Set the root password
Examples:
skyd --mode=dev --auth-root-password \"password12345678\"
Notes:
- If no `--mode` is provided, we default to `dev`
- You must provide `--auth-root-password` to set the default root password
- To use TLS, you must provide both `--tlscert` and `--tlskey`
For further assistance, refer to the official documentation here: https://docs.skytable.org
";
pub(super) const TXT_HELP: &str = include_str!(concat!(env!("OUT_DIR"), "/skyd"));
#[derive(Debug, PartialEq)]
/// Return from parsing CLI configuration
@ -1128,7 +1098,7 @@ pub fn check_configuration() -> RuntimeResult<ConfigReturn> {
// no options were provided in the CLI
None
}
CLIConfigParseReturn::Help => return Ok(ConfigReturn::HelpMessage(CLI_HELP.into())),
CLIConfigParseReturn::Help => return Ok(ConfigReturn::HelpMessage(TXT_HELP.into())),
CLIConfigParseReturn::Version => {
// just output the version
return Ok(ConfigReturn::HelpMessage(format!(

@ -26,7 +26,7 @@
#[macro_use]
mod macros;
mod config;
pub mod config;
mod core;
mod data;
mod error;
@ -48,11 +48,10 @@ use crate::engine::storage::SELoaded;
use {
self::{
config::{ConfigEndpoint, ConfigEndpointTls, ConfigMode, ConfigReturn, Configuration},
config::{ConfigEndpoint, ConfigEndpointTls, ConfigMode, Configuration},
fractal::context::{self, Subsystem},
},
crate::util::os::TerminationSignal,
std::process::exit,
tokio::sync::broadcast,
};
@ -63,17 +62,10 @@ pub(super) fn set_context_init(msg: &'static str) {
/// Initialize all drivers, load all data
///
/// WARN: Must be in [`tokio::runtime::Runtime`] context!
pub fn load_all() -> RuntimeResult<(Configuration, fractal::GlobalStateStart)> {
pub fn load_all(
config: Configuration,
) -> RuntimeResult<(Configuration, fractal::GlobalStateStart)> {
// load configuration
info!("checking configuration ...");
context::set(Subsystem::Init, "loading configuration");
let config = match config::check_configuration()? {
ConfigReturn::Config(cfg) => cfg,
ConfigReturn::HelpMessage(msg) => {
eprintln!("{msg}");
exit(0x00);
}
};
if config.mode == ConfigMode::Dev {
warn!("running in dev mode");
}

@ -144,7 +144,7 @@ fn parse_validate_cli_args_help_and_version() {
let ret4 = config::check_configuration().unwrap();
assert_eq!(
ret3,
ConfigReturn::HelpMessage(config::CLI_HELP.to_string())
ConfigReturn::HelpMessage(config::TXT_HELP.to_string())
);
assert_eq!(
ret4,

@ -42,10 +42,7 @@ extern crate log;
pub mod util;
mod engine;
use {
crate::util::exit_error,
libsky::{URL, VERSION},
};
use libsky::{URL, VERSION};
#[cfg(all(not(target_env = "msvc"), not(miri)))]
#[global_allocator]
@ -65,14 +62,24 @@ type IoResult<T> = std::io::Result<T>;
const SKY_PID_FILE: &str = ".sky_pid";
fn main() {
use crate::engine::config::ConfigReturn;
Builder::new()
.parse_filters(&env::var("SKY_LOG").unwrap_or_else(|_| "info".to_owned()))
.init();
println!("{TEXT}\nSkytable v{VERSION} | {URL}\n");
entrypoint()
let config = match engine::config::check_configuration() {
Ok(cfg) => match cfg {
ConfigReturn::Config(cfg) => cfg,
ConfigReturn::HelpMessage(msg) => {
exit!(eprintln!("{msg}"), 0x00)
}
},
Err(e) => exit_fatal!(error!("{e}")),
};
self::entrypoint(config)
}
fn entrypoint() {
fn entrypoint(config: engine::config::Configuration) {
println!("{TEXT}\nSkytable v{VERSION} | {URL}\n");
let run = || {
let f_rt_start = || {
engine::set_context_init("locking PID file");
@ -91,7 +98,7 @@ fn entrypoint() {
let f_glob_init = runtime.block_on(async move {
engine::set_context_init("binding system signals");
let signal = util::os::TerminationSignal::init()?;
let (config, global) = tokio::task::spawn_blocking(|| engine::load_all())
let (config, global) = tokio::task::spawn_blocking(|| engine::load_all(config))
.await
.unwrap()?;
engine::RuntimeResult::Ok((signal, config, global))
@ -117,9 +124,6 @@ fn entrypoint() {
}
match result {
Ok(()) => println!("goodbye"),
Err(e) => {
error!("{e}");
exit_error();
}
Err(e) => exit_fatal!(error!("{e}")),
}
}

@ -318,3 +318,22 @@ macro_rules! concat_str_to_str {
concat_str_to_str!(A, $c)
}};
}
#[macro_export]
macro_rules! exit {
($do_it:expr, $code:expr) => {{
$do_it;
::std::process::exit($code)
}};
($code:expr) => {
::std::process::exit($code)
};
}
#[macro_export]
macro_rules! exit_fatal {
($do_it:expr) => {{
$do_it;
$crate::util::exit_error()
}};
}

@ -4,9 +4,12 @@ edition = "2021"
name = "sky-bench"
version = "0.8.0-beta.4"
description = "The Skytable benchmark tool can be used to benchmark Skytable installations"
build = "build.rs"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[build-dependencies]
libsky = { path = "../libsky" }
[dependencies]
# internal deps
skytable = { git = "https://github.com/skytable/client-rust.git" }

@ -0,0 +1,3 @@
fn main() -> std::io::Result<()> {
libsky::build_scripts::format_help_txt("sky-bench", "help_text/help", Default::default())
}

@ -1,4 +1,4 @@
sky-bench 0.8.0-beta.4
sky-bench {version}
Sayan N. <ohsayan@outlook.com>
Skytable benchmark tool
@ -13,7 +13,7 @@ REQUIRED OPTIONS:
--password Provide the password
OPTIONS:
--endpoint Set the endpoint (defaults to tcp@127.0.0.1:2003)
--endpoint Set the endpoint (defaults to {default_tcp_endpoint})
--threads Set the number of threads to be used (defaults to logical
CPU count)
--connections Set the number of connections. Defaults to 8 x logical CPU
@ -25,6 +25,8 @@ OPTIONS:
and `fury` is the new experimental engine. Defaults to `fury`
NOTES:
- If no password is supplied, we look for the `{password_env_var}`
environment variable
- The user for auth will be 'root' since only 'root' accounts allow the
creation and deletion of spaces and models
- A space called 'bench' will be created

@ -26,11 +26,11 @@
use {
crate::error::{BenchError, BenchResult},
libsky::CliAction,
std::collections::hash_map::HashMap,
libsky::{env_vars, CliAction},
std::{collections::hash_map::HashMap, env},
};
const TXT_HELP: &str = include_str!("../help_text/help");
const TXT_HELP: &str = include_str!(concat!(env!("OUT_DIR"), "/sky-bench"));
#[derive(Debug)]
enum TaskInner {
@ -144,9 +144,15 @@ pub fn parse() -> BenchResult<Task> {
let passsword = match args.remove("--password") {
Some(p) => p,
None => {
return Err(BenchError::ArgsErr(
"you must provide a value for `--password`".into(),
))
// check env?
match env::var(env_vars::SKYDB_PASSWORD) {
Ok(p) => p,
Err(_) => {
return Err(BenchError::ArgsErr(
"you must provide a value for `--password`".into(),
))
}
}
}
};
// threads

Loading…
Cancel
Save