Merge branch 'integration-not-installation' into 'main'

Integration not Installation

See merge request crystal/software/tourmaline!2
chrooting
Trivernis Trivernis 2 years ago
commit 8f063cdef1

1
Cargo.lock generated

@ -3362,6 +3362,7 @@ dependencies = [
"dotenv", "dotenv",
"embed-nu", "embed-nu",
"lazy_static", "lazy_static",
"paste",
"serde", "serde",
"serde_json", "serde_json",
"thiserror", "thiserror",

@ -21,6 +21,7 @@ color-eyre = "0.6.2"
dotenv = "0.15.0" dotenv = "0.15.0"
embed-nu = "0.3.0" embed-nu = "0.3.0"
lazy_static = "1.4.0" lazy_static = "1.4.0"
paste = "1.0.9"
serde = { version = "1.0.145", features = ["derive"] } serde = { version = "1.0.145", features = ["derive"] }
serde_json = "1.0.86" serde_json = "1.0.86"
thiserror = "1.0.37" thiserror = "1.0.37"

@ -1,2 +1,37 @@
# tourmaline # tourmaline
Tourmaline is a (planned) agnostic, asynchronous and awesome installer framework Tourmaline is a (planned) agnostic, asynchronous and awesome installer framework
## Usage
Just run `cargo run -- help` or `trm help` for now.
## Scripts
Scripts for all supported distros are stored in the `config` folder of this repository.
Each distro has its own folder with several subfolders corresponding to all integration tasks.
```
<distro>
| <task>
| up.nu
| down.nu
| <task>
| up.nu
| down.nu
```
The `up.nu` scripts contain the required steps to apply the change described by the task.
This can include installing packages, creating configuration files and starting systemd units.
The `down.nu` scripts contain the steps to revert the change applied by a task. These scripts will
later be used to offer functionalities like reinstalling grub or changing installed kernels.
# License
> GPL v3
See LICENSE.

@ -0,0 +1,4 @@
# Reverts all system changes of `configure-locale`
def main [cfg] {
echo "Executing up task `configure-locale` with config" $cfg
}

@ -0,0 +1,4 @@
# Applies all system changes of `configure-locale`
def main [cfg] {
echo "Executing up task `configure-locale` with config" $cfg
}

@ -0,0 +1,4 @@
# Reverts all system changes of `configure-network`
def main [cfg] {
echo "Executing up task `configure-network` with config" $cfg
}

@ -0,0 +1,4 @@
# Applies all system changes of `configure-network`
def main [cfg] {
echo "Executing up task `configure-network` with config" $cfg
}

@ -0,0 +1,4 @@
# Reverts all system changes of `configure-unakite`
def main [cfg] {
echo "Executing up task `configure-unakite` with config" $cfg
}

@ -0,0 +1,4 @@
# Applies all system changes of `configure-unakite`
def main [cfg] {
echo "Executing up task `configure-unakite` with config" $cfg
}

@ -0,0 +1,4 @@
# Reverts all system changes of `create-partitions`
def main [cfg] {
echo "Executing up task `create-partitions` with config" $cfg
}

@ -0,0 +1,4 @@
# Applies all system changes of `create-partitions`
def main [cfg] {
echo "Executing up task `create-partitions` with config" $cfg
}

@ -1,6 +0,0 @@
def main [cfg] {
echo "Executing after Task with task config: " $cfg
echo "The global config is: " $TRM_CONFIG
}

@ -1,6 +0,0 @@
def main [cfg] {
echo "Executing before Task with task config: " $cfg
echo "The global config is: " $TRM_CONFIG
}

@ -1,6 +0,0 @@
def main [cfg] {
echo "Executing after Task with task config: " $cfg
echo "The global config is: " $TRM_CONFIG
}

@ -1,6 +0,0 @@
def main [cfg] {
echo "Executing before Task with task config: " $cfg
echo "The global config is: " $TRM_CONFIG
}

@ -1,6 +0,0 @@
def main [cfg] {
echo "Executing after Task with task config: " $cfg
echo "The global config is: " $TRM_CONFIG
}

@ -1,6 +0,0 @@
def main [cfg] {
echo "Executing before Task with task config: " $cfg
echo "The global config is: " $TRM_CONFIG
}

@ -1,6 +0,0 @@
def main [cfg] {
echo "Executing after Task with task config: " $cfg
echo "The global config is: " $TRM_CONFIG
}

@ -1,6 +0,0 @@
def main [cfg] {
echo "Executing before Task with task config: " $cfg
echo "The global config is: " $TRM_CONFIG
}

@ -1,6 +0,0 @@
def main [cfg] {
echo "Executing after Task with task config: " $cfg
echo "The global config is: " $TRM_CONFIG
}

@ -1,6 +0,0 @@
def main [cfg] {
echo "Executing before Task with task config: " $cfg
echo "The global config is: " $TRM_CONFIG
}

@ -1,6 +0,0 @@
def main [cfg] {
echo "Executing after Task with task config: " $cfg
echo "The global config is: " $TRM_CONFIG
}

@ -1,6 +0,0 @@
def main [cfg] {
echo "Executing before Task with task config: " $cfg
echo "The global config is: " $TRM_CONFIG
}

@ -1,6 +0,0 @@
def main [cfg] {
echo "Executing after Task with task config: " $cfg
echo "The global config is: " $TRM_CONFIG
}

@ -1,6 +0,0 @@
def main [cfg] {
echo "Executing before Task with task config: " $cfg
echo "The global config is: " $TRM_CONFIG
}

@ -1,6 +0,0 @@
def main [cfg] {
echo "Executing after Task with task config: " $cfg
echo "The global config is: " $TRM_CONFIG
}

@ -1,6 +0,0 @@
def main [cfg] {
echo "Executing before Task with task config: " $cfg
echo "The global config is: " $TRM_CONFIG
}

@ -1,6 +0,0 @@
def main [cfg] {
echo "Executing after Task with task config: " $cfg
echo "The global config is: " $TRM_CONFIG
}

@ -1,6 +0,0 @@
def main [cfg] {
echo "Executing before Task with task config: " $cfg
echo "The global config is: " $TRM_CONFIG
}

@ -1,6 +0,0 @@
def main [cfg] {
echo "Executing after Task with task config: " $cfg
echo "The global config is: " $TRM_CONFIG
}

@ -1,6 +0,0 @@
def main [cfg] {
echo "Executing before Task with task config: " $cfg
echo "The global config is: " $TRM_CONFIG
}

@ -1,6 +0,0 @@
def main [cfg] {
echo "Executing after Task with task config: " $cfg
echo "The global config is: " $TRM_CONFIG
}

@ -1,6 +0,0 @@
def main [cfg] {
echo "Executing before Task with task config: " $cfg
echo "The global config is: " $TRM_CONFIG
}

@ -1,6 +0,0 @@
def main [cfg] {
echo "Executing after Task with task config: " $cfg
echo "The global config is: " $TRM_CONFIG
}

@ -1,6 +0,0 @@
def main [cfg] {
echo "Executing before Task with task config: " $cfg
echo "The global config is: " $TRM_CONFIG
}

@ -1,6 +0,0 @@
def main [cfg] {
echo "Executing after Task with task config: " $cfg
echo "The global config is: " $TRM_CONFIG
}

@ -1,6 +0,0 @@
def main [cfg] {
echo "Executing before Task with task config: " $cfg
echo "The global config is: " $TRM_CONFIG
}

@ -1,6 +0,0 @@
def main [cfg] {
echo "Executing after Task with task config: " $cfg
echo "The global config is: " $TRM_CONFIG
}

@ -1,6 +0,0 @@
def main [cfg] {
echo "Executing before Task with task config: " $cfg
echo "The global config is: " $TRM_CONFIG
}

@ -0,0 +1,4 @@
# Reverts all system changes of `install-base`
def main [cfg] {
echo "Executing up task `install-base` with config" $cfg
}

@ -0,0 +1,4 @@
# Applies all system changes of `install-base`
def main [cfg] {
echo "Executing up task `install-base` with config" $cfg
}

@ -0,0 +1,4 @@
# Reverts all system changes of `install-bootloader`
def main [cfg] {
echo "Executing up task `install-bootloader` with config" $cfg
}

@ -0,0 +1,4 @@
# Applies all system changes of `install-bootloader`
def main [cfg] {
echo "Executing up task `install-bootloader` with config" $cfg
}

@ -0,0 +1,4 @@
# Reverts all system changes of `install-desktop`
def main [cfg] {
echo "Executing up task `install-desktop` with config" $cfg
}

@ -0,0 +1,4 @@
# Applies all system changes of `install-desktop`
def main [cfg] {
echo "Executing up task `install-desktop` with config" $cfg
}

@ -0,0 +1,4 @@
# Reverts all system changes of `install-extra-packages`
def main [cfg] {
echo "Executing up task `install-extra-packages` with config" $cfg
}

@ -0,0 +1,4 @@
# Applies all system changes of `install-extra-packages`
def main [cfg] {
echo "Executing up task `install-extra-packages` with config" $cfg
}

@ -0,0 +1,4 @@
# Reverts all system changes of `install-flatpak`
def main [cfg] {
echo "Executing up task `install-flatpak` with config" $cfg
}

@ -0,0 +1,4 @@
# Applies all system changes of `install-flatpak`
def main [cfg] {
echo "Executing up task `install-flatpak` with config" $cfg
}

@ -0,0 +1,4 @@
# Reverts all system changes of `install-kernels`
def main [cfg] {
echo "Executing up task `install-kernels` with config" $cfg
}

@ -0,0 +1,4 @@
# Applies all system changes of `install-kernels`
def main [cfg] {
echo "Executing up task `install-kernels` with config" $cfg
}

@ -0,0 +1,4 @@
# Reverts all system changes of `install-timeshift`
def main [cfg] {
echo "Executing up task `install-timeshift` with config" $cfg
}

@ -0,0 +1,4 @@
# Applies all system changes of `install-timeshift`
def main [cfg] {
echo "Executing up task `install-timeshift` with config" $cfg
}

@ -0,0 +1,4 @@
# Reverts all system changes of `install-zramd`
def main [cfg] {
echo "Executing up task `install-zramd` with config" $cfg
}

@ -0,0 +1,4 @@
# Applies all system changes of `install-zramd`
def main [cfg] {
echo "Executing up task `install-zramd` with config" $cfg
}

@ -1,5 +0,0 @@
def main [cfg] {
echo "Executing Task with config" $cfg
}

@ -1,5 +0,0 @@
def main [cfg] {
echo "Executing Task with config" $cfg
}

@ -1,5 +0,0 @@
def main [cfg] {
echo "Executing Task with config" $cfg
}

@ -1,5 +0,0 @@
def main [cfg] {
echo "Executing Task with config" $cfg
}

@ -1,5 +0,0 @@
def main [cfg] {
echo "Executing Task with config" $cfg
}

@ -1,5 +0,0 @@
def main [cfg] {
echo "Executing Task with config" $cfg
}

@ -1,5 +0,0 @@
def main [cfg] {
echo "Executing Task with config" $cfg
}

@ -1,5 +0,0 @@
def main [cfg] {
echo "Executing Task with config" $cfg
}

@ -1,5 +0,0 @@
def main [cfg] {
echo "Executing Task with config" $cfg
}

@ -1,5 +0,0 @@
def main [cfg] {
echo "Executing Task with config" $cfg
}

@ -1,5 +0,0 @@
def main [cfg] {
echo "Executing Task with config" $cfg
}

@ -1,5 +0,0 @@
def main [cfg] {
echo "Executing Task with config" $cfg
}

@ -1,5 +0,0 @@
def main [cfg] {
echo "Executing Task with config" $cfg
}

@ -1,5 +0,0 @@
def main [cfg] {
echo "Executing Task with config" $cfg
}

@ -0,0 +1,4 @@
# Reverts all system changes of `setup-root-user`
def main [cfg] {
echo "Executing up task `setup-root-user` with config" $cfg
}

@ -0,0 +1,4 @@
# Applies all system changes of `setup-root-user`
def main [cfg] {
echo "Executing up task `setup-root-user` with config" $cfg
}

@ -0,0 +1,4 @@
# Reverts all system changes of `setup-users`
def main [cfg] {
echo "Executing up task `setup-users` with config" $cfg
}

@ -0,0 +1,4 @@
# Applies all system changes of `setup-users`
def main [cfg] {
echo "Executing up task `setup-users` with config" $cfg
}

@ -1,7 +1,7 @@
use config::Config; use config::Config;
use error::{AppError, AppResult}; use error::{AppError, AppResult};
use scripting::{ use scripting::{
loader::{HookType, ScriptLoader}, loader::ScriptLoader,
script::{NuScript, Script}, script::{NuScript, Script},
}; };
use tasks::*; use tasks::*;
@ -13,15 +13,10 @@ pub mod tasks;
pub(crate) mod utils; pub(crate) mod utils;
pub use utils::generate_script_files; pub use utils::generate_script_files;
macro_rules! tasks { #[derive(Clone, Copy, Debug, PartialEq, PartialOrd)]
($($function:ident => $script:ident),+) => { pub enum TaskOperation {
$( Up,
#[tracing::instrument(level = "trace", skip(self))] Down,
pub async fn $function(&self, cfg: <$script as crate::scripting::script::Script>::Args) -> AppResult<()> {
self.execute_task::<$script>(cfg).await
}
)+
}
} }
pub struct TaskExecutor { pub struct TaskExecutor {
@ -29,6 +24,20 @@ pub struct TaskExecutor {
loader: ScriptLoader, loader: ScriptLoader,
} }
macro_rules! task_executors {
($($function:ident => $task:ident),+) => {
$(
#[tracing::instrument(level = "trace", skip(self))]
pub async fn $function(&self, operation: TaskOperation, cfg: <$task as crate::tasks::Task>::Config) -> AppResult<()> {
match operation {
TaskOperation::Up => self.execute_task::<<$task as crate::tasks::Task>::UpScript>(cfg).await,
TaskOperation::Down => self.execute_task::<<$task as crate::tasks::Task>::DownScript>(cfg).await,
}
}
)+
}
}
impl TaskExecutor { impl TaskExecutor {
/// Creates a new task executor with a given config /// Creates a new task executor with a given config
pub fn with_config(config: Config) -> Self { pub fn with_config(config: Config) -> Self {
@ -38,67 +47,66 @@ impl TaskExecutor {
} }
} }
tasks!( task_executors!(
setup_users => SetupUsersScript, setup_users => SetupUsersTask,
configure_network => ConfigureNetworkScript, configure_network => ConfigureNetworkTask,
configure_unakite => ConfigureUnakiteScript, configure_unakite => ConfigureUnakiteTask,
create_partitions => CreatePartitionsScript, create_partitions => CreatePartitionsTask,
install_base => InstallBaseScript, install_base => InstallBaseTask,
install_bootloader => InstallBootloaderScript, install_bootloader => InstallBootloaderTask,
install_desktop => InstallDesktopScript, install_desktop => InstallDesktopTask,
install_extra_packages => InstallExtraPackagesScript, install_extra_packages => InstallExtraPackagesTask,
install_flatpak => InstallFlatpakScript, install_flatpak => InstallFlatpakTask,
install_kernels => InstallKernelsScript, install_kernels => InstallKernelsTask,
install_timeshift => InstallTimeshiftScript, install_timeshift => InstallTimeshiftTask,
install_zramd => InstallZRamDScript, install_zramd => InstallZRamDTask,
setup_root_user => SetupRootUserScript, setup_root_user => SetupRootUserTask,
configure_locale => ConfigureLocaleScript configure_locale => ConfigureLocaleTask
); );
/// Installs the system from the given system configuration /// Installs the system from the given system configuration
#[tracing::instrument(level = "trace", skip(self))] #[tracing::instrument(level = "trace", skip(self))]
pub async fn install_from_config(&self) -> AppResult<()> { pub async fn install_from_config(&self) -> AppResult<()> {
let config = self.config.clone().ok_or(AppError::MissingConfig)?; let config = self.config.clone().ok_or(AppError::MissingConfig)?;
self.create_partitions(config.partitions).await?; self.create_partitions(TaskOperation::Up, config.partitions)
self.install_base(()).await?; .await?;
self.install_kernels(config.kernels).await?; self.install_base(TaskOperation::Up, ()).await?;
self.install_bootloader(config.bootloader).await?; self.install_kernels(TaskOperation::Up, config.kernels)
self.configure_locale(config.locale).await?; .await?;
self.configure_network(config.network).await?; self.install_bootloader(TaskOperation::Up, config.bootloader)
.await?;
self.configure_locale(TaskOperation::Up, config.locale)
.await?;
self.configure_network(TaskOperation::Up, config.network)
.await?;
if config.enable_zramd { if config.enable_zramd {
self.install_zramd(()).await?; self.install_zramd(TaskOperation::Up, ()).await?;
} }
if config.enable_timeshift { if config.enable_timeshift {
self.install_timeshift(()).await?; self.install_timeshift(TaskOperation::Up, ()).await?;
} }
if config.enable_flatpak { if config.enable_flatpak {
self.install_flatpak(()).await?; self.install_flatpak(TaskOperation::Up, ()).await?;
} }
self.setup_users(config.users).await?; self.setup_users(TaskOperation::Up, config.users).await?;
self.setup_root_user(config.root_user).await?; self.setup_root_user(TaskOperation::Up, config.root_user)
self.install_desktop(config.desktop).await?; .await?;
self.install_extra_packages(config.extra_packages).await?; self.install_desktop(TaskOperation::Up, config.desktop)
.await?;
self.install_extra_packages(TaskOperation::Up, config.extra_packages)
.await?;
if let Some(unakite) = config.unakite { if let Some(unakite) = config.unakite {
self.configure_unakite(unakite).await?; self.configure_unakite(TaskOperation::Up, unakite).await?;
} }
Ok(()) Ok(())
} }
async fn execute_task<S: Script>(&self, args: S::Args) -> AppResult<()> { async fn execute_task<S: Script>(&self, args: S::Args) -> AppResult<()> {
if let Some(pre_hook) = self.loader.load_hook::<S>(HookType::Pre) {
self.execute(pre_hook, args.clone()).await?;
}
let script = self.loader.load::<S>()?; let script = self.loader.load::<S>()?;
if let Some(post_hook) = self.loader.load_hook::<S>(HookType::Post) {
self.execute(script, args.clone()).await?;
self.execute(post_hook, args).await?;
} else {
self.execute(script, args.clone()).await?; self.execute(script, args.clone()).await?;
}
Ok(()) Ok(())
} }

@ -7,12 +7,6 @@ use super::script::{NuScript, Script};
/// A loader for nu script files /// A loader for nu script files
pub struct ScriptLoader { pub struct ScriptLoader {
script_dir: PathBuf, script_dir: PathBuf,
hook_dir: PathBuf,
}
pub enum HookType {
Pre,
Post,
} }
impl ScriptLoader { impl ScriptLoader {
@ -20,14 +14,13 @@ impl ScriptLoader {
pub fn new() -> Self { pub fn new() -> Self {
Self { Self {
script_dir: crate::utils::SCRIPT_PATH.to_owned(), script_dir: crate::utils::SCRIPT_PATH.to_owned(),
hook_dir: crate::utils::HOOK_PATH.to_owned(),
} }
} }
/// Loads the given script file /// Loads the given script file
#[tracing::instrument(level = "trace", skip_all)] #[tracing::instrument(level = "trace", skip_all)]
pub fn load<S: Script>(&self) -> AppResult<NuScript<S>> { pub fn load<S: Script>(&self) -> AppResult<NuScript<S>> {
let script_path = self.script_dir.join(S::get_name()); let script_path = self.script_dir.join(S::name());
if !script_path.exists() { if !script_path.exists() {
Err(AppError::ScriptNotFound(script_path)) Err(AppError::ScriptNotFound(script_path))
@ -35,18 +28,4 @@ impl ScriptLoader {
Ok(NuScript::new(script_path)) Ok(NuScript::new(script_path))
} }
} }
pub fn load_hook<S: Script>(&self, hook_type: HookType) -> Option<NuScript<S>> {
let script_name = match hook_type {
HookType::Pre => S::get_pre_hook(),
HookType::Post => S::get_post_hook(),
};
let script_path = self.hook_dir.join(script_name);
if !script_path.exists() {
None
} else {
Some(NuScript::new(script_path))
}
}
} }

@ -17,15 +17,7 @@ pub trait Script {
/// Returns the (expected) name of the script file /// Returns the (expected) name of the script file
/// This function is used by the loader to load the associated file /// This function is used by the loader to load the associated file
/// The name needs to include the file extension /// The name needs to include the file extension
fn get_name() -> &'static str; fn name() -> &'static str;
/// Returns the name of the script file that get's executed before
/// the actual script. This has to be the full file name including the extension.
fn get_pre_hook() -> &'static str;
/// Returns the name of the script file that get's executed after
/// the actual script. This has to be the full file name including the extension.
fn get_post_hook() -> &'static str;
} }
/// Script arguments that can be collected in a Vec to /// Script arguments that can be collected in a Vec to
@ -89,32 +81,3 @@ impl<S: Script> NuScript<S> {
fs::read_to_string(&self.path).await.map_err(AppError::from) fs::read_to_string(&self.path).await.map_err(AppError::from)
} }
} }
/// Defines a script
/// This macro doesn't accept a file extension for the script name
/// as it is reused for the hook name
#[macro_export]
macro_rules! script {
($script:ident {
file = $name:literal
args = $argtype:ident
}) => {
pub struct $script;
impl $crate::scripting::script::Script for $script {
type Args = $argtype;
fn get_name() -> &'static str {
concat!($name, ".nu")
}
fn get_pre_hook() -> &'static str {
concat!($name, ".pre.nu")
}
fn get_post_hook() -> &'static str {
concat!($name, ".post.nu")
}
}
};
}

