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:
Lucy C
2021-10-14 14:51:47 -06:00
committed by Aiden McClelland
parent 1ed7396dd1
commit effcd5ea57
5 changed files with 210 additions and 61 deletions

View File

@@ -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)),
}
}

View File

@@ -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 + \"!\"")

View File

@@ -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) => {