feat: building

This commit is contained in:
2022-07-24 02:10:13 +08:00
parent 065d1a89a6
commit 038d5546e0
6 changed files with 171 additions and 495 deletions

View File

@@ -6,13 +6,13 @@ pub struct CommandImpl;
impl Command for CommandImpl {
fn name(&self) -> &str { "cli" }
fn subcommand<'a>(&self) -> App<'a, 'a> {
SubCommand::with_name(self.name()).about("Local mini KMS cli")
.arg(Arg::with_name("connect").long("connect").takes_value(true).default_value("127.0.0.1:6567").help("Connect server"))
}
fn run(&self, _arg_matches: &ArgMatches, sub_arg_matches: &ArgMatches) -> CommandError {
fn run(&self, _arg_matches: &ArgMatches, _sub_arg_matches: &ArgMatches) -> CommandError {
simple_error!("Not implemented")
}
}

27
src/db.rs Normal file
View File

@@ -0,0 +1,27 @@
use rusqlite::{Connection, params};
use rust_util::{debugging, information, opt_result, success, XResult};
pub fn open_db(db: &str) -> XResult<Connection> {
let con = opt_result!(Connection::open(db), "Open sqlite db: {}, failed: {}", db);
debugging!("Db auto commit: {}", con.is_autocommit());
Ok(con)
}
pub fn init_db(conn: &Connection) -> XResult<bool> {
let mut stmt = conn.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='keys'")?;
let mut rows = stmt.query(())?;
if rows.next()?.is_some() {
information!("Table keys exists, skip init");
return Ok(false);
}
let _ = conn.execute(r##"
CREATE TABLE keys (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL,
value TEXT
)
"##, ())?;
success!("Table keys created");
Ok(true)
}

View File

@@ -2,6 +2,7 @@ use clap::{App, AppSettings, ArgMatches};
use rust_util::{failure_and_exit, information};
use rust_util::util_clap::{Command, CommandError};
mod db;
mod cli;
mod serve;

View File

@@ -1,6 +1,16 @@
use std::sync::RwLock;
use clap::{App, Arg, ArgMatches, SubCommand};
use rust_util::simple_error;
use hyper::{Body, Client, Method, Request, Response, Server, StatusCode};
use hyper::client::HttpConnector;
use hyper::service::{make_service_fn, service_fn};
use rust_util::{failure_and_exit, iff, information, success};
use rust_util::util_clap::{Command, CommandError};
use crate::db;
type GenericError = Box<dyn std::error::Error + Send + Sync>;
type Result<T> = std::result::Result<T, GenericError>;
static NOTFOUND: &[u8] = b"Not Found\n";
pub struct CommandImpl;
@@ -9,10 +19,70 @@ impl Command for CommandImpl {
fn subcommand<'a>(&self) -> App<'a, 'a> {
SubCommand::with_name(self.name()).about("Local mini KMS serve")
.arg(Arg::with_name("listen").long("listen").takes_value(true).default_value("127.0.0.1:6567").help("Listen"))
.arg(Arg::with_name("listen").long("listen").takes_value(true).default_value("127.0.0.1:5567").help("Listen"))
}
fn run(&self, _arg_matches: &ArgMatches, sub_arg_matches: &ArgMatches) -> CommandError {
simple_error!("Not implemented")
let listen = sub_arg_matches.value_of("listen").expect("Get argument listen error");
let rt = tokio::runtime::Runtime::new().expect("Create tokio runtime error");
rt.block_on(async {
let addr = listen.parse().expect(&format!("Parse listen error: {}", listen));
let client = Client::new();
let new_service = make_service_fn(move |_| {
let client = client.clone();
async {
Ok::<_, GenericError>(service_fn(move |req| {
response_requests(req, client.to_owned())
}))
}
});
let server = Server::bind(&addr).serve(new_service);
information!("Listening on http://{}", addr);
match server.await {
Err(e) => failure_and_exit!("Server error: {}", e),
Ok(_) => success!("Server ended"),
}
});
Ok(Some(0))
}
}
}
// ref: https://github.com/hyperium/hyper/blob/master/examples/web_api.rs
async fn response_requests(
req: Request<Body>,
_client: Client<HttpConnector>,
) -> Result<Response<Body>> {
match (req.method(), req.uri().path()) {
// (&Method::GET, "/") | (&Method::GET, "/index.html") => Ok(Response::new(INDEX.into())),
// (&Method::GET, "/test.html") => client_request_response(&client).await,
(&Method::GET, "/status") => status().await,
(&Method::GET, "/version") => get_version().await,
_ => {
Ok(Response::builder()
.status(StatusCode::NOT_FOUND).body(NOTFOUND.into())
.expect("Response not found error"))
}
}
}
// -------------------------------------------------------------------------------------------------
struct MemoryKey {
master_key: Vec<u8>,
}
lazy_static::lazy_static! {
static ref STATUS_RW_LOCK: RwLock<bool> = RwLock::new(false);
}
async fn status() -> Result<Response<Body>> {
let status_rw_lock = STATUS_RW_LOCK.read().expect("Lock read status rw lock error");
let status_rw_lock_value = *status_rw_lock;
Ok(Response::builder().body(format!("{}\n", iff!(status_rw_lock_value, "init", "uninit")).into()).expect("x"))
}
async fn get_version() -> Result<Response<Body>> {
Ok(Response::builder().body(format!(
"{} - {}\n", env!("CARGO_PKG_NAME"), env!("CARGO_PKG_VERSION")
).into()).expect("Response get_version error"))
}