@ -1,10 +1,10 @@
use embed_nu::rusty_value::*; use embed_nu::rusty_value::*;
use serde::Deserialize; use serde::Deserialize;
use crate::script; use crate::task;
script!(ConfigureLocaleScript { task!(ConfigureLocale {
file = "configure-locale" name = "configure-locale"
args = LocaleConfig args = LocaleConfig
}); });

@ -1,10 +1,10 @@
use embed_nu::rusty_value::*; use embed_nu::rusty_value::*;
use serde::Deserialize; use serde::Deserialize;
use crate::script; use crate::task;
script!(ConfigureNetworkScript { task!(ConfigureNetwork {
file = "configure-network" name = "configure-network"
args = NetworkConfig args = NetworkConfig
}); });

@ -3,10 +3,10 @@ use std::path::PathBuf;
use embed_nu::rusty_value::*; use embed_nu::rusty_value::*;
use serde::Deserialize; use serde::Deserialize;
use crate::script; use crate::task;
script!(ConfigureUnakiteScript { task!(ConfigureUnakite {
file = "configure-unakite" name = "configure-unakite"
args = UnakiteConfig args = UnakiteConfig
}); });

@ -3,10 +3,10 @@ use std::path::PathBuf;
use embed_nu::rusty_value::*; use embed_nu::rusty_value::*;
use serde::Deserialize; use serde::Deserialize;
use crate::script; use crate::task;
script!(CreatePartitionsScript { task!(CreatePartitions {
file = "create-partitions" name = "create-partitions"
args = PartitionsConfig args = PartitionsConfig
}); });

