Merge branch 'finetune-chrooting' into 'main'
Fineune some aspect of chrooting (and test this thing) See merge request crystal/software/tourmaline!2main
commit
5c6ea5e9a4
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,86 @@
|
|||||||
|
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] {
|
||||||
|
run parted -s $device mklabel gpt
|
||||||
|
debug "Partition table created"
|
||||||
|
|
||||||
|
run parted -s $device mkpart fat32 0 300
|
||||||
|
debug "EFI partition created"
|
||||||
|
|
||||||
|
run parted -s $device mkpart primary btrfs 512MIB 100%
|
||||||
|
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 -o subvol=@
|
||||||
|
mkdir /mnt/boot/efi
|
||||||
|
mkdir /mnt/home
|
||||||
|
run mount $root_part /mnt/home -o subvol=@home
|
||||||
|
run mount $boot_part /mnt/boot/efi
|
||||||
|
}
|
||||||
|
|
||||||
|
export def bios [device: string] {
|
||||||
|
debug "Creating bios partitions"
|
||||||
|
bios_layout $device
|
||||||
|
}
|
||||||
|
|
||||||
|
def bios_layout [device: string] {
|
||||||
|
parted -s $device mklabel msdos
|
||||||
|
parted -s $device mkpart primary ext4 1MIB 512MIB
|
||||||
|
parted -s $device mkpart primary btrfs 512MIB 100%
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
# Applies all system changes of `create-partitions`
|
# Applies all system changes of `create-partitions`
|
||||||
def main [cfg] {
|
def main [cfg] {
|
||||||
echo "Executing up task `create-partitions` with config" $cfg
|
debug $"Creating partitions with config ($cfg)"
|
||||||
|
|
||||||
|
if $cfg.partitions == "Auto" {
|
||||||
|
info "Creating partitions automatically..."
|
||||||
|
use auto_partition
|
||||||
|
|
||||||
|
if $cfg.efi_partition {
|
||||||
|
auto_partition efi $cfg.device
|
||||||
|
} else {
|
||||||
|
auto_partition bios $cfg.device
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
info "Creating partitions manually"
|
||||||
|
}
|
||||||
|
|
||||||
|
info "Partitions created!"
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,69 @@
|
|||||||
let REQUIRES_CHROOT = true;
|
def install_base_packages [] {
|
||||||
|
(
|
||||||
|
run pacstrap /mnt
|
||||||
|
base
|
||||||
|
linux-firmware
|
||||||
|
systemd-sysvcompat
|
||||||
|
networkmanager
|
||||||
|
man-db
|
||||||
|
man-pages
|
||||||
|
texinfo
|
||||||
|
nano
|
||||||
|
sudo
|
||||||
|
curl
|
||||||
|
archlinux-keyring
|
||||||
|
|
||||||
|
# crystal base
|
||||||
|
crystal-core
|
||||||
|
crystal-branding
|
||||||
|
|
||||||
|
# crystal extras
|
||||||
|
crystal-first-setup
|
||||||
|
neofetch
|
||||||
|
btrfs-progs
|
||||||
|
which
|
||||||
|
base-devel
|
||||||
|
|
||||||
|
# chaotic aur
|
||||||
|
chaotic-keyring
|
||||||
|
chaotic-mirrorlist
|
||||||
|
|
||||||
|
# fonts
|
||||||
|
noto-fonts
|
||||||
|
noto-fonts-emoji
|
||||||
|
noto-fonts-cjk
|
||||||
|
noto-fonts-extra
|
||||||
|
ttf-nerd-fonts-symbols-common
|
||||||
|
ttf-firacode-nerd
|
||||||
|
ttf-liberation
|
||||||
|
|
||||||
|
# audio
|
||||||
|
pipewire
|
||||||
|
pipewire-pulse
|
||||||
|
pipewire-alsa
|
||||||
|
pipewire-jack
|
||||||
|
wireplumber
|
||||||
|
helvum
|
||||||
|
|
||||||
|
# utils
|
||||||
|
xterm
|
||||||
|
cups
|
||||||
|
cups-pdf
|
||||||
|
bluez
|
||||||
|
bluez-cups
|
||||||
|
ntfs-3g
|
||||||
|
bash-completion
|
||||||
|
zsh-completions
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
# Applies all system changes of `install-base`
|
# Applies all system changes of `install-base`
|
||||||
def main [cfg] {
|
def main [cfg] {
|
||||||
echo "Executing up task `install-base` with config" $cfg
|
debug $"installing base with config ($cfg)"
|
||||||
|
|
||||||
|
mkdir /mnt/etc
|
||||||
|
install_base_packages
|
||||||
|
cp /etc/pacman.conf /mnt/etc/pacman.conf
|
||||||
|
run bash -c 'genfstab -U /mnt >> /mnt/etc/fstab'
|
||||||
|
info "Base packages installed!"
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,41 @@
|
|||||||
|
let RUN_IN_CHROOT = true;
|
||||||
|
|
||||||
|
def install_grub_pkgs [] {
|
||||||
|
(run pacman -S --noconfirm
|
||||||
|
grub
|
||||||
|
efibootmgr
|
||||||
|
crystal-grub-theme
|
||||||
|
os-prober
|
||||||
|
crystal-branding
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
def install_grub_efi [location: string] {
|
||||||
|
debug $"Installing grub to ($location)"
|
||||||
|
install_grub_pkgs
|
||||||
|
|
||||||
|
(run grub-install
|
||||||
|
--target=x86_64-efi
|
||||||
|
--efi-directory $location
|
||||||
|
--bootloader-id=crystal
|
||||||
|
--removable
|
||||||
|
)
|
||||||
|
(run grub-install
|
||||||
|
--target=x86_64-efi
|
||||||
|
--efi-directory $location
|
||||||
|
--bootloader-id=crystal
|
||||||
|
)
|
||||||
|
"\nGRUB_THEME=\"/usr/share/grub/themes/crystal/theme.txt\"" | save --append /etc/default/grub
|
||||||
|
run grub-mkconfig -o /boot/grub/grub.cfg
|
||||||
|
}
|
||||||
|
|
||||||
# Applies all system changes of `install-bootloader`
|
# Applies all system changes of `install-bootloader`
|
||||||
def main [cfg] {
|
def main [cfg] {
|
||||||
echo "Executing up task `install-bootloader` with config" $cfg
|
debug "Installing bootloader with config ($cfg)"
|
||||||
|
|
||||||
|
if $cfg.preset == "GrubEfi" {
|
||||||
|
install_grub_efi $cfg.location
|
||||||
|
} else {
|
||||||
|
error make {msg: "Not implemented"}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,27 @@
|
|||||||
|
let SUPPORTED_KERNELS = ["linux", "linux-zen", "linus-hardened", "linux-lts"];
|
||||||
|
|
||||||
# Applies all system changes of `install-kernels`
|
# Applies all system changes of `install-kernels`
|
||||||
def main [cfg] {
|
def main [cfg] {
|
||||||
echo "Executing up task `install-kernels` with config" $cfg
|
debug $"installing kernels with config ($cfg)"
|
||||||
|
mut kernel = $cfg.default
|
||||||
|
|
||||||
|
if $kernel not-in $SUPPORTED_KERNELS {
|
||||||
|
warn $"Unsupported kernel ($kernel). Defaulting to 'linux' kernel"
|
||||||
|
$kernel = "linux"
|
||||||
|
}
|
||||||
|
|
||||||
|
run pacstrap /mnt $kernel
|
||||||
|
|
||||||
|
debug "Installing additional kernels"
|
||||||
|
|
||||||
|
$cfg.additional | each {|$k|
|
||||||
|
debug $"installing ($k)"
|
||||||
|
|
||||||
|
if $k in $SUPPORTED_KERNELS {
|
||||||
|
run pacstrap /mnt $k
|
||||||
|
} else {
|
||||||
|
warn $"Unsupported kernel ($k)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
info "Kernels installed!"
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
|
let RUN_IN_CHROOT = true;
|
||||||
# Applies all system changes of `setup-users`
|
# Applies all system changes of `setup-users`
|
||||||
def main [cfg] {
|
def main [cfg] {
|
||||||
echo "Executing up task `setup-users` with config" $cfg
|
echo "Executing up task `setup-users` with config" $cfg
|
||||||
echo $TRM_CONFIG
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,36 @@
|
|||||||
|
use embed_nu::{
|
||||||
|
nu_protocol::{engine::Command, Signature, SyntaxShape},
|
||||||
|
CallExt, PipelineData,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct DebugCommand;
|
||||||
|
|
||||||
|
impl Command for DebugCommand {
|
||||||
|
fn name(&self) -> &str {
|
||||||
|
"debug"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn signature(&self) -> embed_nu::nu_protocol::Signature {
|
||||||
|
Signature::new("debug")
|
||||||
|
.rest("rest", SyntaxShape::Any, "the message to print")
|
||||||
|
.category(embed_nu::nu_protocol::Category::Custom("Tourmaline".into()))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn usage(&self) -> &str {
|
||||||
|
"Prints the given message and values with debug severity (only when --verbose is passed to tourmaline)"
|
||||||
|
}
|
||||||
|
|
||||||
|
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<embed_nu::PipelineData, embed_nu::nu_protocol::ShellError> {
|
||||||
|
let args: Vec<String> = call.rest(engine_state, stack, 0)?;
|
||||||
|
tracing::debug!("{}", args.join(" "));
|
||||||
|
|
||||||
|
Ok(PipelineData::empty())
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
use embed_nu::{
|
||||||
|
nu_protocol::{engine::Command, Signature, SyntaxShape},
|
||||||
|
CallExt, PipelineData,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct InfoCommand;
|
||||||
|
|
||||||
|
impl Command for InfoCommand {
|
||||||
|
fn name(&self) -> &str {
|
||||||
|
"info"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn signature(&self) -> embed_nu::nu_protocol::Signature {
|
||||||
|
Signature::new("info")
|
||||||
|
.rest("rest", SyntaxShape::Any, "the message to print")
|
||||||
|
.category(embed_nu::nu_protocol::Category::Custom("Tourmaline".into()))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn usage(&self) -> &str {
|
||||||
|
"Prints the given message and values with info severity"
|
||||||
|
}
|
||||||
|
|
||||||
|
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<embed_nu::PipelineData, embed_nu::nu_protocol::ShellError> {
|
||||||
|
let args: Vec<String> = call.rest(engine_state, stack, 0)?;
|
||||||
|
tracing::info!("{}", args.join(" "));
|
||||||
|
|
||||||
|
Ok(PipelineData::empty())
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
mod debug;
|
||||||
|
mod info;
|
||||||
|
mod run;
|
||||||
|
mod warn;
|
||||||
|
mod with_cwd;
|
||||||
|
pub use debug::*;
|
||||||
|
pub use info::*;
|
||||||
|
pub use run::*;
|
||||||
|
pub use warn::*;
|
||||||
|
pub use with_cwd::*;
|
@ -0,0 +1,72 @@
|
|||||||
|
use std::{
|
||||||
|
io::Write,
|
||||||
|
process::{Command, Stdio},
|
||||||
|
};
|
||||||
|
|
||||||
|
use embed_nu::{
|
||||||
|
nu_protocol::{ShellError, Signature, SyntaxShape},
|
||||||
|
CallExt, PipelineData,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct RunCommand;
|
||||||
|
|
||||||
|
impl embed_nu::nu_protocol::engine::Command for RunCommand {
|
||||||
|
fn name(&self) -> &str {
|
||||||
|
"run"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn signature(&self) -> embed_nu::nu_protocol::Signature {
|
||||||
|
Signature::new("run")
|
||||||
|
.required("executable", SyntaxShape::String, "The executable to run")
|
||||||
|
.rest(
|
||||||
|
"rest",
|
||||||
|
SyntaxShape::String,
|
||||||
|
"the args for the given command",
|
||||||
|
)
|
||||||
|
.allows_unknown_args()
|
||||||
|
.category(embed_nu::nu_protocol::Category::Custom("Tourmalin".into()))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn usage(&self) -> &str {
|
||||||
|
"run <executable> [...<args>]"
|
||||||
|
}
|
||||||
|
|
||||||
|
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<embed_nu::PipelineData, embed_nu::nu_protocol::ShellError> {
|
||||||
|
let executable: String = call.req(engine_state, stack, 0)?;
|
||||||
|
let args: Vec<String> = 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())
|
||||||
|
.stdin(Stdio::piped())
|
||||||
|
.spawn()?;
|
||||||
|
|
||||||
|
let mut stdin = cmd.stdin.take().unwrap();
|
||||||
|
stdin.write_all(input.collect_string_strict(call.span())?.0.as_bytes())?;
|
||||||
|
|
||||||
|
if cmd.wait()?.success() {
|
||||||
|
Ok(PipelineData::empty())
|
||||||
|
} else {
|
||||||
|
Err(ShellError::ExternalCommand(
|
||||||
|
executable,
|
||||||
|
String::from("Is it written correctly?"),
|
||||||
|
call.span(),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
use embed_nu::{
|
||||||
|
nu_protocol::{engine::Command, Signature, SyntaxShape},
|
||||||
|
CallExt, PipelineData,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct WarnCommand;
|
||||||
|
|
||||||
|
impl Command for WarnCommand {
|
||||||
|
fn name(&self) -> &str {
|
||||||
|
"warn"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn signature(&self) -> embed_nu::nu_protocol::Signature {
|
||||||
|
Signature::new("warn")
|
||||||
|
.rest("rest", SyntaxShape::Any, "the warning to print")
|
||||||
|
.category(embed_nu::nu_protocol::Category::Custom("Tourmaline".into()))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn usage(&self) -> &str {
|
||||||
|
"Prints the given message and values with warning severity"
|
||||||
|
}
|
||||||
|
|
||||||
|
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<embed_nu::PipelineData, embed_nu::nu_protocol::ShellError> {
|
||||||
|
let args: Vec<String> = call.rest(engine_state, stack, 0)?;
|
||||||
|
tracing::warn!("{}", args.join(" "));
|
||||||
|
|
||||||
|
Ok(PipelineData::empty())
|
||||||
|
}
|
||||||
|
}
|
@ -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 <path> <block> [<args>...]"
|
||||||
|
}
|
||||||
|
|
||||||
|
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<embed_nu::PipelineData, embed_nu::nu_protocol::ShellError> {
|
||||||
|
let path: String = call.req(engine_state, stack, 0)?;
|
||||||
|
let block: Closure = call.req(engine_state, stack, 1)?;
|
||||||
|
let block_args: Vec<Value> = 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
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue