From d0b43db8ed9b2d10a7dbcff567bcb53edf26d13e Mon Sep 17 00:00:00 2001 From: S4NKALP Date: Wed, 11 Mar 2026 23:32:03 +0545 Subject: [PATCH] feat(src/utils): add system utilities module Create utilities for root checking, file creation with permissions, display manager detection, and initramfs rebuild. - New Features - Introduce `system` module with `assert_root`, `create_file`, `get_display_manager`, and `rebuild_initramfs` functions. - Enhancements - Add comprehensive logging (info, debug, warn, error) and debug output. - Implement directory creation and executable permission handling. - Wrap initramfs rebuild commands with `systemd-inhibit` when available. - Bug Fixes - None --- src/utils/mod.rs | 1 + src/utils/system.rs | 109 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 110 insertions(+) create mode 100644 src/utils/mod.rs diff --git a/src/utils/mod.rs b/src/utils/mod.rs new file mode 100644 index 0000000..ac77f63 --- /dev/null +++ b/src/utils/mod.rs @@ -0,0 +1 @@ +pub mod system; diff --git a/src/utils/system.rs b/src/utils/system.rs index e69de29..23713d2 100644 --- a/src/utils/system.rs +++ b/src/utils/system.rs @@ -0,0 +1,109 @@ +use log::{debug, error, info, warn}; +use std::fs; +use std::os::unix::fs::PermissionsExt; +use std::path::Path; +use std::process::Command; + +pub fn assert_root() { + let output = Command::new("id").arg("-u").output(); + if let Ok(output) = output { + let is_root = String::from_utf8_lossy(&output.stdout).trim() == "0"; + if !is_root { + error!("This operation requires root privileges"); + std::process::exit(1); + } + } +} + +pub fn create_file(path: &str, content: &str, executable: bool) { + let path_obj = Path::new(path); + if let Some(parent) = path_obj.parent() { + if !parent.exists() { + if let Err(e) = fs::create_dir_all(parent) { + error!("Failed to create directories for '{}': {}", path, e); + return; + } + } + } + + match fs::write(path_obj, content) { + Ok(_) => { + info!("Created file {}", path); + debug!("{}", content); + + if executable { + if let Ok(mut perms) = fs::metadata(path_obj).map(|m| m.permissions()) { + perms.set_mode(perms.mode() | 0o111); + let _ = fs::set_permissions(path_obj, perms); + info!("Added execution privilege to file {}", path); + } + } + } + Err(e) => { + error!("Failed to create file '{}': {}", path, e); + } + } +} + +pub fn get_display_manager() -> Option { + if let Ok(content) = fs::read_to_string("/etc/systemd/system/display-manager.service") { + let re = regex::Regex::new(r"ExecStart=(.+)\n").unwrap(); + if let Some(cap) = re.captures(&content) { + let path = cap.get(1).unwrap().as_str(); + let dm = Path::new(path).file_name()?.to_string_lossy().to_string(); + info!("Found {} Display Manager", dm); + return Some(dm); + } + } + warn!("Display Manager detection is not available"); + None +} + +pub fn rebuild_initramfs() { + let mut command: Vec<&str> = Vec::new(); + + if Path::new("/ostree").exists() || Path::new("/sysroot/ostree").exists() { + println!("Rebuilding the initramfs with rpm-ostree..."); + command = vec!["rpm-ostree", "initramfs", "--enable", "--arg=--force"]; + } else if Path::new("/etc/debian_version").exists() { + command = vec!["update-initramfs", "-u", "-k", "all"]; + } else if Path::new("/etc/redhat-release").exists() || Path::new("/usr/bin/zypper").exists() { + command = vec!["dracut", "--force", "--regenerate-all"]; + } else if Path::new("/usr/lib/endeavouros-release").exists() && Path::new("/usr/bin/dracut").exists() { + command = vec!["dracut-rebuild"]; + } else if Path::new("/etc/altlinux-release").exists() { + command = vec!["make-initrd"]; + } else if Path::new("/etc/arch-release").exists() { + command = vec!["mkinitcpio", "-P"]; + } + + if let Ok(which) = Command::new("which").arg("systemd-inhibit").output() { + if which.status.success() { + let mut new_cmd = vec!["systemd-inhibit", "--who=lapctl", "--why", "Rebuilding initramfs", "--"]; + new_cmd.extend(command.iter()); + command = new_cmd; + } + } + + if !command.is_empty() { + println!("Rebuilding the initramfs..."); + let is_debug = log::log_enabled!(log::Level::Debug); + + let mut cmd = Command::new(command[0]); + cmd.args(&command[1..]); + + if !is_debug { + cmd.stdout(std::process::Stdio::null()); + cmd.stderr(std::process::Stdio::null()); + } + + match cmd.status() { + Ok(status) if status.success() => { + println!("Successfully rebuilt the initramfs!"); + } + _ => { + error!("An error occurred while rebuilding the initramfs"); + } + } + } +}