@ -1,7 +1,7 @@
use crate::script; use crate::task;
script!(InstallBaseScript { task!(InstallBase {
file = "install-base" name = "install-base"
args = InstallBaseArgs args = InstallBaseArgs
}); });

@ -3,10 +3,10 @@ use std::path::PathBuf;
use embed_nu::rusty_value::*; use embed_nu::rusty_value::*;
use serde::Deserialize; use serde::Deserialize;
use crate::script; use crate::task;
script!(InstallBootloaderScript { task!(InstallBootloader {
file = "install-bootloader" name = "install-bootloader"
args = BootloaderConfig args = BootloaderConfig
}); });

@ -1,10 +1,10 @@
use embed_nu::rusty_value::*; use embed_nu::rusty_value::*;
use serde::Deserialize; use serde::Deserialize;
use crate::script; use crate::task;
script!(InstallDesktopScript { task!(InstallDesktop {
file = "install-desktop" name = "install-desktop"
args = DesktopConfig args = DesktopConfig
}); });

@ -1,7 +1,7 @@
use crate::script; use crate::task;
script!(InstallExtraPackagesScript { task!(InstallExtraPackages {
file = "install-extra-packages" name = "install-extra-packages"
args = ExtraPackages args = ExtraPackages
}); });

@ -1,7 +1,7 @@
use crate::script; use crate::task;
script!(InstallFlatpakScript { task!(InstallFlatpak {
file = "install-flatpak" name = "install-flatpak"
args = FlatpakConfig args = FlatpakConfig
}); });

