Refactor to chain realm specific config to global config
Now if a variable is not set in a realm config file (or the file does not exist), the 'global' config file will also be searched in the parent directory (ie: /storage/realms/config). If the variable is still not found, the value from the default instance is returned.
This commit is contained in:
parent
6215b58167
commit
0b2480f849
@ -1,112 +1,172 @@
|
|||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::fs::File;
|
use std::fs;
|
||||||
use std::io::Read;
|
|
||||||
use toml;
|
use toml;
|
||||||
use crate::Result;
|
|
||||||
|
|
||||||
fn default_true() -> bool {
|
lazy_static! {
|
||||||
true
|
pub static ref GLOBAL_CONFIG: RealmConfig = RealmConfig::load_global_config();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn default_zone() -> String {
|
fn default_zone() -> String {
|
||||||
"clear".to_owned()
|
"clear".to_owned()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn default_realmfs() -> String {
|
||||||
|
"base".to_owned()
|
||||||
|
}
|
||||||
|
|
||||||
#[derive (Deserialize,Clone)]
|
#[derive (Deserialize,Clone)]
|
||||||
pub struct RealmConfig {
|
pub struct RealmConfig {
|
||||||
#[serde(default = "default_true", rename="use-shared-dir")]
|
#[serde(rename="use-shared-dir")]
|
||||||
use_shared_dir: bool,
|
use_shared_dir: Option<bool>,
|
||||||
|
|
||||||
#[serde(default, rename="use-ephemeral-home")]
|
#[serde(rename="use-ephemeral-home")]
|
||||||
use_ephemeral_home: bool,
|
use_ephemeral_home: Option<bool>,
|
||||||
|
|
||||||
#[serde(default = "default_true", rename="use-sound")]
|
#[serde(rename="use-sound")]
|
||||||
use_sound: bool,
|
use_sound: Option<bool>,
|
||||||
|
|
||||||
#[serde(default = "default_true", rename="use-x11")]
|
#[serde(rename="use-x11")]
|
||||||
use_x11: bool,
|
use_x11: Option<bool>,
|
||||||
|
|
||||||
#[serde(default = "default_true", rename="use-wayland")]
|
#[serde(rename="use-wayland")]
|
||||||
use_wayland: bool,
|
use_wayland: Option<bool>,
|
||||||
|
|
||||||
#[serde(default, rename="use-kvm")]
|
#[serde(rename="use-kvm")]
|
||||||
use_kvm: bool,
|
use_kvm: Option<bool>,
|
||||||
|
|
||||||
#[serde(default,rename="use-gpu")]
|
#[serde(rename="use-gpu")]
|
||||||
use_gpu: bool,
|
use_gpu: Option<bool>,
|
||||||
|
|
||||||
#[serde(default = "default_true", rename="use-network")]
|
#[serde(rename="use-network")]
|
||||||
use_network: bool,
|
use_network: Option<bool>,
|
||||||
|
|
||||||
|
#[serde(rename="network-zone")]
|
||||||
|
network_zone: Option<String>,
|
||||||
|
|
||||||
|
realmfs: Option<String>,
|
||||||
|
|
||||||
|
#[serde(rename="realmfs-write")]
|
||||||
|
realmfs_write: Option<bool>,
|
||||||
|
|
||||||
|
#[serde(skip)]
|
||||||
|
parent: Option<Box<RealmConfig>>,
|
||||||
|
|
||||||
#[serde(default = "default_zone", rename="network-zone")]
|
|
||||||
network_zone: String,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RealmConfig {
|
impl RealmConfig {
|
||||||
pub fn load_or_default(path: &Path) -> Result<RealmConfig> {
|
|
||||||
if path.exists() {
|
pub fn load_or_default<P: AsRef<Path>>(path: P) -> RealmConfig {
|
||||||
let s = load_as_string(&path)?;
|
match RealmConfig::load_config(path) {
|
||||||
let config = toml::from_str::<RealmConfig>(&s)?;
|
Some(config) => config,
|
||||||
Ok(config)
|
None => GLOBAL_CONFIG.clone()
|
||||||
} else {
|
|
||||||
Ok(RealmConfig::default())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn load_global_config() -> RealmConfig {
|
||||||
|
if let Some(mut global) = RealmConfig::load_config("/storage/realms/config") {
|
||||||
|
global.parent = Some(Box::new(RealmConfig::default()));
|
||||||
|
return global;
|
||||||
|
}
|
||||||
|
RealmConfig::default()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn load_config<P: AsRef<Path>>(path: P) -> Option<RealmConfig> {
|
||||||
|
if path.as_ref().exists() {
|
||||||
|
match fs::read_to_string(path.as_ref()) {
|
||||||
|
Ok(s) => return toml::from_str::<RealmConfig>(&s).ok(),
|
||||||
|
Err(e) => warn!("Error reading config file: {}", e),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
pub fn default() -> RealmConfig {
|
pub fn default() -> RealmConfig {
|
||||||
RealmConfig {
|
RealmConfig {
|
||||||
use_shared_dir: true,
|
use_shared_dir: Some(true),
|
||||||
use_ephemeral_home: false,
|
use_ephemeral_home: Some(false),
|
||||||
use_sound: true,
|
use_sound: Some(true),
|
||||||
use_x11: true,
|
use_x11: Some(true),
|
||||||
use_wayland: true,
|
use_wayland: Some(true),
|
||||||
use_kvm: false,
|
use_kvm: Some(false),
|
||||||
use_gpu: false,
|
use_gpu: Some(false),
|
||||||
use_network: true,
|
use_network: Some(true),
|
||||||
network_zone: default_zone(),
|
network_zone: Some(default_zone()),
|
||||||
|
realmfs: Some(default_realmfs()),
|
||||||
|
realmfs_write: Some(false),
|
||||||
|
parent: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn kvm(&self) -> bool {
|
pub fn kvm(&self) -> bool {
|
||||||
self.use_kvm
|
self.bool_value(|c| c.use_kvm)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn gpu(&self) -> bool {
|
pub fn gpu(&self) -> bool {
|
||||||
self.use_gpu
|
self.bool_value(|c| c.use_gpu)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn shared_dir(&self) -> bool {
|
pub fn shared_dir(&self) -> bool {
|
||||||
self.use_shared_dir
|
self.bool_value(|c| c.use_shared_dir)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn emphemeral_home(&self) -> bool {
|
pub fn emphemeral_home(&self) -> bool {
|
||||||
self.use_ephemeral_home
|
self.bool_value(|c| c.use_ephemeral_home)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sound(&self) -> bool {
|
pub fn sound(&self) -> bool {
|
||||||
self.use_sound
|
self.bool_value(|c| c.use_sound)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn x11(&self) -> bool {
|
pub fn x11(&self) -> bool {
|
||||||
self.use_x11
|
self.bool_value(|c| c.use_x11)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn wayland(&self) -> bool {
|
pub fn wayland(&self) -> bool {
|
||||||
self.use_wayland
|
self.bool_value(|c| c.use_network)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn network(&self) -> bool {
|
pub fn network(&self) -> bool {
|
||||||
self.use_network
|
self.bool_value(|c| c.use_network)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn network_zone(&self) -> &str {
|
pub fn network_zone(&self) -> &str {
|
||||||
&self.network_zone
|
self.str_value(|c| c.network_zone.as_ref())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn realmfs(&self) -> &str {
|
||||||
|
self.str_value(|c| c.realmfs.as_ref())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn realmfs_write(&self) -> bool {
|
||||||
|
self.bool_value(|c| c.realmfs_write)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn str_value<F>(&self, get: F) -> &str
|
||||||
|
where F: Fn(&RealmConfig) -> Option<&String>
|
||||||
|
{
|
||||||
|
if let Some(ref val) = get(self) {
|
||||||
|
return val
|
||||||
|
}
|
||||||
|
if let Some(ref parent) = self.parent {
|
||||||
|
if let Some(val) = get(parent) {
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
""
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bool_value<F>(&self, get: F) -> bool
|
||||||
|
where F: Fn(&RealmConfig) -> Option<bool>
|
||||||
|
{
|
||||||
|
if let Some(val) = get(self) {
|
||||||
|
return val
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(ref parent) = self.parent {
|
||||||
|
return get(parent).unwrap_or(false);
|
||||||
|
}
|
||||||
|
false
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn load_as_string(path: &Path) -> Result<String> {
|
|
||||||
let mut f = File::open(path)?;
|
|
||||||
let mut buffer = String::new();
|
|
||||||
f.read_to_string(&mut buffer)?;
|
|
||||||
Ok(buffer)
|
|
||||||
}
|
|
||||||
|
Loading…
Reference in New Issue
Block a user