Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 3 additions & 7 deletions src/backends/qemu/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ use serde::{Deserialize, Serialize};

use crate::{
backends::{Backend, BackendClientError, BackendRegistration},
config::{ConfigError, load_config},
config::{self, ConfigError},
instance::{Instance, InstanceClient},
util::Path,
};
Expand Down Expand Up @@ -82,12 +82,8 @@ impl QemuConfig {
/// Read `<dir>/qemu.json` if present, otherwise return the
/// built-in defaults.
pub fn from_dir(dir: &Path) -> Result<Self, ConfigError> {
let path = Path::new(&dir.join("qemu.json"));
if path.exists() {
load_config(path)
} else {
Ok(Self::default())
}
let path = dir.join("qemu.json");
config::load_config_or_default(&path)
}
}

Expand Down
18 changes: 17 additions & 1 deletion src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,8 +136,24 @@ impl Default for Config {
}
}

/// Attempt to load a JSON config file. If not found, fall back on the
/// Default implementation.
pub fn load_config_or_default<T: for<'de> Deserialize<'de> + Default>(
path: impl AsRef<std::path::Path>,
) -> Result<T, ConfigError> {
match load_config(path) {
r @ Ok(_) => r,
Err(ConfigError::Io(e)) if e.kind() == std::io::ErrorKind::NotFound => {
Ok(Default::default())
}
e @ Err(_) => e,
}
}

/// Load a JSON config file.
pub fn load_config<T: for<'de> Deserialize<'de>>(path: impl AsRef<Path>) -> Result<T, ConfigError> {
pub fn load_config<T: for<'de> Deserialize<'de>>(
path: impl AsRef<std::path::Path>,
) -> Result<T, ConfigError> {
let path = path.as_ref();
let data = std::fs::read_to_string(path)?;
let val: T = serde_json::from_str(&data)?;
Expand Down
11 changes: 3 additions & 8 deletions src/engines/threshold.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use serde::{Deserialize, Serialize};
use tokio::sync::Mutex;

use crate::{
config::{ConfigError, deserialize_percent, serialize_percent},
config::{self, ConfigError, deserialize_percent, serialize_percent},
engines::{
AppliedOutcome, EngineError, EngineRegistration, EngineTickContext, ScaleAction,
ScalingEngine,
Expand Down Expand Up @@ -211,13 +211,8 @@ impl ThresholdEngine {

/// Load `threshold.json`, falling back to built-in defaults when absent.
pub fn from_config_dir(dir: &Path) -> Result<Self, EngineError> {
let path = Path::new(&dir.join(format!("{ENGINE_NAME}.json")));
// TODO TOCTOU, blindly load and return default if ENOENT
let cfg: ThresholdConfig = if path.exists() {
crate::config::load_config(path)?
} else {
ThresholdConfig::default()
};
let path = dir.join(format!("{ENGINE_NAME}.json"));
let cfg: ThresholdConfig = config::load_config_or_default(&path)?;
cfg.validate()?;
Ok(Self::new(cfg))
}
Expand Down
18 changes: 3 additions & 15 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,10 @@

//! `io-thread-controller` daemon entry point.

use std::io::ErrorKind;

use clap::{self, CommandFactory, FromArgMatches, Parser};
use io_thread_controller::{
backends::BackendClientError,
backends::registered_backends,
config::{Config, ConfigError, dump_default_config, load_config, validate_config},
backends::{BackendClientError, registered_backends},
config::{Config, ConfigError, dump_default_config, load_config_or_default, validate_config},
daemon::{DaemonError, VERSION, run},
util::Path,
};
Expand Down Expand Up @@ -122,7 +119,7 @@ async fn main() -> Result<(), IoThreadControllerError> {
return Err(IoThreadControllerError::NoSuchBackend(name.to_string()));
}

let mut cfg = load_daemon_config(&cli.config)?;
let mut cfg: Config = load_config_or_default(&cli.config)?;
if cli.print_status_header {
cfg.print_status_header = true;
}
Expand All @@ -135,15 +132,6 @@ async fn main() -> Result<(), IoThreadControllerError> {
Ok(())
}

/// Load defaults only for an absent file; propagate every other open failure.
fn load_daemon_config(path: &Path) -> Result<Config, ConfigError> {
match std::fs::File::open(path) {
Ok(_) => load_config(path),
Err(error) if error.kind() == ErrorKind::NotFound => Ok(Config::default()),
Err(error) => Err(error)?,
}
}

/// Install the process-wide tracing subscriber.
fn init_logging(filter: &str, style: LogStyle) {
// Auto-detection: systemd sets `JOURNAL_STREAM=<dev>:<ino>`
Expand Down
Loading