@ -1,10 +1,10 @@
use embed_nu::rusty_value::*; use embed_nu::rusty_value::*;
use serde::Deserialize; use serde::Deserialize;
use crate::script; use crate::task;
script!(InstallKernelsScript { task!(InstallKernels {
file = "install-kernels" name = "install-kernels"
args = KernelConfig args = KernelConfig
}); });

@ -1,7 +1,7 @@
use crate::script; use crate::task;
script!(InstallTimeshiftScript { task!(InstallTimeshift {
file = "install-timeshift" name = "install-timeshift"
args = TimeshiftConfig args = TimeshiftConfig
}); });

@ -1,7 +1,7 @@
use crate::script; use crate::task;
script!(InstallZRamDScript { task!(InstallZRamD {
file = "install-zramd" name = "install-zramd"
args = ZRamDConfig args = ZRamDConfig
}); });

@ -13,7 +13,7 @@ mod install_zramd;
mod setup_root_user; mod setup_root_user;
mod setup_users; mod setup_users;
use std::path::{Path, PathBuf}; use std::{fmt, path::PathBuf};
pub use configure_locale::*; pub use configure_locale::*;
pub use configure_network::*; pub use configure_network::*;
@ -30,57 +30,89 @@ pub use install_zramd::*;
pub use setup_root_user::*; pub use setup_root_user::*;
pub use setup_users::*; pub use setup_users::*;
use crate::scripting::script::Script; use crate::scripting::script::{Script, ScriptArgs};
pub struct TaskFiles { pub trait Task {
script: String, type Config: ScriptArgs + fmt::Debug + Clone;
pre_hook: String, type UpScript: Script<Args = Self::Config>;
post_hook: String, type DownScript: Script<Args = Self::Config>;
}
impl TaskFiles { fn name() -> &'static str;
pub fn script_path(&self, base: &Path) -> PathBuf {
base.join("scripts").join(&self.script)
} }
pub fn pre_hook_path(&self, base: &Path) -> PathBuf { /// Defines a script
base.join("hooks").join(&self.pre_hook) /// This macro doesn't accept a file extension for the script name
/// as it is reused for the hook name
#[macro_export]
macro_rules! task {
($task:ident {
name = $name:literal
args = $argtype:ident
}) => {
paste::item! {
pub struct [<$task Task>];
impl $crate::tasks::Task for [<$task Task>] {
type Config = $argtype;
type UpScript = [<$task UpScript>];
type DownScript = [<$task DownScript>];
#[inline]
fn name() -> &'static str {
$name
} }
}
pub struct [<$task UpScript>];
impl $crate::scripting::script::Script for [<$task UpScript>] {
type Args = $argtype;
pub fn post_hook_path(&self, base: &Path) -> PathBuf { #[inline]
base.join("hooks").join(&self.post_hook) fn name() -> &'static str {
"up.nu"
} }
} }
macro_rules! __all_tasks { pub struct [<$task DownScript>];
($($task:ident),+) => {
{ impl $crate::scripting::script::Script for [<$task DownScript>] {
vec![$( type Args = $argtype;
TaskFiles {
script: $task::get_name().into(), #[inline]
pre_hook: $task::get_pre_hook().into(), fn name() -> &'static str {
post_hook: $task::get_post_hook().into(), "down.nu"
}, }
)+] }
} }
}; };
} }
pub fn all_tasks() -> Vec<TaskFiles> { pub(crate) fn all_tasks() -> Vec<(&'static str, PathBuf, PathBuf)> {
__all_tasks!( macro_rules! task_scripts {
ConfigureLocaleScript, ($task:ident) => {{
ConfigureNetworkScript, let base = PathBuf::from($task::name());
ConfigureUnakiteScript, (
CreatePartitionsScript, $task::name(),
InstallBaseScript, base.join(<$task as Task>::UpScript::name()),
InstallBootloaderScript, base.join(<$task as Task>::DownScript::name()),
InstallDesktopScript,
InstallExtraPackagesScript,
InstallFlatpakScript,
InstallKernelsScript,
InstallTimeshiftScript,
InstallZRamDScript,
SetupRootUserScript,
SetupUsersScript
) )
}};
}
vec![
task_scripts!(ConfigureLocaleTask),
task_scripts!(ConfigureNetworkTask),
task_scripts!(ConfigureUnakiteTask),
task_scripts!(CreatePartitionsTask),
task_scripts!(InstallBaseTask),
task_scripts!(InstallBootloaderTask),
task_scripts!(InstallDesktopTask),
task_scripts!(InstallExtraPackagesTask),
task_scripts!(InstallFlatpakTask),
task_scripts!(InstallKernelsTask),
task_scripts!(InstallTimeshiftTask),
task_scripts!(InstallZRamDTask),
task_scripts!(SetupRootUserTask),
task_scripts!(SetupUsersTask),
]
} }

