navinstall/src/install/drives.rs
JMARyA 8d046e5852
All checks were successful
ci/woodpecker/push/build Pipeline was successful
fstrim #6
2025-03-26 21:32:49 +01:00

122 lines
3.1 KiB
Rust

use yansi::{Color, Paint};
use crate::{
config::DriveConfig,
linux::{run_command, systemd_service_enable},
print_status,
};
// TODO : Add support for using entire block device
/// Format the drives with the given config
pub fn format_drives(conf: &DriveConfig) {
disk_safe_check(&conf.root);
disk_safe_check(&conf.root);
// EFI (BOOT)
run_command(&["mkfs.vfat", "-F", "32", conf.boot.as_str()], None, false);
// ROOT
if let Some(pass) = &conf.encryption {
run_command(
&["cryptsetup", "-q", "luksFormat", conf.root.as_str()],
Some(&format!("{pass}\n")),
false,
);
run_command(
&["cryptsetup", "open", conf.root.as_str(), "root"],
Some(&format!("{pass}\n")),
false,
);
run_command(&["mkfs.ext4", "/dev/mapper/root"], None, false);
} else {
run_command(&["mkfs.ext4", conf.root.as_str()], None, false);
}
}
// MOUNT
/// Mount the drives at `/mnt`
pub fn mount_drives(conf: &DriveConfig) {
if conf.encryption.is_some() {
run_command(&["mount", "/dev/mapper/root", "/mnt"], None, false);
} else {
run_command(&["mount", conf.root.as_str(), "/mnt"], None, false);
}
run_command(
&[
"mount",
"--mkdir",
conf.boot.as_str(),
"/mnt/boot",
"-o",
"rw,nosuid,nodev,noatime,fmask=0137,dmask=0027",
],
None,
false,
);
}
/// Format a disk with EFI and BOOT partitions.
pub fn partition_disk(dev: &str) {
disk_safe_check(dev);
print_status(&format!("Formatting disk {dev}"));
let cmd = vec!["fdisk", dev];
let input = "g\nn\n1\n\n+1G\nt\n1\nn\n2\n\nw\n";
run_command(&cmd, Some(input), false);
}
/// Check if `dev` contains a filesystem and error if it does
pub fn disk_safe_check(dev: &str) {
if let Some(fs) = has_filesystem(dev) {
println!(
"{} Device {} already contains a filesystem {}",
"Error:".paint(Color::Red),
dev.paint(Color::Red),
fs.paint(Color::Blue)
);
std::process::exit(1);
}
}
pub fn has_filesystem(dev: &str) -> Option<String> {
let blockdevs: serde_json::Value =
serde_json::from_str(&run_command(&["lsblk", "--fs", "--json"], None, false).0).unwrap();
// TODO : Follow if symlink from /dev/disks
let dev = dev.trim_start_matches("/dev/");
let dev_entry = blockdevs
.as_object()
.unwrap()
.get("blockdevices")
.unwrap()
.as_array()
.unwrap()
.iter()
.find(|x| {
x.as_object()
.unwrap()
.get("name")
.unwrap()
.as_str()
.unwrap()
== dev
});
if let Some(dev_entry) = dev_entry {
if let Some(fs) = dev_entry.as_object().unwrap().get("fstype") {
return Some(fs.to_string());
}
}
None
}
pub fn setup_fstrim() {
print_status("Setting up FsTrim");
systemd_service_enable("fstrim.service");
}