From c9e091be674f7c4db9e4884771911ab8941916f8 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 3 Jan 2024 21:58:52 +0100 Subject: [PATCH 1/4] Remove mention of /games This is no longer used since redox-os/redox!1397 --- test.toml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/test.toml b/test.toml index 02376f0154..39c0082dcf 100644 --- a/test.toml +++ b/test.toml @@ -137,11 +137,6 @@ path = "/usr/bin" data = "../bin" symlink = true -[[files]] -path = "/usr/games" -data = "../games" -symlink = true - [[files]] path = "/usr/include" data = "../include" From 5cdec468003c7213b7caf80d20d718ab32f6347f Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 4 Jan 2024 14:53:05 +0100 Subject: [PATCH 2/4] Reserialize filesystem.toml instead of copying the original config This will be necessary to handle including other configs from the config to use as these configs will not be copied. --- src/bin/installer.rs | 2 +- src/config/file.rs | 2 +- src/config/general.rs | 2 +- src/config/mod.rs | 2 +- src/config/package.rs | 2 +- src/config/user.rs | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/bin/installer.rs b/src/bin/installer.rs index eb43526e0f..b87130d59f 100644 --- a/src/bin/installer.rs +++ b/src/bin/installer.rs @@ -55,7 +55,7 @@ fn main() { // Add filesystem.toml to config config.files.push(redox_installer::FileConfig { path: "filesystem.toml".to_string(), - data: config_data, + data: toml::to_string_pretty(&config).unwrap(), ..Default::default() }); diff --git a/src/config/file.rs b/src/config/file.rs index 21565c3659..7672f908d5 100644 --- a/src/config/file.rs +++ b/src/config/file.rs @@ -29,7 +29,7 @@ fn chown>(path: P, uid: uid_t, gid: gid_t, recursive: bool) -> Re Ok(()) } -#[derive(Clone, Debug, Default, Deserialize)] +#[derive(Clone, Debug, Default, Deserialize, Serialize)] pub struct FileConfig { pub path: String, pub data: String, diff --git a/src/config/general.rs b/src/config/general.rs index 59099bbcdb..1ef4807a0c 100644 --- a/src/config/general.rs +++ b/src/config/general.rs @@ -1,4 +1,4 @@ -#[derive(Clone, Debug, Default, Deserialize)] +#[derive(Clone, Debug, Default, Deserialize, Serialize)] pub struct GeneralConfig { pub prompt: bool, // Allow config to specify cookbook recipe or binary package as default diff --git a/src/config/mod.rs b/src/config/mod.rs index 6172d4a86d..0348f1e49f 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -5,7 +5,7 @@ pub mod file; pub mod package; pub mod user; -#[derive(Clone, Debug, Default, Deserialize)] +#[derive(Clone, Debug, Default, Deserialize, Serialize)] pub struct Config { pub general: general::GeneralConfig, #[serde(default)] diff --git a/src/config/package.rs b/src/config/package.rs index f2df773caa..5f37196fe5 100644 --- a/src/config/package.rs +++ b/src/config/package.rs @@ -1,4 +1,4 @@ -#[derive(Clone, Debug, Deserialize)] +#[derive(Clone, Debug, Deserialize, Serialize)] #[serde(untagged)] pub enum PackageConfig { Empty, diff --git a/src/config/user.rs b/src/config/user.rs index 4886f4f968..3b82342048 100644 --- a/src/config/user.rs +++ b/src/config/user.rs @@ -1,4 +1,4 @@ -#[derive(Clone, Debug, Default, Deserialize)] +#[derive(Clone, Debug, Default, Deserialize, Serialize)] pub struct UserConfig { pub password: Option, pub uid: Option, From 1f4bbece4ae83e4c7725b1f7779ca027025091c6 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 4 Jan 2024 14:54:13 +0100 Subject: [PATCH 3/4] Introduce Config::from_file for parsing the config toml --- src/bin/installer.rs | 23 +++++------------------ src/bin/installer_tui.rs | 19 +------------------ src/config/mod.rs | 21 ++++++++++++++++++++- 3 files changed, 26 insertions(+), 37 deletions(-) diff --git a/src/bin/installer.rs b/src/bin/installer.rs index b87130d59f..bd87130d49 100644 --- a/src/bin/installer.rs +++ b/src/bin/installer.rs @@ -3,13 +3,13 @@ extern crate redox_installer; extern crate serde; extern crate toml; -use std::io::{Read, Write}; +use std::io::Write; use std::path::Path; use std::{env, fs, io, process}; use arg_parser::ArgParser; -use redox_installer::PackageConfig; +use redox_installer::{Config, PackageConfig}; fn main() { let stderr = io::stderr(); @@ -27,24 +27,11 @@ fn main() { // If not set on the command line or the filesystem config, then build packages from source. let repo_binary = parser.found("repo-binary"); - let mut config_data = String::new(); let mut config = if let Some(path) = parser.get_opt("config") { - match fs::File::open(&path) { - Ok(mut config_file) => match config_file.read_to_string(&mut config_data) { - Ok(_) => match toml::from_str(&config_data) { - Ok(config) => config, - Err(err) => { - writeln!(stderr, "installer: {}: failed to decode: {}", path, err).unwrap(); - process::exit(1); - } - }, - Err(err) => { - writeln!(stderr, "installer: {}: failed to read: {}", path, err).unwrap(); - process::exit(1); - } - }, + match Config::from_file(Path::new(&path)) { + Ok(config) => config, Err(err) => { - writeln!(stderr, "installer: {}: failed to open: {}", path, err).unwrap(); + writeln!(stderr, "installer: {err}").unwrap(); process::exit(1); } } diff --git a/src/bin/installer_tui.rs b/src/bin/installer_tui.rs index 74067a542e..fb58264e75 100644 --- a/src/bin/installer_tui.rs +++ b/src/bin/installer_tui.rs @@ -309,24 +309,7 @@ fn main() { efi_partition_size: None, }; let res = with_whole_disk(&disk_path, &disk_option, |mount_path| -> Result<(), failure::Error> { - let mut config: Config = { - let path = root_path.join("filesystem.toml"); - match fs::read_to_string(&path) { - Ok(config_data) => { - match toml::from_str(&config_data) { - Ok(config) => { - config - }, - Err(err) => { - return Err(format_err!("{}: failed to decode: {}", path.display(), err)); - } - } - }, - Err(err) => { - return Err(format_err!("{}: failed to read: {}", path.display(), err)); - } - } - }; + let mut config: Config = Config::from_file(&root_path.join("filesystem.toml"))?; // Copy filesystem.toml, which is not packaged let mut files = vec![ diff --git a/src/config/mod.rs b/src/config/mod.rs index 0348f1e49f..712803b2c8 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -1,7 +1,9 @@ use std::collections::BTreeMap; +use std::fs; +use std::path::Path; -pub mod general; pub mod file; +pub mod general; pub mod package; pub mod user; @@ -15,3 +17,20 @@ pub struct Config { #[serde(default)] pub users: BTreeMap, } + +impl Config { + pub fn from_file(path: &Path) -> Result { + let config = match fs::read_to_string(&path) { + Ok(config_data) => match toml::from_str(&config_data) { + Ok(config) => config, + Err(err) => { + return Err(format_err!("{}: failed to decode: {}", path.display(), err)); + } + }, + Err(err) => { + return Err(format_err!("{}: failed to read: {}", path.display(), err)); + } + }; + Ok(config) + } +} From adfee954840aa84b1e1a5605f0b5cf727bed324e Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 4 Jan 2024 15:08:49 +0100 Subject: [PATCH 4/4] Support including other config files from a config file This will allow significantly reducing the amount of duplication between all the different configs used by Redox OS. --- src/config/general.rs | 8 ++++++++ src/config/mod.rs | 47 +++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 53 insertions(+), 2 deletions(-) diff --git a/src/config/general.rs b/src/config/general.rs index 1ef4807a0c..7ed6c33f5e 100644 --- a/src/config/general.rs +++ b/src/config/general.rs @@ -5,3 +5,11 @@ pub struct GeneralConfig { pub repo_binary: Option, pub efi_partition_size: Option, //MiB } + +impl GeneralConfig { + pub(super) fn merge(&mut self, other: GeneralConfig) { + self.prompt = other.prompt; + self.repo_binary = other.repo_binary.or(self.repo_binary); + self.efi_partition_size = other.efi_partition_size.or(self.efi_partition_size); + } +} diff --git a/src/config/mod.rs b/src/config/mod.rs index 712803b2c8..e6ff206cb2 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -1,6 +1,7 @@ use std::collections::BTreeMap; use std::fs; -use std::path::Path; +use std::mem; +use std::path::{Path, PathBuf}; pub mod file; pub mod general; @@ -9,6 +10,8 @@ pub mod user; #[derive(Clone, Debug, Default, Deserialize, Serialize)] pub struct Config { + #[serde(default)] + pub include: Vec, pub general: general::GeneralConfig, #[serde(default)] pub packages: BTreeMap, @@ -20,7 +23,7 @@ pub struct Config { impl Config { pub fn from_file(path: &Path) -> Result { - let config = match fs::read_to_string(&path) { + let mut config: Config = match fs::read_to_string(&path) { Ok(config_data) => match toml::from_str(&config_data) { Ok(config) => config, Err(err) => { @@ -31,6 +34,46 @@ impl Config { return Err(format_err!("{}: failed to read: {}", path.display(), err)); } }; + + let config_dir = path.parent().unwrap(); + + let mut configs = mem::take(&mut config.include) + .into_iter() + .map(|path| Config::from_file(&config_dir.join(path))) + .collect::, failure::Error>>()?; + configs.push(config); // Put ourself last to ensure that it overwrites anything else. + + config = configs.remove(0); + + for other_config in configs { + config.merge(other_config); + } + Ok(config) } + + pub fn merge(&mut self, other: Config) { + assert!(self.include.is_empty()); + assert!(other.include.is_empty()); + + let Config { + include: _, + general: other_general, + packages: other_packages, + files: other_files, + users: other_users, + } = other; + + self.general.merge(other_general); + + for (package, package_config) in other_packages { + self.packages.insert(package, package_config); + } + + self.files.extend(other_files); + + for (user, user_config) in other_users { + self.users.insert(user, user_config); + } + } }