some fetching modules fixes and ItemData::sort_keys()

This commit is contained in:
Sebastian Moser
2024-10-06 11:14:54 +02:00
parent 5607dcaad2
commit d98585e026
3 changed files with 91 additions and 11 deletions

View File

@@ -5,6 +5,40 @@ use crate::item::IntoItemData;
use super::*; use super::*;
#[test]
fn test_sort_keys() -> MizeResult<()> {
let mut data = ItemData::from_toml(r#"
[hi]
test = 4
[config]
zzz = "hiiii"
hi = "hello from config/hi"
[config.test]
inner = "inner"
"#)?;
let data_sorted = ItemData::from_toml(r#"
[config]
hi = "hello from config/hi"
test = { inner = "inner" }
zzz = "hiiii"
[hi]
test = 4
"#)?;
data.sort_keys()?;
assert_eq!(data.to_json()?, data_sorted.to_json()?);
Ok(())
}
#[test] #[test]
fn test_get_module_hash() -> MizeResult<()> { fn test_get_module_hash() -> MizeResult<()> {
let mut instance = Instance::empty()?; let mut instance = Instance::empty()?;
@@ -18,9 +52,10 @@ fn test_get_module_hash() -> MizeResult<()> {
instance.set_blocking("0/config/selector", ItemData::from_toml(&selector_toml)?)?; instance.set_blocking("0/config/selector", ItemData::from_toml(&selector_toml)?)?;
let hash = get_module_hash(&mut instance, "String", ItemData::new())?; let (hash, selector) = get_module_hash(&mut instance, "String", ItemData::new())?;
test_println!("hash: {}", hash); test_println!("hash: {}", hash);
test_println!("selector: {}", selector);
assert_eq!(hash, "e96edf60216688314efc263c1aa8d6ce".to_owned()); assert_eq!(hash, "e96edf60216688314efc263c1aa8d6ce".to_owned());

View File

@@ -189,6 +189,10 @@ impl ItemData {
ItemData (cbor) ItemData (cbor)
} }
pub fn sort_keys(&mut self) -> MizeResult<()> {
item_data_sort_keys(&mut self.0)
}
pub fn null() -> CborValue { pub fn null() -> CborValue {
CborValue::Null CborValue::Null
} }
@@ -254,6 +258,38 @@ pub fn item_data_get_path(data: &CborValue, path: Vec<String>) -> MizeResult<&Cb
item_data_get_path(sub_data, path_iter.collect()) item_data_get_path(sub_data, path_iter.collect())
} }
pub fn item_data_sort_keys(data: &mut CborValue) -> MizeResult<()> {
// for a list, sort each item of the list
if data.is_array() {
for el in data.as_array_mut().unwrap().iter_mut() {
item_data_sort_keys(el)?
}
}
// sort the keys of a map
if data.is_map() {
let map: &mut Vec<(CborValue, CborValue)> = data.as_map_mut().unwrap();
//map.sort_by_key(|el| el.0);
map.sort_by(|a,b| {
match a.0.partial_cmp(&b.0) {
Some(val) => val,
None => {
// just say the two values are equal, if they can't be ordered
std::cmp::Ordering::Equal
}
}
});
// also sort every sub value
for (key, val) in map {
item_data_sort_keys(val)?
}
}
Ok(())
}
pub fn item_data_set_path(data: &mut CborValue, path: Vec<String>, data_to_set: &CborValue) -> MizeResult<()> { pub fn item_data_set_path(data: &mut CborValue, path: Vec<String>, data_to_set: &CborValue) -> MizeResult<()> {
//trace!("[ {} ] item_data_set_path()", "CALL".yellow()); //trace!("[ {} ] item_data_set_path()", "CALL".yellow());
//trace!("[ {} ] data: {}", "ARG".yellow(), data.clone().into_item_data()); //trace!("[ {} ] data: {}", "ARG".yellow(), data.clone().into_item_data());

View File

@@ -146,19 +146,21 @@ pub fn seconds_since_modification(path: &Path) -> MizeResult<u64> {
Ok(duration.as_secs()) Ok(duration.as_secs())
} }
pub fn get_module_hash(instance: &mut Instance, name: &str, mut options: ItemData) -> MizeResult<String> { pub fn get_module_hash(instance: &mut Instance, name: &str, mut options: ItemData) -> MizeResult<(String, String)> {
let mut selector_data = instance.get("0/config/selector")?.as_data_full()?; let mut selector_data = instance.get("0/config/selector")?.as_data_full()?;
selector_data.set_path("name", name)?; selector_data.set_path("modName", name)?;
selector_data.merge(options); selector_data.merge(options);
selector_data.sort_keys();
let selector_str = selector_data.to_json()?; let selector_str = selector_data.to_json()?;
let mut hasher = Sha256::new(); let mut hasher = Sha256::new();
hasher.update(selector_str.as_bytes()); hasher.update(selector_str.clone().as_bytes());
let result = hasher.finalize(); let result = hasher.finalize();
@@ -169,16 +171,23 @@ pub fn get_module_hash(instance: &mut Instance, name: &str, mut options: ItemDat
hex.truncate(32); hex.truncate(32);
return Ok(hex); return Ok((hex, selector_str));
} }
fn fetch_module(instance: &mut Instance, store_path: &str, module_url: &str, module_hash: &str, module_name: &str) -> MizeResult<()> { fn fetch_module(instance: &mut Instance, store_path: &str, module_url: &str, module_hash: &str, module_name: &str, module_selector: &str) -> MizeResult<()> {
let tmp_file_path_gz = format!("{}/{}.tar.gz", store_path, module_hash); let tmp_file_path_gz = format!("{}/{}.tar.gz", store_path, module_hash);
let mut tmp_gz_file = File::create(&tmp_file_path_gz)?; let mut tmp_gz_file = File::create(&tmp_file_path_gz)?;
http_req::request::get(format!("http://{}/mize/dist/{}-{}.tar.gz", module_url, module_hash, module_name), &mut tmp_gz_file)?; debug!("fetching module '{}' with hash: {}", module_name, module_hash);
let response = http_req::request::get(format!("http://{}/mize/dist/{}-{}.tar.gz", module_url, module_hash, module_name), &mut tmp_gz_file)?;
let code = response.status_code();
if code != 200.into() {
return Err(mize_err!("failed to get module '{}' with hash '{}' and selector: {}", module_name, module_hash, module_selector).msg(format!("the http request to fetch the module returned a status code of: {}", code)));
}
let tar = GzDecoder::new(tmp_gz_file); let tar = GzDecoder::new(tmp_gz_file);
let mut archive = Archive::new(tar); let mut archive = Archive::new(tar);
@@ -207,11 +216,11 @@ pub fn load_module(instance: &mut Instance, module_name: &str, path: Option<Path
let store_path = instance.get("0/config/store_path")?.value_string()?; let store_path = instance.get("0/config/store_path")?.value_string()?;
let module_hash = get_module_hash(instance, name, ItemData::new())?; let (module_hash, module_selector) = get_module_hash(instance, module_name, ItemData::new())?;
if !PathBuf::from(format!("{}/modules/{}", store_path, module_hash.as_str())).exists() { if !PathBuf::from(format!("{}/modules/{}", store_path, module_hash.as_str())).exists() {
// fetch module if it does not exist // fetch module if it does not exist
fetch_module(instance, store_path.as_str(), module_url.as_str(), module_hash.as_str(), module_name.as_str())?; fetch_module(instance, store_path.as_str(), module_url.as_str(), module_hash.as_str(), module_name, module_selector.as_str())?;
} }
// the module_path // the module_path
@@ -225,7 +234,7 @@ pub fn load_module(instance: &mut Instance, module_name: &str, path: Option<Path
let lib = unsafe { libloading::Library::new(module_path)? }; let lib = unsafe { libloading::Library::new(module_path)? };
let func: libloading::Symbol<unsafe extern "C" fn(&mut Box<dyn Module + Send + Sync>) -> ()> = unsafe { lib.get(format!("get_mize_module_{}", name).as_bytes())? }; let func: libloading::Symbol<unsafe extern "C" fn(&mut Box<dyn Module + Send + Sync>) -> ()> = unsafe { lib.get(format!("get_mize_module_{}", module_name).as_bytes())? };
let mut module: Box<dyn Module + Send + Sync> = Box::new(EmptyModule {}); let mut module: Box<dyn Module + Send + Sync> = Box::new(EmptyModule {});
@@ -235,7 +244,7 @@ pub fn load_module(instance: &mut Instance, module_name: &str, path: Option<Path
module.init(&instance); module.init(&instance);
modules_inner.insert(name.to_owned(), module); modules_inner.insert(module_name.to_owned(), module);
unsafe { unsafe {
// dropping the lib, would (i suspect) free all memory, of the library's code, which would // dropping the lib, would (i suspect) free all memory, of the library's code, which would