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 { 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"); }