@ -1,10 +1,10 @@
use embed_nu::rusty_value::*; use embed_nu::rusty_value::*;
use serde::Deserialize; use serde::Deserialize;
use crate::script; use crate::task;
script!(SetupRootUserScript { task!(SetupRootUser {
file = "setup-root-user" name = "setup-root-user"
args = RootUserConfig args = RootUserConfig
}); });

@ -1,10 +1,10 @@
use embed_nu::rusty_value::*; use embed_nu::rusty_value::*;
use serde::Deserialize; use serde::Deserialize;
use crate::script; use crate::task;
script!(SetupUsersScript { task!(SetupUsers {
file = "setup-users" name = "setup-users"
args = UsersConfig args = UsersConfig
}); });

@ -4,7 +4,6 @@ use std::{env, path::PathBuf};
use tokio::fs; use tokio::fs;
use crate::error::AppResult; use crate::error::AppResult;
use crate::tasks::all_tasks; use crate::tasks::all_tasks;
const DEFAULT_CONFIG_DIR: &str = "/etc"; const DEFAULT_CONFIG_DIR: &str = "/etc";
@ -12,53 +11,44 @@ const DEFAULT_CONFIG_DIR: &str = "/etc";
lazy_static::lazy_static! { lazy_static::lazy_static! {
pub static ref CFG_PATH: PathBuf = env::var("TRM_CFG_PATH").map(PathBuf::from).unwrap_or_else(|_| PathBuf::from(DEFAULT_CONFIG_DIR).join("tourmaline")); pub static ref CFG_PATH: PathBuf = env::var("TRM_CFG_PATH").map(PathBuf::from).unwrap_or_else(|_| PathBuf::from(DEFAULT_CONFIG_DIR).join("tourmaline"));
pub static ref SCRIPT_PATH: PathBuf = CFG_PATH.join("scripts"); pub static ref SCRIPT_PATH: PathBuf = CFG_PATH.join("scripts");
pub static ref HOOK_PATH: PathBuf = CFG_PATH.join("hooks");
} }
pub async fn generate_script_files<P: AsRef<Path>>(output: P) -> AppResult<()> { pub async fn generate_script_files<P: AsRef<Path>>(output: P) -> AppResult<()> {
let script_path = output.as_ref().join("scripts"); let output = output.as_ref();
let hook_path = output.as_ref().join("hooks");
if !script_path.exists() {
fs::create_dir_all(&script_path).await?;
}
if !hook_path.exists() {
fs::create_dir_all(&hook_path).await?;
}
let tasks = all_tasks(); let tasks = all_tasks();
for task in tasks { for (name, up_script, down_script) in tasks {
fs::write( let script_dir = output.join(&name);
task.script_path(output.as_ref()),
r#" if !script_dir.exists() {
def main [cfg] { fs::create_dir_all(&script_dir).await?;
echo "Executing Task with config" $cfg
} }
"# let up_path = output.join(&up_script);
.to_string(), let down_path = output.join(down_script);
)
.await?;
fs::write( fs::write(
task.pre_hook_path(output.as_ref()), &up_path,
r#" format!(
def main [cfg] { r#"# Applies all system changes of `{name}`
echo "Executing before Task with task config: " $cfg def main [cfg] {{
echo "The global config is: " $TRM_CONFIG echo "Executing up task `{name}` with config" $cfg
} }}
"# "#
.to_string(), ),
) )
.await?; .await?;
fs::write( fs::write(
task.post_hook_path(output.as_ref()), &down_path,
r#" format!(
def main [cfg] { r#"# Reverts all system changes of `{name}`
echo "Executing after Task with task config: " $cfg def main [cfg] {{
echo "The global config is: " $TRM_CONFIG echo "Executing up task `{name}` with config" $cfg
} }}
"# "#
.to_string(), )
.trim(),
) )
.await?; .await?;
} }

Loading…
Cancel
Save