diff --git a/Cargo.toml b/Cargo.toml index 4f54470..a2f4a5a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,7 +17,7 @@ axum = "0.7.4" tokio = { version = "1.35.1", features = ["full"] } serde = { version = "1.0", features = ["derive"] } -serde_json = "1.0" +serde_json = "1.0.112" toml = "0.8.8" apache-avro = "0.16.0" @@ -27,6 +27,9 @@ sha1 = "0.10.6" zstd = "0.13.0" log = "0.4.20" +[dependencies.simple_logger] +version = "4.3.3" +features = ["colors", "threads", "timestamps", "stderr"] # [dependencies.db_logger] # version = "0.1" # optional = true diff --git a/src/cluster.rs b/src/cluster.rs index 7fab1fa..ca91f32 100644 --- a/src/cluster.rs +++ b/src/cluster.rs @@ -1,4 +1,4 @@ -use crate::config::{Config}; +use crate::config::Config; use crate::utils::avro_data_to_file_list; use crate::PROTOCOL_VERSION; @@ -63,7 +63,11 @@ impl Cluster { let url = self.config.join_center_url("/openbmclapi/files"); let password = self.config.cluster_secret.clone(); let username = self.config.cluster_id.clone(); - let client = Client::builder().user_agent(self.ua.clone()).build().unwrap(); + let client = Client::builder() + .user_agent(self.ua.clone()) + .build() + .unwrap(); + info!("getting file list from: {}", url); let res = client .get(url) .basic_auth(username, Some(password)) @@ -78,6 +82,7 @@ impl Cluster { match res.status() { StatusCode::OK => { let body = res.bytes().await.unwrap(); + info!("got file list len: {}, decompressing", body.len()); let cur = std::io::Cursor::new(body); let raw_data = decode_all(cur); if raw_data.is_err() { @@ -117,12 +122,13 @@ mod tests { test_conf.cluster_port, test_conf.cluster_id, test_conf.cluster_secret, - false, + None, ) } #[tokio::test] async fn test_get_file_list() { + crate::log::init_log_with_cli(); let config = gen_config(); let cluster = Cluster::new(config); cluster.get_file_list().await.unwrap(); diff --git a/src/config.rs b/src/config.rs index 7a21d02..79a75ab 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,9 +1,15 @@ +use { + crate::fatal, + log::{error, info, warn}, + std::{env, fs}, +}; +const CONFIG_PATH: &str = "config.toml"; -#[derive(Debug, Clone, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] pub struct Config { /// http or https - /// CLUSTER_BYOC + CENTER_URL + /// CENTER_URL pub center_url: String, /// CLUSTER_IP pub host_ip: String, @@ -15,34 +21,86 @@ pub struct Config { pub cluster_secret: String, /// NO_DEMAON pub no_demaon: bool, - // DISABLE_ACCESS_LOG - // pub disable_access_log: bool, - // FORCE_NOOPEN - // pub force_noopen: bool, - // ENABLE_NGINX - // pub enable_nginx: bool, - // NODE_UNIQUE_ID - // pub node_unique_id: String, } impl Config { pub fn new( center_url: Option, - host_ip: String, - host_port: u32, + host_ip: Option, + host_port: Option, cluster_id: String, cluster_secret: String, - no_demaon: bool, + no_demaon: Option, ) -> Self { - // https://openbmclapi.bangbang93.com Self { center_url: center_url.unwrap_or("https://openbmclapi.bangbang93.com".to_string()), + host_ip: host_ip.unwrap_or("0.0.0.0".to_string()), + host_port: host_port.unwrap_or(8080), + cluster_id, + cluster_secret, + no_demaon: no_demaon.unwrap_or(false), + } + } + + pub fn convert_from_env() { + // Load from env + let center_url = env::var("CENTER_URL").ok(); + let host_ip = env::var("CLUSTER_IP").ok(); + let host_port = env::var("CLUSTER_PORT").unwrap().parse::().ok(); + let no_demaon = env::var("NO_DAEMON").unwrap().parse::().ok(); + + // Load from env + let cluster_id = env::var("CLUSTER_ID").unwrap_or_else(|err| { + fatal!("CLUSTER_ID must be set"); + }); + let cluster_secret = env::var("CLUSTER_SECRET").unwrap_or_else(|err| { + fatal!("CLUSTER_SECRET must be set"); + }); + + // Decrapated warning + if env::var("CLUSTER_BYOC").is_ok() { + warn!("CLUSTER_BYOC is deprecated, ignored"); + } + if env::var("DISABLE_ACCESS_LOG").is_ok() { + warn!("DISABLE_ACCESS_LOG is deprecated, ignored"); + } + if env::var("FORCE_NOOPEN").is_ok() { + warn!("FORCE_NOOPEN is deprecated, ignored"); + } + if env::var("ENABLE_NGINX").is_ok() { + warn!("ENABLE_NGINX is deprecated, ignored"); + // If you want to use Nginx, why would you choose this program? + } + + // Create config + let config = Config::new( + center_url, host_ip, host_port, cluster_id, cluster_secret, no_demaon, + ); + + // Save config + config.save(); + } + pub fn save(&self) { + if !fs::canonicalize(CONFIG_PATH).is_ok() { + fs::File::create(CONFIG_PATH).unwrap_or_else(|err| { + fatal!("Failed to create config file"); + }); + //TODO: Trigger initialization } + fs::write(CONFIG_PATH, toml::to_string(&self).unwrap()).unwrap_or_else(|err| { + fatal!("Failed to save config file"); + }); + } + + pub fn load() -> Result { + toml::from_str(&self.load_raw()?).map_err(|err| { + fatal!("Failed to parse config file"); + }) } pub fn join_center_url(&self, path: &str) -> String { diff --git a/src/log.rs b/src/log.rs index ed79b27..739ebb2 100644 --- a/src/log.rs +++ b/src/log.rs @@ -1 +1,22 @@ -pub fn init_logging() {} +pub fn init_log_with_cli() { + // 命令行参数 + // --warn + // --debug + // --trace + // 从低级开始判断 + let log_level; + if std::env::args().any(|x| x == "--trace") { + log_level = log::LevelFilter::Trace; + } else if std::env::args().any(|x| x == "--debug") { + log_level = log::LevelFilter::Debug; + } else if std::env::args().any(|x| x == "--warn") { + log_level = log::LevelFilter::Warn; + } else { + log_level = log::LevelFilter::Info; + } + simple_logger::SimpleLogger::new() + .with_level(log_level) + .env() + .init() + .unwrap(); +} diff --git a/src/main.rs b/src/main.rs index ac562f2..3c3f315 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,4 +6,6 @@ mod utils; pub const PROTOCOL_VERSION: &str = "1.6.11"; -fn main() {} +fn main() { + log::init_log_with_cli(); +} diff --git a/src/utils.rs b/src/utils.rs index fb5f3f7..6da638c 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -1,12 +1,12 @@ -use crate::cluster::{SyncFile}; +use crate::cluster::SyncFile; use std::io::Cursor; -use log::{info, warn}; -use std::path::PathBuf; use apache_avro::{from_avro_datum, from_value, types::Value}; +use log::{info, warn}; use md5::{Digest, Md5}; use sha1::Sha1; +use std::path::PathBuf; /// import {join} from 'path' /// @@ -92,6 +92,7 @@ pub fn avro_data_to_file_list(data: Vec) -> Option> { } files.push(try_item.unwrap()); } + info!("parsed {} files", len); Some(files) } _ => { @@ -101,6 +102,16 @@ pub fn avro_data_to_file_list(data: Vec) -> Option> { } } +#[macro_export] +macro_rules! fatal { + ($($arg:tt)+) => { + use log::error; + // error!() + panic!() + error!($($arg)+); + panic!($($arg)+); + }; +} + #[test] fn test_hash_to_filename() { assert_eq!(