From 7963bafed92fbae5b08e7f89da228ea9de736e3d Mon Sep 17 00:00:00 2001 From: trivernis Date: Sun, 12 Mar 2023 15:34:43 +0100 Subject: [PATCH] Add fs creation and mounting for efi no hdds --- configs/crystal/create-partitions/up.nu | 37 +++++++++ src/task/commands/mod.rs | 2 + src/task/commands/run.rs | 6 ++ src/task/commands/with_cwd.rs | 102 ++++++++++++++++++++++++ src/task/exec_builder.rs | 3 +- 5 files changed, 149 insertions(+), 1 deletion(-) create mode 100644 src/task/commands/with_cwd.rs diff --git a/configs/crystal/create-partitions/up.nu b/configs/crystal/create-partitions/up.nu index 39a1653..bb6a526 100644 --- a/configs/crystal/create-partitions/up.nu +++ b/configs/crystal/create-partitions/up.nu @@ -1,8 +1,23 @@ +module utils { + export def is_ssd [device: string] { + $device =~ '^/dev/(nvme|mmcblk)' + } +} + module auto_partition { + use utils export def efi [device: string] { info "Creating efi partitions" efi_layout $device + + if utils is_ssd $device { + debug "Creating file systems for ssd" + efi_create_fs_ssd $device + } else { + debug "Creating file systems for hdd" + efi_create_fs_hdd $device + } } def efi_layout [device: string] { @@ -16,6 +31,28 @@ module auto_partition { debug "Root partition created" } + def efi_create_fs_ssd [device: string] { + } + + def efi_create_fs_hdd [device: string] { + let boot_part = $"($device)1"; + let root_part = $"($device)2" + + run mkfs.vfat -F32 $boot_part + run mkfs.btrfs -f $root_part + run mount $root_part /mnt + with-cwd /mnt { + run btrfs subvolume create @ + run btrfs subvolume create @home + } + run umount $root_part + run mount $root_part /mnt subvol=@ + mkdir /mnt/boot/efi + mkdir /mnt/home + run mount $root_part /mnt/home subvol=@home + run mount $boot_part /mnt/boot/efi + } + export def bios [device: string] { debug "Creating bios partitions" bios_layout $device diff --git a/src/task/commands/mod.rs b/src/task/commands/mod.rs index e4df48f..ae3824d 100644 --- a/src/task/commands/mod.rs +++ b/src/task/commands/mod.rs @@ -1,6 +1,8 @@ mod debug; mod info; mod run; +mod with_cwd; pub use debug::*; pub use info::*; pub use run::*; +pub use with_cwd::*; diff --git a/src/task/commands/run.rs b/src/task/commands/run.rs index f65de5f..36fe1f6 100644 --- a/src/task/commands/run.rs +++ b/src/task/commands/run.rs @@ -41,9 +41,15 @@ impl embed_nu::nu_protocol::engine::Command for RunCommand { ) -> Result { let executable: String = call.req(engine_state, stack, 0)?; let args: Vec = call.rest(engine_state, stack, 1)?; + let pwd = stack + .get_env_var(engine_state, "PWD") + .and_then(|v| v.as_string().ok()) + .unwrap_or_else(|| std::env::var("PWD").unwrap_or_else(|_| "/".into())); + tracing::debug!("Running {executable} {}", args.join(" ")); let mut cmd = Command::new(&executable) + .current_dir(pwd) .args(args) .stdout(Stdio::inherit()) .stderr(Stdio::inherit()) diff --git a/src/task/commands/with_cwd.rs b/src/task/commands/with_cwd.rs new file mode 100644 index 0000000..805318f --- /dev/null +++ b/src/task/commands/with_cwd.rs @@ -0,0 +1,102 @@ +use embed_nu::{ + nu_engine::eval_block_with_early_return, + nu_protocol::{engine::Closure, Signature, Span, SyntaxShape}, + CallExt, NewEmpty, Value, +}; + +#[derive(Clone)] +pub struct WithCwdCommand; + +impl embed_nu::nu_protocol::engine::Command for WithCwdCommand { + fn name(&self) -> &str { + "with-cwd" + } + + fn signature(&self) -> embed_nu::nu_protocol::Signature { + Signature::new("with-cwd") + .required( + "dir", + SyntaxShape::String, + "The directory to run the closure in", + ) + .required("closure", SyntaxShape::Any, "The closure to run") + .rest("rest", SyntaxShape::Any, "The parameters for the closure") + .category(embed_nu::nu_protocol::Category::Custom("Tourmalin".into())) + } + + fn usage(&self) -> &str { + "with-cwd [...]" + } + + fn run( + &self, + engine_state: &embed_nu::nu_protocol::engine::EngineState, + stack: &mut embed_nu::nu_protocol::engine::Stack, + call: &embed_nu::nu_protocol::ast::Call, + input: embed_nu::PipelineData, + ) -> Result { + let path: String = call.req(engine_state, stack, 0)?; + let block: Closure = call.req(engine_state, stack, 1)?; + let block_args: Vec = call.rest(engine_state, stack, 2)?; + + let block = engine_state.get_block(block.block_id); + let old_cwd = engine_state.get_env_var("PWD"); + tracing::debug!("Executing block with CWD {path}"); + stack.add_env_var("PWD".into(), Value::string(path, Span::empty())); + + let params: Vec<_> = block + .signature + .required_positional + .iter() + .chain(block.signature.optional_positional.iter()) + .collect(); + + for param in params.iter().zip(&block_args) { + if let Some(var_id) = param.0.var_id { + stack.add_var(var_id, param.1.clone()) + } + } + + if let Some(param) = &block.signature.rest_positional { + if block_args.len() > params.len() { + let mut args = vec![]; + + for r in block_args.into_iter().skip(params.len()) { + args.push(r); + } + + let span = if let Some(arg) = args.first() { + arg.span()? + } else { + call.head + }; + + stack.add_var( + param + .var_id + .expect("Internal error: rest positional parameter lacks var_id"), + Value::List { vals: args, span }, + ) + } + } + let result = eval_block_with_early_return( + engine_state, + stack, + block, + input, + call.redirect_stdout, + call.redirect_stdout, + ); + + stack.add_env_var( + "PWD".into(), + old_cwd.cloned().unwrap_or_else(|| { + std::env::current_dir() + .map(|d| Value::string(d.to_string_lossy(), Span::empty())) + .unwrap_or_else(|_| Value::nothing(Span::empty())) + }), + ); + + result + } +} diff --git a/src/task/exec_builder.rs b/src/task/exec_builder.rs index cf19afe..c0d9d1f 100644 --- a/src/task/exec_builder.rs +++ b/src/task/exec_builder.rs @@ -6,7 +6,7 @@ use std::fs; use crate::{distro::OSConfig, error::ScriptError, utils::CFG_PATH}; use miette::{Context, IntoDiagnostic, Result}; -use super::commands::{DebugCommand, InfoCommand, RunCommand}; +use super::commands::{DebugCommand, InfoCommand, RunCommand, WithCwdCommand}; #[derive(Clone)] pub struct ExecBuilder { @@ -27,6 +27,7 @@ impl ExecBuilder { .add_command(RunCommand)? .add_command(InfoCommand)? .add_command(DebugCommand)? + .add_command(WithCwdCommand)? .add_env_var("PWD", std::env::var("PWD").unwrap_or(String::from("/"))) .add_env_var( "PATH",