Move logging config to main configuration file.

- Move the content of what was stored in log4rs.yml into the main config
  file, so that there is just one file to parse to get the complete
  configuration.
- Create the global switch `--home` to pass/overload the value for
  SEQUOIA_HOME in the configuration file.
This commit is contained in:
Malte Meiboom
2026-05-18 11:11:22 +02:00
parent 6611a43a24
commit 14dca91d92
5 changed files with 81 additions and 23 deletions
+21 -2
View File
@@ -5,6 +5,25 @@ connection = "localhost:3000"
sequoia_home = "/tmp/sq_home" sequoia_home = "/tmp/sq_home"
logfile_config = "./config/log4rs.yml" #keyservers = [ "hkps://keys.openpgp.org/", "hkps://mail-api.proton.me", "hkps://keys.mailvelope.com", "hkps://keyserver.ubuntu.com", "hkps://sks.pod01.fleetstreetops.com" ]
keyservers = [ "hkp://example.com" ]
[logging.appenders.console]
kind = "console"
[logging.appenders.console.encoder]
pattern = "{d(%Y-%m-%d %H:%M:%S)(local)} {h({l})} [{t}] {m}{n}"
[logging.appenders.file]
kind = "file"
path = "/tmp/husk.log"
[logging.appenders.file.encoder]
pattern = "{d(%Y-%m-%d %H:%M:%S)(local)} {h({l})} [{t}] {m}{n}"
[logging.root]
level = "debug"
appenders = ["file"]
[logging.loggers."husk"]
level = "debug"
keyservers = [ "hkps://keys.openpgp.org/", "hkps://mail-api.proton.me", "hkps://keys.mailvelope.com", "hkps://keyserver.ubuntu.com", "hkps://sks.pod01.fleetstreetops.com" ]
+7
View File
@@ -15,6 +15,13 @@ pub struct CliArgs {
)] )]
pub config: Option<String>, pub config: Option<String>,
#[clap(
long,
global = true,
help = "Certification store (SEQUOIA_HOME).",
)]
pub home: Option<String>,
#[clap(subcommand)] #[clap(subcommand)]
pub subcommand: HuskSubcommands, pub subcommand: HuskSubcommands,
} }
+26 -12
View File
@@ -3,27 +3,36 @@
// //
use anyhow; use anyhow;
use std::fs; use std::fs;
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
use serde_derive::Deserialize; use serde_derive::Deserialize;
use toml;
use log4rs;
use crate::types::errors::HuskError; use crate::types::errors::HuskError;
use crate::types::defaults::CONSOLE_LOGGING;
#[derive(Deserialize, Debug, Clone)] #[derive(Deserialize, Debug, Clone)]
pub struct HuskConfig { pub struct HuskConfig {
pub connection: String, pub connection: String,
pub sequoia_home: String, pub sequoia_home: String,
logfile_config: Option<String>,
pub keyservers: Option<Vec<String>>, pub keyservers: Option<Vec<String>>,
logging: Option<toml::Value>,
} }
impl HuskConfig { impl HuskConfig {
pub fn load(path: &str) -> anyhow::Result<Self> { pub fn load(path: &str, home: Option<String>) -> anyhow::Result<Self> {
match fs::read_to_string(path) { match fs::read_to_string(path) {
Ok(data) => { Ok(data) => {
match toml::from_str(data.as_str()) { match toml::from_str::<HuskConfig>(data.as_str()) {
Ok(configuration) => Ok(configuration), Ok(mut configuration) => {
if let Some(home) = home {
configuration.sequoia_home = home;
}
Ok(configuration)
},
Err(e) => { Err(e) => {
Err(HuskError::ConfigFileParseError(e.to_string()).into()) Err(HuskError::ConfigFileParseError(e.to_string()).into())
} }
@@ -35,14 +44,19 @@ impl HuskConfig {
} }
} }
pub fn logfile_config(&self) -> String { pub fn init_logging(&self) -> anyhow::Result<()> {
match &self.logfile_config { let config = match toml::to_string(&self.logging) {
Some(c) => c.clone(), Ok(c) => c,
None => { Err(e) => {
eprintln!("Using logging configuration from 'log4rs.yml'"); eprintln!("use default logging, because {}", e);
"log4rs.yml".to_string() eprintln!("{:?}", self.logging);
}, CONSOLE_LOGGING.to_string()
} }
};
let raw_config = toml::from_str::<log4rs::config::RawConfig>(config.as_str())?;
log4rs::init_raw_config(raw_config)?;
Ok(())
} }
pub fn get_keyservers(&self) -> Vec<String> { pub fn get_keyservers(&self) -> Vec<String> {
+6 -9
View File
@@ -1,5 +1,6 @@
//! Husk milter //! Husk milter
use anyhow;
use std::process; use std::process;
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
@@ -18,7 +19,7 @@ use daemon::Daemon;
pub mod common; pub mod common;
#[tokio::main] #[tokio::main]
async fn main() { async fn main() -> anyhow::Result<()> {
let args = CliArgs::parse(); let args = CliArgs::parse();
let config_file = match &args.config { let config_file = match &args.config {
@@ -26,7 +27,8 @@ async fn main() {
None => defaults::CONFIG_FILE_LOCATION None => defaults::CONFIG_FILE_LOCATION
}; };
let husk_config = match HuskConfig::load(config_file) { // XXX: Improve the way cli parameters are passed into the configuration.
let husk_config = match HuskConfig::load(config_file, args.home.clone()) {
Ok(config) => config, Ok(config) => config,
Err(e) => { Err(e) => {
eprintln!("{:?}", e); eprintln!("{:?}", e);
@@ -34,14 +36,9 @@ async fn main() {
} }
}; };
log4rs::init_file(husk_config.logfile_config(), Default::default()).unwrap(); husk_config.init_logging()?;
log::info!("starting...");
let config_container: HuskConfigContainer = Arc::new(Mutex::new(husk_config)); let config_container: HuskConfigContainer = Arc::new(Mutex::new(husk_config));
if let Err(e) = commands::dispatch(args, config_container).await { commands::dispatch(args, config_container).await
eprintln!("exit with {:?}", e);
// XXX: actually return an error code
}
} }
+21
View File
@@ -1,3 +1,24 @@
//! Defaults //! Defaults
pub const CONFIG_FILE_LOCATION: &'static str = "/etc/husk/config.toml"; pub const CONFIG_FILE_LOCATION: &'static str = "/etc/husk/config.toml";
/// Default logging configuration.
pub const CONSOLE_LOGGING: &'static str = "
[appenders.console]
kind = \"console\"
[appenders.console.encoder]
pattern = \"{d(%Y-%m-%d %H:%M:%S)(local)} {h({l})} [{t}] {m}{n}\"
[[appenders.console.filters]]
kind = \"threshold\"
level = \"debug\"
[root]
level = \"info\"
appenders = [\"console\"]
[loggers.\"husk\"]
level = \"debug\"
";