SHA256
Working on EFI boot records update
This commit is contained in:
@@ -22,7 +22,13 @@ use std::fs;
|
|||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
use time_format;
|
use time_format;
|
||||||
|
|
||||||
|
|
||||||
const SNAPS_DIR: &str = "/bzz_snaps";
|
const SNAPS_DIR: &str = "/bzz_snaps";
|
||||||
|
const EFI_BOOT_MOUNT_POINT: &str = "/beefi";
|
||||||
|
const EFI_PARTLABEL: &str = "bee-efi";
|
||||||
|
const BOOT_MENU_LABEL: &str = "Kira OS";
|
||||||
|
const UKI_IMAGE_NAME: &str = "\\EFI\\kira-linux-lts.efi";
|
||||||
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct CommandFailed {
|
pub struct CommandFailed {
|
||||||
@@ -268,3 +274,93 @@ pub fn sys_upgrade() -> Result<String, SysUpgradeError> {
|
|||||||
Err(ex) => Err(SysUpgradeError::PkgUpgradeErr((snap_time, ex))),
|
Err(ex) => Err(SysUpgradeError::PkgUpgradeErr((snap_time, ex))),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Gets device node aka /dev/sda1 from gpr partition label
|
||||||
|
/// blkid -s PARTLABEL --match-token PARTLABEL="bzz-primary"
|
||||||
|
pub fn find_partlabel(partlabel: &str) -> Result<Option<String>, ExecCommandError> {
|
||||||
|
let out = Command::new("/usr/bin/blkid")
|
||||||
|
.args([
|
||||||
|
"-s",
|
||||||
|
"PARTLABEL",
|
||||||
|
"-t",
|
||||||
|
format!("PARTLABEL=\"{}\"", partlabel).as_str(),
|
||||||
|
])
|
||||||
|
.output()?;
|
||||||
|
if out.status.success() {
|
||||||
|
let out_text = String::from_utf8(out.stdout)?;
|
||||||
|
|
||||||
|
let split_res = out_text.split_once(':').ok_or_else(|| {
|
||||||
|
ExecCommandError::Other(format!("Unexpected blkid output format: \"{}\"", out_text))
|
||||||
|
})?;
|
||||||
|
|
||||||
|
Ok(Some(split_res.0.to_string()))
|
||||||
|
} else {
|
||||||
|
if let Some(code) = out.status.code()
|
||||||
|
&& code == 2
|
||||||
|
{
|
||||||
|
Ok(None)
|
||||||
|
} else {
|
||||||
|
Err(ExecCommandError::Other(format!(
|
||||||
|
"Error while looking for partlabel={}: \"{}\"",
|
||||||
|
partlabel,
|
||||||
|
String::from_utf8(out.stderr).unwrap_or_else(|ex| ex.to_string())
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///
|
||||||
|
/// We need to use lsblk to find out parent device, or read topology from sysfs
|
||||||
|
/// (basename $(readlink -f /sys/class/block/sda1/..))
|
||||||
|
/// But lsblk approach looks more reasonable
|
||||||
|
/// NAME="/dev/nvme0n1p1" PARTLABEL="nyazefi" PARTN="1" PKNAME="/dev/nvme0n1"
|
||||||
|
/// lsblk -P -p -Q 'PARTLABEL=="nyazefi"' -o NAME,PARTLABEL,PARTN,PKNAME
|
||||||
|
/// Returns: touple of partition number and parent device as Strings (part_num, par_dev)
|
||||||
|
/// Returns Error if no efi partition was found
|
||||||
|
///
|
||||||
|
|
||||||
|
fn get_efi_part_info() -> Result<(String,String), ExecCommandError> {
|
||||||
|
use regex::Regex;
|
||||||
|
let re = Regex::new(r#"^PARTN="([0-9]+)" PKNAME="([0-9a-Z]+)"$"#).unwrap();
|
||||||
|
|
||||||
|
let lsblk_query = format!("PARTLABEL==\"{}\"", EFI_PARTLABEL);
|
||||||
|
let lsblk_args: Vec<&str> = vec!["-P", "-p", "-Q", &lsblk_query, "-o", "PARTN,PKNAME"];
|
||||||
|
let lsblk_res = exec_command_out("lsblk", &lsblk_args)?;
|
||||||
|
|
||||||
|
if let Some(captured) = re.captures(&lsblk_res) {
|
||||||
|
// let part_no = captured[1];
|
||||||
|
// let parent_dev = captured[2];
|
||||||
|
Ok((captured[1].to_string(), captured[2].to_string()))
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Err(ExecCommandError::Other(format!("No EFI partition (with PARTLABEL={}) was found!", EFI_PARTLABEL)))
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// efibootmgr
|
||||||
|
/// Assuming boot partition has "bee-efi" PARTLABEL
|
||||||
|
///
|
||||||
|
/// Generaly lets just add new record with date. Label modification not allways works?
|
||||||
|
/// May add deletion of old record latel
|
||||||
|
/// sudo efibootmgr --create --disk /dev/nvme0n1 --part 1 --label "Kira OS" --loader '\EFI\nyanlinux\kira-bzz.efi' --unicode 'initrd=\EFI\initrd.img'
|
||||||
|
|
||||||
|
pub fn boot_record_update(maybe_kernel_cmd: Option<&str>) -> Result<(), ExecCommandError> {
|
||||||
|
|
||||||
|
let (efi_partno, efi_parent_dev) = get_efi_part_info()?;
|
||||||
|
|
||||||
|
let local_date = time_format::strftime_local("%Y-%m-%d", time_format::now().unwrap()).unwrap();
|
||||||
|
let boot_label = format!("{} {}", BOOT_MENU_LABEL, local_date);
|
||||||
|
|
||||||
|
let mut efibootmgr_args: Vec<&str> = vec!["--create", "--disk", &efi_parent_dev, "--part", &efi_partno, "--label", &boot_label, "--loader", UKI_IMAGE_NAME];
|
||||||
|
if let Some(kernel_cmd) = maybe_kernel_cmd {
|
||||||
|
efibootmgr_args.push("--unicode");
|
||||||
|
efibootmgr_args.push(kernel_cmd);
|
||||||
|
}
|
||||||
|
exec_command("efibootmgr", &efibootmgr_args)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user