Merge branch 'config_include' into 'master'
Support including other config files from a config file See merge request redox-os/installer!29
This commit is contained in:
+6
-19
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -55,7 +42,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()
|
||||
});
|
||||
|
||||
|
||||
@@ -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![
|
||||
|
||||
+1
-1
@@ -29,7 +29,7 @@ fn chown<P: AsRef<Path>>(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,
|
||||
|
||||
@@ -1,7 +1,15 @@
|
||||
#[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
|
||||
pub repo_binary: Option<bool>,
|
||||
pub efi_partition_size: Option<u32>, //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);
|
||||
}
|
||||
}
|
||||
|
||||
+64
-2
@@ -1,12 +1,17 @@
|
||||
use std::collections::BTreeMap;
|
||||
use std::fs;
|
||||
use std::mem;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
pub mod general;
|
||||
pub mod file;
|
||||
pub mod general;
|
||||
pub mod package;
|
||||
pub mod user;
|
||||
|
||||
#[derive(Clone, Debug, Default, Deserialize)]
|
||||
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
|
||||
pub struct Config {
|
||||
#[serde(default)]
|
||||
pub include: Vec<PathBuf>,
|
||||
pub general: general::GeneralConfig,
|
||||
#[serde(default)]
|
||||
pub packages: BTreeMap<String, package::PackageConfig>,
|
||||
@@ -15,3 +20,60 @@ pub struct Config {
|
||||
#[serde(default)]
|
||||
pub users: BTreeMap<String, user::UserConfig>,
|
||||
}
|
||||
|
||||
impl Config {
|
||||
pub fn from_file(path: &Path) -> Result<Self, failure::Error> {
|
||||
let mut config: 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));
|
||||
}
|
||||
};
|
||||
|
||||
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::<Result<Vec<Config>, 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||
#[serde(untagged)]
|
||||
pub enum PackageConfig {
|
||||
Empty,
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
#[derive(Clone, Debug, Default, Deserialize)]
|
||||
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
|
||||
pub struct UserConfig {
|
||||
pub password: Option<String>,
|
||||
pub uid: Option<u32>,
|
||||
|
||||
Reference in New Issue
Block a user