Split out parsing stuff as well, and test it

This commit is contained in:
Benjamin Leggett
2026-03-25 15:56:02 -04:00
parent 133476a0df
commit b53d21cea5
16 changed files with 467 additions and 164 deletions

View File

@@ -1,4 +1,3 @@
use crate::utils;
use alloc::string::ToString;
use alloc::{format, vec};
use anyhow::{Context, Result};
@@ -8,6 +7,7 @@ use edera_sprout_config::actions::chainload::ChainloadConfiguration;
use edera_sprout_config::entries::EntryDeclaration;
use edera_sprout_config::generators::GeneratorDeclaration;
use edera_sprout_config::generators::bls::BlsConfiguration;
use edera_sprout_parsing::unique_hash;
use uefi::cstr16;
use uefi::fs::{FileSystem, Path};
use uefi::proto::device_path::DevicePath;
@@ -37,7 +37,7 @@ pub fn scan(
root.push('/');
// Generate a unique hash of the root path.
let root_unique_hash = utils::unique_hash(&root);
let root_unique_hash = unique_hash(&root);
// Whether we have a loader.conf file.
let has_loader_conf = filesystem

View File

@@ -1,4 +1,3 @@
use crate::utils;
use alloc::collections::BTreeMap;
use alloc::string::{String, ToString};
use alloc::vec::Vec;
@@ -10,6 +9,10 @@ use edera_sprout_config::actions::chainload::ChainloadConfiguration;
use edera_sprout_config::entries::EntryDeclaration;
use edera_sprout_config::generators::GeneratorDeclaration;
use edera_sprout_config::generators::list::ListConfiguration;
use edera_sprout_parsing::{
LINUX_INITRAMFS_PREFIXES, LINUX_KERNEL_PREFIXES, initramfs_candidates, match_kernel_prefix,
unique_hash,
};
use uefi::CString16;
use uefi::fs::{FileSystem, Path, PathBuf};
use uefi::proto::device_path::DevicePath;
@@ -23,11 +26,6 @@ const LINUX_CHAINLOAD_ACTION_PREFIX: &str = "linux-chainload-";
/// The empty string represents the root of the filesystem.
const SCAN_LOCATIONS: &[&str] = &["\\boot", "\\"];
/// Prefixes of kernel files to scan for.
const KERNEL_PREFIXES: &[&str] = &["vmlinuz", "Image"];
/// Prefixes of initramfs files to match to.
const INITRAMFS_PREFIXES: &[&str] = &["initramfs", "initrd", "initrd.img"];
/// This is really silly, but if what we are booting is the Canonical stubble stub,
/// there is a chance it will assert that the load options are non-empty.
@@ -108,9 +106,7 @@ fn scan_directory(filesystem: &mut FileSystem, path: &str) -> Result<Vec<KernelP
// Find a kernel prefix that matches, if any.
// This is case-insensitive to ensure we pick up all possibilities.
let Some(prefix) = KERNEL_PREFIXES.iter().find(|prefix| {
name_for_match == **prefix || name_for_match.starts_with(&format!("{}-", prefix))
}) else {
let Some(prefix) = match_kernel_prefix(&name_for_match, LINUX_KERNEL_PREFIXES) else {
// Skip over anything that doesn't match a kernel prefix.
continue;
};
@@ -118,15 +114,14 @@ fn scan_directory(filesystem: &mut FileSystem, path: &str) -> Result<Vec<KernelP
// Acquire the suffix of the name, this will be used to match an initramfs.
let suffix = &name[prefix.len()..];
// Find a matching initramfs, if any.
let mut initramfs_prefix_iter = INITRAMFS_PREFIXES.iter();
// Find a matching initramfs by trying each candidate name, if any.
let mut candidates = initramfs_candidates(suffix, LINUX_INITRAMFS_PREFIXES);
let matched_initramfs_path = loop {
let Some(prefix) = initramfs_prefix_iter.next() else {
let Some(candidate) = candidates.next() else {
break None;
};
// Construct an initramfs path.
let initramfs = format!("{}{}", prefix, suffix);
let initramfs = CString16::try_from(initramfs.as_str())
let initramfs = CString16::try_from(candidate.as_str())
.context("unable to convert initramfs name to CString16")?;
let mut initramfs_path = path_for_join.clone();
initramfs_path.push(Path::new(&initramfs));
@@ -171,7 +166,7 @@ pub fn scan(
root.push('/');
// Generate a unique hash of the root path.
let root_unique_hash = utils::unique_hash(&root);
let root_unique_hash = unique_hash(&root);
// Scan all locations for kernel pairs, adding them to the list.
for location in SCAN_LOCATIONS {

View File

@@ -1,4 +1,3 @@
use crate::utils;
use alloc::string::ToString;
use alloc::{format, vec};
use anyhow::{Context, Result};
@@ -6,6 +5,7 @@ use edera_sprout_config::RootConfiguration;
use edera_sprout_config::actions::ActionDeclaration;
use edera_sprout_config::actions::chainload::ChainloadConfiguration;
use edera_sprout_config::entries::EntryDeclaration;
use edera_sprout_parsing::unique_hash;
use uefi::CString16;
use uefi::fs::{FileSystem, Path};
use uefi::proto::device_path::DevicePath;
@@ -45,7 +45,7 @@ pub fn scan(
root.push('/');
// Generate a unique hash of the root path.
let root_unique_hash = utils::unique_hash(&root);
let root_unique_hash = unique_hash(&root);
// Generate a unique name for the Windows chainload action.
let chainload_action_name = format!("{}{}", WINDOWS_CHAINLOAD_ACTION_PREFIX, root_unique_hash,);