diff --git a/configs/crystal/hooks/setup-users.post.nu b/configs/crystal/hooks/setup-users.post.nu index fbef04a..960f294 100644 --- a/configs/crystal/hooks/setup-users.post.nu +++ b/configs/crystal/hooks/setup-users.post.nu @@ -1,3 +1,5 @@ def main [cfg] { echo "Running after creating users" + $TRM_CONFIG | describe + $TRM_CONFIG } \ No newline at end of file diff --git a/src/config.rs b/src/config.rs index 0d0e0f9..f8c46b9 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,15 +1,65 @@ -use serde::Serialize; +use std::path::PathBuf; + +use serde::{Deserialize, Serialize}; use crate::tasks::{ - BootloaderConfig, DesktopConfig, LocaleConfig, NetworkConfig, PartitionsConfig, UsersConfig, + BootloaderConfig, BootloaderPreset, DesktopConfig, ExtraPackages, Kernel, KernelConfig, + LocaleConfig, NetworkConfig, Partitions, PartitionsConfig, RootUserConfig, UnakiteConfig, + UsersConfig, }; -#[derive(Clone, Debug, Serialize)] +#[derive(Clone, Debug, Deserialize, Serialize)] pub struct Config { - pub local: LocaleConfig, + pub locale: LocaleConfig, pub network: NetworkConfig, pub partitions: PartitionsConfig, pub bootloader: BootloaderConfig, + pub kernels: KernelConfig, pub desktop: DesktopConfig, pub users: UsersConfig, + pub root_user: RootUserConfig, + pub unakite: Option, + pub extra_packages: ExtraPackages, + pub enable_timeshift: bool, + pub enable_flatpak: bool, + pub enable_zramd: bool, +} + +impl Config { + pub(crate) fn empty() -> Self { + Self { + locale: LocaleConfig { + locale: Vec::new(), + keymap: String::new(), + timezone: String::new(), + }, + network: NetworkConfig { + hostname: String::new(), + ipv6_loopback: false, + }, + partitions: PartitionsConfig { + device: PathBuf::new(), + efi_partition: false, + partitions: Partitions::Auto, + }, + bootloader: BootloaderConfig { + preset: BootloaderPreset::GrubEfi, + location: PathBuf::new(), + }, + kernels: KernelConfig { + default: Kernel(String::new()), + additional: Vec::new(), + }, + desktop: DesktopConfig::KdePlasma, + users: UsersConfig { users: Vec::new() }, + root_user: RootUserConfig { + password: String::new(), + }, + unakite: None, + extra_packages: Vec::new(), + enable_timeshift: false, + enable_flatpak: false, + enable_zramd: false, + } + } } diff --git a/src/error.rs b/src/error.rs index ea84bed..d2564a4 100644 --- a/src/error.rs +++ b/src/error.rs @@ -9,7 +9,7 @@ pub type AppResult = std::result::Result; #[derive(Error, Diagnostic, Debug)] pub enum AppError { #[error("Miette error")] - #[diagnostic(code(tourmaline::error))] + #[diagnostic()] Miette(miette::Error), #[error("Error while evaluating nu script")] @@ -20,7 +20,7 @@ pub enum AppError { ScriptNotFound(PathBuf), #[diagnostic()] - #[error("Could not parse the source file")] + #[error("Could not parse the source file: {0}")] ParseError(#[from] nu_parser::ParseError), #[diagnostic()] @@ -29,6 +29,9 @@ pub enum AppError { #[error("Failed to execute script")] FailedToExecuteScript, + + #[error("Missing config")] + MissingConfig, } impl From for AppError { diff --git a/src/lib.rs b/src/lib.rs index 32d6082..a76454d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,7 +1,8 @@ use config::Config; -use error::AppResult; +use error::{AppError, AppResult}; use scripting::{ loader::{HookType, ScriptLoader}, + record::RecordValue, script::{NuScript, Script, ScriptArgs}, }; use tasks::*; @@ -12,11 +13,6 @@ pub(crate) mod scripting; pub mod tasks; pub(crate) mod utils; -pub struct TaskExecutor { - config: Option, - loader: ScriptLoader, -} - macro_rules! tasks { ($($function:ident => $script:ident),+) => { $( @@ -28,17 +24,64 @@ macro_rules! tasks { } } +pub struct TaskExecutor { + config: Option, + loader: ScriptLoader, +} + impl TaskExecutor { tasks!( setup_users => SetupUsersScript, configure_network => ConfigureNetworkScript, + configure_unakite => ConfigureUnakiteScript, create_partitions => CreatePartitionsScript, install_base => InstallBaseScript, install_bootloader => InstallBootloaderScript, install_desktop => InstallDesktopScript, - configure_local => ConfigureLocaleScript + install_extra_packages => InstallExtraPackagesScript, + install_flatpak => InstallFlatpakScript, + install_kernels => InstallKernelsScript, + install_timeshift => InstallTimeshiftScript, + install_zramd => InstallZRamDScript, + setup_root_user => SetupRootUserScript, + configure_locale => ConfigureLocaleScript ); + /// Installs the system from the given system configuration + #[tracing::instrument(level = "trace", skip(self))] + pub async fn install_from_config(&self) -> AppResult<()> { + let config = self + .config + .as_ref() + .ok_or_else(|| AppError::MissingConfig)?; + self.create_partitions(&config.partitions).await?; + self.install_base(&()).await?; + self.install_kernels(&config.kernels).await?; + self.install_bootloader(&config.bootloader).await?; + self.configure_locale(&config.locale).await?; + self.configure_network(&config.network).await?; + + if config.enable_zramd { + self.install_zramd(&()).await?; + } + if config.enable_timeshift { + self.install_timeshift(&()).await?; + } + if config.enable_flatpak { + self.install_flatpak(&()).await?; + } + self.setup_users(&config.users).await?; + self.setup_root_user(&config.root_user).await?; + self.install_desktop(&config.desktop).await?; + self.install_extra_packages(&config.extra_packages).await?; + + if let Some(unakite) = &config.unakite { + self.configure_unakite(unakite).await?; + } + + Ok(()) + } + async fn execute_task(&self, args: &S::Args) -> AppResult<()> { if let Some(pre_hook) = self.loader.load_hook::(HookType::Pre) { self.execute(pre_hook, args).await?; @@ -58,7 +101,7 @@ impl TaskExecutor { if let Some(cfg) = self.config.as_ref() { script.set_global_var("TRM_CONFIG", cfg.get_args()) } else { - &mut script + script.set_global_var("TRM_CONFIG", RecordValue::from(Config::empty().get_args())) } .set_global_var("TRM_VERSION", env!("CARGO_PKG_VERSION")) .execute(args) diff --git a/src/scripting/executor.rs b/src/scripting/executor.rs index ecb5b76..a2cb273 100644 --- a/src/scripting/executor.rs +++ b/src/scripting/executor.rs @@ -110,7 +110,7 @@ impl NuExecutor { // create a call to the main method wit the given arguments and execute it let call_block = create_call(main_id, args); - nu_engine::eval_block( + let data = nu_engine::eval_block( &engine_state, &mut stack, &call_block, @@ -118,6 +118,9 @@ impl NuExecutor { false, false, )?; + // the last print is returned as the result pipeline of the script so + // we need to print it manually + data.print(&mut engine_state, &mut stack, false, true); AppResult::Ok(()) }) diff --git a/src/tasks/configure_locale.rs b/src/tasks/configure_locale.rs index 9c7a19a..7168f28 100644 --- a/src/tasks/configure_locale.rs +++ b/src/tasks/configure_locale.rs @@ -1,4 +1,4 @@ -use serde::Serialize; +use serde::{Deserialize, Serialize}; use crate::script; @@ -7,7 +7,7 @@ script!(ConfigureLocaleScript { args = LocaleConfig }); -#[derive(Clone, Serialize, Debug)] +#[derive(Clone, Deserialize, Serialize, Debug)] pub struct LocaleConfig { pub locale: Vec, pub keymap: String, diff --git a/src/tasks/configure_network.rs b/src/tasks/configure_network.rs index d95b968..e267930 100644 --- a/src/tasks/configure_network.rs +++ b/src/tasks/configure_network.rs @@ -1,4 +1,4 @@ -use serde::Serialize; +use serde::{Deserialize, Serialize}; use crate::script; @@ -7,7 +7,7 @@ script!(ConfigureNetworkScript { args = NetworkConfig }); -#[derive(Clone, Debug, Serialize)] +#[derive(Clone, Debug, Deserialize, Serialize)] pub struct NetworkConfig { pub hostname: String, pub ipv6_loopback: bool, diff --git a/src/tasks/configure_unakite.rs b/src/tasks/configure_unakite.rs new file mode 100644 index 0000000..31b2651 --- /dev/null +++ b/src/tasks/configure_unakite.rs @@ -0,0 +1,18 @@ +use std::path::PathBuf; + +use serde::{Deserialize, Serialize}; + +use crate::script; + +script!(ConfigureUnakiteScript { + file = "configure-unakite" + args = UnakiteConfig +}); + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct UnakiteConfig { + pub root: PathBuf, + pub old_root: PathBuf, + pub efidir: PathBuf, + pub bootdev: PathBuf, +} diff --git a/src/tasks/create_partitions.rs b/src/tasks/create_partitions.rs index 2bfb7f9..b7cc39e 100644 --- a/src/tasks/create_partitions.rs +++ b/src/tasks/create_partitions.rs @@ -1,6 +1,6 @@ use std::path::PathBuf; -use serde::Serialize; +use serde::{Deserialize, Serialize}; use crate::script; @@ -9,27 +9,27 @@ script!(CreatePartitionsScript { args = PartitionsConfig }); -#[derive(Clone, Debug, Serialize)] +#[derive(Clone, Debug, Deserialize, Serialize)] pub struct PartitionsConfig { pub device: PathBuf, pub efi_partition: bool, pub partitions: Partitions, } -#[derive(Clone, Debug, Serialize)] +#[derive(Clone, Debug, Deserialize, Serialize)] pub enum Partitions { Auto, Manual(Vec), } -#[derive(Clone, Debug, Serialize)] +#[derive(Clone, Debug, Deserialize, Serialize)] pub struct Partition { pub mountpoint: PathBuf, pub blockdevice: PathBuf, pub filesystem: Option, } -#[derive(Clone, Debug, Serialize)] +#[derive(Clone, Debug, Deserialize, Serialize)] pub enum FileSystem { VFAT, BFS, diff --git a/src/tasks/install_bootloader.rs b/src/tasks/install_bootloader.rs index 7545bb1..0a49a12 100644 --- a/src/tasks/install_bootloader.rs +++ b/src/tasks/install_bootloader.rs @@ -1,6 +1,6 @@ use std::path::PathBuf; -use serde::Serialize; +use serde::{Deserialize, Serialize}; use crate::script; @@ -9,13 +9,13 @@ script!(InstallBootloaderScript { args = BootloaderConfig }); -#[derive(Clone, Debug, Serialize)] +#[derive(Clone, Debug, Deserialize, Serialize)] pub struct BootloaderConfig { - preset: BootloaderPreset, - location: PathBuf, + pub preset: BootloaderPreset, + pub location: PathBuf, } -#[derive(Clone, Debug, Serialize)] +#[derive(Clone, Debug, Deserialize, Serialize)] pub enum BootloaderPreset { GrubEfi, Legacy, diff --git a/src/tasks/install_desktop.rs b/src/tasks/install_desktop.rs index 910f067..64396cc 100644 --- a/src/tasks/install_desktop.rs +++ b/src/tasks/install_desktop.rs @@ -1,4 +1,4 @@ -use serde::Serialize; +use serde::{Deserialize, Serialize}; use crate::script; @@ -7,7 +7,7 @@ script!(InstallDesktopScript { args = DesktopConfig }); -#[derive(Clone, Debug, Serialize)] +#[derive(Clone, Debug, Deserialize, Serialize)] pub enum DesktopConfig { Onyx, KdePlasma, diff --git a/src/tasks/install_extra_packages.rs b/src/tasks/install_extra_packages.rs new file mode 100644 index 0000000..a36a62d --- /dev/null +++ b/src/tasks/install_extra_packages.rs @@ -0,0 +1,8 @@ +use crate::script; + +script!(InstallExtraPackagesScript { + file = "install-extra-packages" + args = ExtraPackages +}); + +pub type ExtraPackages = Vec; diff --git a/src/tasks/install_flatpak.rs b/src/tasks/install_flatpak.rs new file mode 100644 index 0000000..48ec09e --- /dev/null +++ b/src/tasks/install_flatpak.rs @@ -0,0 +1,8 @@ +use crate::script; + +script!(InstallFlatpakScript { + file = "install-flatpak" + args = FlatpakConfig +}); + +pub type FlatpakConfig = (); diff --git a/src/tasks/install_kernels.rs b/src/tasks/install_kernels.rs new file mode 100644 index 0000000..65eeb10 --- /dev/null +++ b/src/tasks/install_kernels.rs @@ -0,0 +1,17 @@ +use serde::{Deserialize, Serialize}; + +use crate::script; + +script!(InstallKernelsScript { + file = "install-kernels" + args = KernelConfig +}); + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct KernelConfig { + pub default: Kernel, + pub additional: Vec, +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct Kernel(pub String); diff --git a/src/tasks/install_timeshift.rs b/src/tasks/install_timeshift.rs new file mode 100644 index 0000000..4fb110a --- /dev/null +++ b/src/tasks/install_timeshift.rs @@ -0,0 +1,8 @@ +use crate::script; + +script!(InstallTimeshiftScript { + file = "install-timeshift" + args = TimeshiftConfig +}); + +pub type TimeshiftConfig = (); diff --git a/src/tasks/install_zramd.rs b/src/tasks/install_zramd.rs new file mode 100644 index 0000000..c268392 --- /dev/null +++ b/src/tasks/install_zramd.rs @@ -0,0 +1,8 @@ +use crate::script; + +script!(InstallZRamDScript { + file = "install-zramd" + args = ZRamDConfig +}); + +pub type ZRamDConfig = (); diff --git a/src/tasks/mod.rs b/src/tasks/mod.rs index 50a1c30..b624bce 100644 --- a/src/tasks/mod.rs +++ b/src/tasks/mod.rs @@ -1,15 +1,29 @@ mod configure_locale; mod configure_network; +mod configure_unakite; mod create_partitions; mod install_base; mod install_bootloader; mod install_desktop; +mod install_extra_packages; +mod install_flatpak; +mod install_kernels; +mod install_timeshift; +mod install_zramd; +mod setup_root_user; mod setup_users; pub use configure_locale::*; pub use configure_network::*; +pub use configure_unakite::*; pub use create_partitions::*; pub use install_base::*; pub use install_bootloader::*; pub use install_desktop::*; +pub use install_extra_packages::*; +pub use install_flatpak::*; +pub use install_kernels::*; +pub use install_timeshift::*; +pub use install_zramd::*; +pub use setup_root_user::*; pub use setup_users::*; diff --git a/src/tasks/setup_root_user.rs b/src/tasks/setup_root_user.rs new file mode 100644 index 0000000..de3de14 --- /dev/null +++ b/src/tasks/setup_root_user.rs @@ -0,0 +1,13 @@ +use serde::{Deserialize, Serialize}; + +use crate::script; + +script!(SetupRootUserScript { + file = "setup-root-user" + args = RootUserConfig +}); + +#[derive(Clone, Debug, Deserialize, Serialize)] +pub struct RootUserConfig { + pub password: String, +} diff --git a/src/tasks/setup_users.rs b/src/tasks/setup_users.rs index 3fb5152..6d4844c 100644 --- a/src/tasks/setup_users.rs +++ b/src/tasks/setup_users.rs @@ -1,4 +1,4 @@ -use serde::Serialize; +use serde::{Deserialize, Serialize}; use crate::script; @@ -7,12 +7,12 @@ script!(SetupUsersScript { args = UsersConfig }); -#[derive(Clone, Debug, Serialize)] +#[derive(Clone, Debug, Deserialize, Serialize)] pub struct UsersConfig { pub users: Vec, } -#[derive(Clone, Debug, Serialize)] +#[derive(Clone, Debug, Deserialize, Serialize)] pub struct User { pub name: String, pub password: String,