forked from brl/citadel-tools
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::fs::File;
|
||||
use std::io::Read;
|
||||
use std::fs;
|
||||
use toml;
|
||||
use crate::Result;
|
||||
|
||||
fn default_true() -> bool {
|
||||
true
|
||||
lazy_static! {
|
||||
pub static ref GLOBAL_CONFIG: RealmConfig = RealmConfig::load_global_config();
|
||||
}
|
||||
|
||||
fn default_zone() -> String {
|
||||
"clear".to_owned()
|
||||
}
|
||||
|
||||
fn default_realmfs() -> String {
|
||||
"base".to_owned()
|
||||
}
|
||||
|
||||
#[derive (Deserialize,Clone)]
|
||||
pub struct RealmConfig {
|
||||
#[serde(default = "default_true", rename="use-shared-dir")]
|
||||
use_shared_dir: bool,
|
||||
#[serde(rename="use-shared-dir")]
|
||||
use_shared_dir: Option<bool>,
|
||||
|
||||
#[serde(default, rename="use-ephemeral-home")]
|
||||
use_ephemeral_home: bool,
|
||||
#[serde(rename="use-ephemeral-home")]
|
||||
use_ephemeral_home: Option<bool>,
|
||||
|
||||
#[serde(default = "default_true", rename="use-sound")]
|
||||
use_sound: bool,
|
||||
#[serde(rename="use-sound")]
|
||||
use_sound: Option<bool>,
|
||||
|
||||
#[serde(default = "default_true", rename="use-x11")]
|
||||
use_x11: bool,
|
||||
#[serde(rename="use-x11")]
|
||||
use_x11: Option<bool>,
|
||||
|
||||
#[serde(default = "default_true", rename="use-wayland")]
|
||||
use_wayland: bool,
|
||||
#[serde(rename="use-wayland")]
|
||||
use_wayland: Option<bool>,
|
||||
|
||||
#[serde(default, rename="use-kvm")]
|
||||
use_kvm: bool,
|
||||
#[serde(rename="use-kvm")]
|
||||
use_kvm: Option<bool>,
|
||||
|
||||
#[serde(default,rename="use-gpu")]
|
||||
use_gpu: bool,
|
||||
#[serde(rename="use-gpu")]
|
||||
use_gpu: Option<bool>,
|
||||
|
||||
#[serde(default = "default_true", rename="use-network")]
|
||||
use_network: bool,
|
||||
#[serde(rename="use-network")]
|
||||
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 {
|
||||
pub fn load_or_default(path: &Path) -> Result<RealmConfig> {
|
||||
if path.exists() {
|
||||
let s = load_as_string(&path)?;
|
||||
let config = toml::from_str::<RealmConfig>(&s)?;
|
||||
Ok(config)
|
||||
} else {
|
||||
Ok(RealmConfig::default())
|
||||
|
||||
pub fn load_or_default<P: AsRef<Path>>(path: P) -> RealmConfig {
|
||||
match RealmConfig::load_config(path) {
|
||||
Some(config) => config,
|
||||
None => GLOBAL_CONFIG.clone()
|
||||
}
|
||||
}
|
||||
|
||||
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 {
|
||||
RealmConfig {
|
||||
use_shared_dir: true,
|
||||
use_ephemeral_home: false,
|
||||
use_sound: true,
|
||||
use_x11: true,
|
||||
use_wayland: true,
|
||||
use_kvm: false,
|
||||
use_gpu: false,
|
||||
use_network: true,
|
||||
network_zone: default_zone(),
|
||||
use_shared_dir: Some(true),
|
||||
use_ephemeral_home: Some(false),
|
||||
use_sound: Some(true),
|
||||
use_x11: Some(true),
|
||||
use_wayland: Some(true),
|
||||
use_kvm: Some(false),
|
||||
use_gpu: Some(false),
|
||||
use_network: Some(true),
|
||||
network_zone: Some(default_zone()),
|
||||
realmfs: Some(default_realmfs()),
|
||||
realmfs_write: Some(false),
|
||||
parent: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn kvm(&self) -> bool {
|
||||
self.use_kvm
|
||||
self.bool_value(|c| c.use_kvm)
|
||||
}
|
||||
|
||||
pub fn gpu(&self) -> bool {
|
||||
self.use_gpu
|
||||
self.bool_value(|c| c.use_gpu)
|
||||
}
|
||||
|
||||
pub fn shared_dir(&self) -> bool {
|
||||
self.use_shared_dir
|
||||
self.bool_value(|c| c.use_shared_dir)
|
||||
}
|
||||
|
||||
pub fn emphemeral_home(&self) -> bool {
|
||||
self.use_ephemeral_home
|
||||
self.bool_value(|c| c.use_ephemeral_home)
|
||||
}
|
||||
|
||||
pub fn sound(&self) -> bool {
|
||||
self.use_sound
|
||||
self.bool_value(|c| c.use_sound)
|
||||
}
|
||||
|
||||
pub fn x11(&self) -> bool {
|
||||
self.use_x11
|
||||
self.bool_value(|c| c.use_x11)
|
||||
}
|
||||
|
||||
pub fn wayland(&self) -> bool {
|
||||
self.use_wayland
|
||||
self.bool_value(|c| c.use_network)
|
||||
}
|
||||
|
||||
pub fn network(&self) -> bool {
|
||||
self.use_network
|
||||
self.bool_value(|c| c.use_network)
|
||||
}
|
||||
|
||||
pub fn network_zone(&self) -> &str {
|
||||
&self.network_zone
|
||||
}
|
||||
self.str_value(|c| c.network_zone.as_ref())
|
||||
}
|
||||
|
||||
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)
|
||||
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
|
||||
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user