use std::io::Write; use config::InstallConfig; use nix::unistd::{Uid, getuid}; mod args; mod config; mod create_iso; mod install; mod pkg; use create_iso::create_iso; use install::install; fn is_root() -> bool { getuid() == Uid::from_raw(0) } fn run_command(cmd: &[String], input: Option<&str>, inherit: bool) -> (String, String) { println!("--> {}", cmd.join(" ")); let mut cmd_setup = std::process::Command::new(cmd[0].clone()); let mut cmd_setup = cmd_setup.args(cmd.into_iter().skip(1).collect::>()); if inherit { assert!(input.is_none()); cmd_setup = cmd_setup .stdout(std::process::Stdio::inherit()) .stdin(std::process::Stdio::inherit()); } else { cmd_setup = cmd_setup.stdout(std::process::Stdio::piped()); } if input.is_some() { cmd_setup = cmd_setup.stdin(std::process::Stdio::piped()); } let mut child = cmd_setup.spawn().unwrap(); if let Some(input) = input { let stdin = child.stdin.as_mut().unwrap(); stdin.write_all(input.as_bytes()).unwrap(); stdin.flush().unwrap(); } let status = child.wait_with_output().unwrap(); assert!(status.status.success()); let output = String::from_utf8(status.stdout).unwrap(); let stderr = String::from_utf8(status.stderr).unwrap(); if !stderr.trim().is_empty() { if !inherit { eprintln!("{}", stderr); } } if !inherit { println!("{}", output); } (output, stderr) } fn main() { println!("⚠️ Warning: This is an alpha version of the installer. DO NOT USE in PROD"); let args = args::get_args(); match args.subcommand() { Some(("create-iso", _)) => { create_iso(); std::process::exit(0); } Some(("create-tar", _)) => { println!("Tar creation is not yet supported"); unimplemented!() } Some(("create-img", install_args)) => { let config_file: &String = install_args.get_one("config").unwrap(); let config_content = std::fs::read_to_string(config_file); let conf: InstallConfig = match config_content { Ok(content) => match toml::from_str(&content) { Ok(config) => config, Err(e) => { eprintln!("Error: Could not deserialize TOML file. {e}"); std::process::exit(1); } }, Err(_) => { eprintln!("Error: Could not read config file."); std::process::exit(1); } }; println!("Installing to a disk image is not yet supported"); unimplemented!() } Some(("install", install_args)) => { let config_file: &String = install_args.get_one("config").unwrap(); let config_content = std::fs::read_to_string(config_file); let conf: InstallConfig = match config_content { Ok(content) => match toml::from_str(&content) { Ok(config) => config, Err(e) => { eprintln!("Error: Could not deserialize TOML file. {e}"); std::process::exit(1); } }, Err(_) => { eprintln!("Error: Could not read config file."); std::process::exit(1); } }; // TODO : Show config println!("Config: {conf:?}"); println!("\nDo you want to proceed with this configuration? (yes/no)"); let mut input = String::new(); std::io::stdout().flush().expect("Error flushing stdout."); std::io::stdin() .read_line(&mut input) .expect("Error reading input."); let input = input.trim().to_lowercase(); if input != "yes" { println!("Installation aborted."); std::process::exit(0); } // Run the install(conf) } _ => {} } }