Skip to content

Commit 7a603be

Browse files
committed
Allow specifying default configuration through a configuration file
Muvm will first look in $XDG_CONFIG_DIR:-~/.config for a muvm/config.json file. Failing this, it will try reading /etc/muvm/config.json. Currently the configuration file only allows *prepending* execute_pre option. Specifying --execute-pre will not overwrite what's already in the config file. Signed-off-by: Nikodem Rabuliński <[email protected]>
1 parent bde8f68 commit 7a603be

File tree

3 files changed

+68
-1
lines changed

3 files changed

+68
-1
lines changed

crates/muvm/src/bin/muvm.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use krun_sys::{
1515
};
1616
use log::debug;
1717
use muvm::cli_options::options;
18+
use muvm::config::Configuration;
1819
use muvm::cpu::{get_fallback_cores, get_performance_cores};
1920
use muvm::env::{find_muvm_exec, prepare_env_vars};
2021
use muvm::hidpipe_server::spawn_hidpipe_server;
@@ -73,6 +74,12 @@ fn main() -> Result<ExitCode> {
7374
}
7475

7576
let options = options().fallback_to_usage().run();
77+
let config = Configuration::parse_config_file()?;
78+
79+
let mut init_commands = options.init_commands;
80+
if let Some(init_command) = config.execute_pre {
81+
init_commands.insert(0, init_command);
82+
}
7683

7784
let (_lock_file, command, command_args, env) = match launch_or_lock(
7885
options.command,
@@ -397,7 +404,7 @@ fn main() -> Result<ExitCode> {
397404
merged_rootfs: options.merged_rootfs,
398405
emulator: options.emulator,
399406
cwd,
400-
init_commands: options.init_commands,
407+
init_commands,
401408
};
402409
let mut muvm_config_file = NamedTempFile::new()
403410
.context("Failed to create a temporary file to store the muvm guest config")?;

crates/muvm/src/config.rs

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
use std::{
2+
env::{self, VarError},
3+
io,
4+
path::{Path, PathBuf},
5+
};
6+
7+
use anyhow::{Context, Result};
8+
use serde::{Deserialize, Serialize};
9+
10+
#[derive(Deserialize, Serialize, Default)]
11+
pub struct Configuration {
12+
pub execute_pre: Option<PathBuf>,
13+
}
14+
15+
fn get_var_if_exists(name: &str) -> Option<Result<String>> {
16+
match env::var(name) {
17+
Ok(val) => Some(Ok(val)),
18+
Err(VarError::NotPresent) => None,
19+
Err(e) => Some(Err(e.into())),
20+
}
21+
}
22+
23+
fn get_user_config_path() -> Result<PathBuf> {
24+
let mut path = get_var_if_exists("XDG_CONFIG_DIR").map_or_else(
25+
|| {
26+
let base = env::var("HOME").context("Failed to get HOME")?;
27+
let mut base = PathBuf::from(base);
28+
base.push(".config");
29+
Ok(base)
30+
},
31+
|p| p.map(PathBuf::from),
32+
)?;
33+
path.push("muvm");
34+
path.push("config.json");
35+
Ok(path)
36+
}
37+
38+
fn get_system_config_path() -> PathBuf {
39+
PathBuf::from("/etc/muvm/config.json")
40+
}
41+
42+
fn read_to_string_if_exists(p: &Path) -> Option<io::Result<String>> {
43+
match std::fs::read_to_string(p) {
44+
Ok(content) => Some(Ok(content)),
45+
Err(err) if err.kind() == io::ErrorKind::NotFound => None,
46+
Err(e) => Some(Err(e)),
47+
}
48+
}
49+
50+
impl Configuration {
51+
pub fn parse_config_file() -> Result<Self> {
52+
let Some(content) = read_to_string_if_exists(&get_user_config_path()?)
53+
.or_else(|| read_to_string_if_exists(&get_system_config_path()))
54+
else {
55+
return Ok(Default::default());
56+
};
57+
Ok(serde_json::from_str(&content?)?)
58+
}
59+
}

crates/muvm/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
pub mod cli_options;
2+
pub mod config;
23
pub mod cpu;
34
pub mod env;
45
pub mod hidpipe_common;

0 commit comments

Comments
 (0)