mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-03-26 02:11:53 +00:00
Feature/dry auto configure (#584)
* rename variables for clarity * return altered dep config * add utils system image, move compat into system-images * rename variables for clarity * sync integration and add debug instrumentation * debugging * add trace instrumentation * fix compilation for instrumentation * fix potential deadlocking behavior * fix import * fix dep check response return * hook back up to rpc, was overwritten in rebase * fix package command * get proper package config * testing dep config * version/volume for dep * vars * compat debugs * clean up * remove tar Co-authored-by: Chris Guida <chrisguida@gmail.com>
This commit is contained in:
@@ -4,7 +4,7 @@ use std::path::Path;
|
||||
|
||||
use beau_collector::BeauCollector;
|
||||
use embassy::config::action::SetResult;
|
||||
use embassy::config::{Config, spec};
|
||||
use embassy::config::{spec, Config};
|
||||
use linear_map::LinearMap;
|
||||
|
||||
pub mod rules;
|
||||
@@ -28,7 +28,10 @@ pub fn validate_configuration(
|
||||
match rule_check {
|
||||
Ok(_) => {
|
||||
// create temp config file
|
||||
serde_yaml::to_writer(std::fs::File::create(config_path.with_extension("tmp"))?, &config)?;
|
||||
serde_yaml::to_writer(
|
||||
std::fs::File::create(config_path.with_extension("tmp"))?,
|
||||
&config,
|
||||
)?;
|
||||
std::fs::rename(config_path.with_extension("tmp"), config_path)?;
|
||||
// return set result
|
||||
Ok(SetResult {
|
||||
@@ -37,7 +40,7 @@ pub fn validate_configuration(
|
||||
signal: Some(nix::sys::signal::SIGTERM),
|
||||
})
|
||||
}
|
||||
Err(e) => Err(anyhow!("{}", e))
|
||||
Err(e) => Err(anyhow!("{}", e)),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,28 +61,28 @@ pub fn validate_dependency_configuration(
|
||||
.bcollect::<Vec<_>>();
|
||||
match rule_check {
|
||||
Ok(_) => Ok(()),
|
||||
Err(e) => Err(anyhow!("{}", e))
|
||||
Err(e) => Err(anyhow!("{}", e)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn apply_dependency_configuration(
|
||||
name: &str,
|
||||
package_id: &str,
|
||||
config: Config,
|
||||
parent_name: &str,
|
||||
mut parent_config: Config,
|
||||
dependency_id: &str,
|
||||
mut dep_config: Config,
|
||||
rules_path: &Path,
|
||||
) -> Result<Config, anyhow::Error> {
|
||||
let rules: Vec<ConfigRuleEntryWithSuggestions> =
|
||||
serde_yaml::from_reader(std::fs::File::open(rules_path)?)?;
|
||||
let mut cfgs = LinearMap::new();
|
||||
cfgs.insert(parent_name, Cow::Owned(parent_config.clone()));
|
||||
cfgs.insert(name, Cow::Owned(config.clone()));
|
||||
cfgs.insert(dependency_id, Cow::Owned(dep_config.clone()));
|
||||
cfgs.insert(package_id, Cow::Owned(config.clone()));
|
||||
let rule_check = rules
|
||||
.into_iter()
|
||||
.map(|r| r.apply(parent_name, &mut parent_config, &mut cfgs))
|
||||
.map(|r| r.apply(dependency_id, &mut dep_config, &mut cfgs))
|
||||
.bcollect::<Vec<_>>();
|
||||
match rule_check {
|
||||
Ok(_) => Ok(parent_config),
|
||||
Ok(_) => Ok(dep_config),
|
||||
Err(e) => Err(anyhow!("{}", e)),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,8 +7,8 @@ use pest::Parser;
|
||||
use rand::SeedableRng;
|
||||
use serde_json::Value;
|
||||
|
||||
use embassy::config::Config;
|
||||
use embassy::config::util::STATIC_NULL;
|
||||
use embassy::config::Config;
|
||||
|
||||
#[derive(Parser)]
|
||||
#[grammar = "config/rule_parser.pest"]
|
||||
@@ -114,7 +114,7 @@ impl ConfigRuleEntry {
|
||||
cfgs: &LinearMap<&str, Cow<Config>>,
|
||||
) -> Result<(), anyhow::Error> {
|
||||
if !(self.rule.compiled)(cfg, cfgs) {
|
||||
return Err(anyhow::anyhow!("{}", self.description))
|
||||
return Err(anyhow::anyhow!("{}", self.description));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
@@ -514,9 +514,8 @@ fn compile_var_rec(mut ident: Pairs<Rule>) -> Option<Accessor> {
|
||||
Rule::sub_ident_regular_expr => {
|
||||
let idx = compile_str_expr(idx.into_inner().next().unwrap().into_inner());
|
||||
Box::new(move |v, dep_cfg| match v {
|
||||
Value::Object(o) => idx(&Config::default(), dep_cfg).map(|idx| {
|
||||
idx.and_then(|idx| o.get(&idx)).unwrap_or(&STATIC_NULL)
|
||||
}),
|
||||
Value::Object(o) => idx(&Config::default(), dep_cfg)
|
||||
.map(|idx| idx.and_then(|idx| o.get(&idx)).unwrap_or(&STATIC_NULL)),
|
||||
_ => VarRes::Exactly(&STATIC_NULL),
|
||||
})
|
||||
}
|
||||
@@ -605,16 +604,15 @@ fn compile_var_mut_rec(mut ident: Pairs<Rule>) -> Result<Option<AccessorMut>, fa
|
||||
predicate(&cfg, cfgs)
|
||||
})
|
||||
.next(),
|
||||
Value::Object(o) => {
|
||||
o.iter_mut()
|
||||
.map(|(_, item)| item)
|
||||
.filter(|item| {
|
||||
let mut cfg = Config::default();
|
||||
cfg.insert(item_var.clone(), (*item).clone());
|
||||
predicate(&cfg, cfgs)
|
||||
})
|
||||
.next()
|
||||
}
|
||||
Value::Object(o) => o
|
||||
.iter_mut()
|
||||
.map(|(_, item)| item)
|
||||
.filter(|item| {
|
||||
let mut cfg = Config::default();
|
||||
cfg.insert(item_var.clone(), (*item).clone());
|
||||
predicate(&cfg, cfgs)
|
||||
})
|
||||
.next(),
|
||||
_ => None,
|
||||
})
|
||||
}
|
||||
@@ -631,16 +629,15 @@ fn compile_var_mut_rec(mut ident: Pairs<Rule>) -> Result<Option<AccessorMut>, fa
|
||||
predicate(&cfg, cfgs)
|
||||
})
|
||||
.next_back(),
|
||||
Value::Object(o) => {
|
||||
o.iter_mut()
|
||||
.map(|(_, item)| item)
|
||||
.filter(|item| {
|
||||
let mut cfg = Config::default();
|
||||
cfg.insert(item_var.clone(), (*item).clone());
|
||||
predicate(&cfg, cfgs)
|
||||
})
|
||||
.next_back()
|
||||
}
|
||||
Value::Object(o) => o
|
||||
.iter_mut()
|
||||
.map(|(_, item)| item)
|
||||
.filter(|item| {
|
||||
let mut cfg = Config::default();
|
||||
cfg.insert(item_var.clone(), (*item).clone());
|
||||
predicate(&cfg, cfgs)
|
||||
})
|
||||
.next_back(),
|
||||
_ => None,
|
||||
})
|
||||
}
|
||||
@@ -780,7 +777,7 @@ fn compile_num_var(var: Pairs<Rule>) -> CompiledExpr<VarRes<f64>> {
|
||||
Value::Number(n) => n.as_f64().unwrap(),
|
||||
Value::String(s) => match s.parse() {
|
||||
Ok(n) => n,
|
||||
Err(_) => panic!("string cannot be parsed as an f64")
|
||||
Err(_) => panic!("string cannot be parsed as an f64"),
|
||||
},
|
||||
Value::Bool(b) => {
|
||||
if b {
|
||||
@@ -1045,11 +1042,12 @@ fn compile_value_expr(mut pairs: Pairs<Rule>) -> CompiledExpr<VarRes<Value>> {
|
||||
}
|
||||
Rule::num_expr => {
|
||||
let expr = compile_num_expr(expr.into_inner());
|
||||
Box::new(move |cfg, cfgs| expr(cfg, cfgs).map(|n| match
|
||||
serde_json::Number::from_f64(n) {
|
||||
Box::new(move |cfg, cfgs| {
|
||||
expr(cfg, cfgs).map(|n| match serde_json::Number::from_f64(n) {
|
||||
Some(a) => Value::Number(a),
|
||||
None => panic!("cannot coerce f64 into numberc type")
|
||||
}))
|
||||
None => panic!("cannot coerce f64 into numberc type"),
|
||||
})
|
||||
})
|
||||
}
|
||||
Rule::bool_expr => {
|
||||
let expr = compile_bool_expr(expr.into_inner());
|
||||
@@ -1244,10 +1242,8 @@ mod test {
|
||||
let mut dependent_cfg = Config::default();
|
||||
let mut dependency_cfg = Config::default();
|
||||
let mut cfgs = LinearMap::new();
|
||||
dependent_cfg
|
||||
.insert("foo".to_owned(), Value::String("bar".to_owned()));
|
||||
dependency_cfg
|
||||
.insert("foo".to_owned(), Value::String("bar!".to_owned()));
|
||||
dependent_cfg.insert("foo".to_owned(), Value::String("bar".to_owned()));
|
||||
dependency_cfg.insert("foo".to_owned(), Value::String("bar!".to_owned()));
|
||||
cfgs.insert("my-dependent", Cow::Borrowed(&dependent_cfg));
|
||||
cfgs.insert("my-dependency", Cow::Borrowed(&dependency_cfg));
|
||||
assert!((compile("'foo = '[my-dependent].foo + \"!\"")
|
||||
|
||||
@@ -238,7 +238,7 @@ fn inner_main() -> Result<(), anyhow::Error> {
|
||||
}
|
||||
}
|
||||
("auto-configure", Some(sub_m)) => {
|
||||
let parent_config = serde_yaml::from_reader(stdin())?;
|
||||
let dep_config = serde_yaml::from_reader(stdin())?;
|
||||
let config = serde_yaml::from_reader(
|
||||
File::open(
|
||||
Path::new(sub_m.value_of("mountpoint").unwrap()).join("start9/config.yaml"),
|
||||
@@ -246,13 +246,13 @@ fn inner_main() -> Result<(), anyhow::Error> {
|
||||
.unwrap(),
|
||||
)?;
|
||||
let rules_path = Path::new(sub_m.value_of("assets").unwrap());
|
||||
let name = sub_m.value_of("dependent_package_id").unwrap();
|
||||
let parent_name = sub_m.value_of("dependency_package_id").unwrap();
|
||||
let package_id = sub_m.value_of("dependent_package_id").unwrap();
|
||||
let dependency_id = sub_m.value_of("dependency_package_id").unwrap();
|
||||
match apply_dependency_configuration(
|
||||
name,
|
||||
package_id,
|
||||
config,
|
||||
parent_name,
|
||||
parent_config,
|
||||
dependency_id,
|
||||
dep_config,
|
||||
rules_path,
|
||||
) {
|
||||
Ok(a) => {
|
||||
|
||||
Reference in New Issue
Block a user