mirror of
https://github.com/edera-dev/sprout.git
synced 2025-12-19 15:40:16 +00:00
fix(autoconfigure): detect kernel and initramfs case-insensitive, even at the root
This commit is contained in:
@@ -7,7 +7,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && apt-get update && apt-get install -
|
|||||||
WORKDIR /work
|
WORKDIR /work
|
||||||
COPY sprout.efi /work/${EFI_NAME}.EFI
|
COPY sprout.efi /work/${EFI_NAME}.EFI
|
||||||
COPY sprout.toml /work/SPROUT.TOML
|
COPY sprout.toml /work/SPROUT.TOML
|
||||||
COPY kernel.efi /work/KERNEL.EFI
|
COPY kernel.efi /work/VMLINUZ
|
||||||
COPY shell.efi /work/SHELL.EFI
|
COPY shell.efi /work/SHELL.EFI
|
||||||
COPY xen.efi /work/XEN.EFI
|
COPY xen.efi /work/XEN.EFI
|
||||||
COPY xen.cfg /work/XEN.CFG
|
COPY xen.cfg /work/XEN.CFG
|
||||||
@@ -24,7 +24,7 @@ RUN truncate -s128MiB sprout.img && \
|
|||||||
mmd -i sprout.img ::/LOADER && \
|
mmd -i sprout.img ::/LOADER && \
|
||||||
mmd -i sprout.img ::/LOADER/ENTRIES && \
|
mmd -i sprout.img ::/LOADER/ENTRIES && \
|
||||||
mcopy -i sprout.img ${EFI_NAME}.EFI ::/EFI/BOOT/ && \
|
mcopy -i sprout.img ${EFI_NAME}.EFI ::/EFI/BOOT/ && \
|
||||||
mcopy -i sprout.img KERNEL.EFI ::/EFI/BOOT/ && \
|
mcopy -i sprout.img VMLINUZ ::/VMLINUZ && \
|
||||||
mcopy -i sprout.img SHELL.EFI ::/EFI/BOOT/ && \
|
mcopy -i sprout.img SHELL.EFI ::/EFI/BOOT/ && \
|
||||||
mcopy -i sprout.img XEN.EFI ::/EFI/BOOT/ && \
|
mcopy -i sprout.img XEN.EFI ::/EFI/BOOT/ && \
|
||||||
mcopy -i sprout.img XEN.CFG ::/EFI/BOOT/ && \
|
mcopy -i sprout.img XEN.CFG ::/EFI/BOOT/ && \
|
||||||
|
|||||||
@@ -4,10 +4,10 @@ version = 1
|
|||||||
default-entry = "kernel"
|
default-entry = "kernel"
|
||||||
|
|
||||||
[extractors.boot.filesystem-device-match]
|
[extractors.boot.filesystem-device-match]
|
||||||
has-item = "\\EFI\\BOOT\\kernel.efi"
|
has-item = "\\vmlinuz"
|
||||||
|
|
||||||
[actions.chainload-kernel]
|
[actions.chainload-kernel]
|
||||||
chainload.path = "$boot\\EFI\\BOOT\\kernel.efi"
|
chainload.path = "$boot\\vmlinuz"
|
||||||
chainload.options = ["console=hvc0"]
|
chainload.options = ["console=hvc0"]
|
||||||
chainload.linux-initrd = "$boot\\initramfs"
|
chainload.linux-initrd = "$boot\\initramfs"
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
title Boot Linux
|
title Boot Linux
|
||||||
linux /efi/boot/kernel.efi
|
linux /vmlinuz
|
||||||
options console=hvc0
|
options console=hvc0
|
||||||
initrd /initramfs
|
initrd /initramfs
|
||||||
|
|||||||
@@ -5,10 +5,10 @@ default-entry = "kernel"
|
|||||||
menu-timeout = 0
|
menu-timeout = 0
|
||||||
|
|
||||||
[extractors.boot.filesystem-device-match]
|
[extractors.boot.filesystem-device-match]
|
||||||
has-item = "\\EFI\\BOOT\\kernel.efi"
|
has-item = "\\vmlinuz"
|
||||||
|
|
||||||
[actions.chainload-kernel]
|
[actions.chainload-kernel]
|
||||||
chainload.path = "$boot\\EFI\\BOOT\\kernel.efi"
|
chainload.path = "$boot\\vmlinuz"
|
||||||
chainload.options = ["console=hvc0"]
|
chainload.options = ["console=hvc0"]
|
||||||
chainload.linux-initrd = "$boot\\initramfs"
|
chainload.linux-initrd = "$boot\\initramfs"
|
||||||
|
|
||||||
|
|||||||
@@ -6,9 +6,10 @@ use crate::generators::GeneratorDeclaration;
|
|||||||
use crate::generators::list::ListConfiguration;
|
use crate::generators::list::ListConfiguration;
|
||||||
use crate::utils;
|
use crate::utils;
|
||||||
use anyhow::{Context, Result};
|
use anyhow::{Context, Result};
|
||||||
|
use log::info;
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
use uefi::CString16;
|
use uefi::CString16;
|
||||||
use uefi::fs::{FileSystem, Path};
|
use uefi::fs::{FileSystem, Path, PathBuf};
|
||||||
use uefi::proto::device_path::DevicePath;
|
use uefi::proto::device_path::DevicePath;
|
||||||
use uefi::proto::device_path::text::{AllowShortcuts, DisplayOnly};
|
use uefi::proto::device_path::text::{AllowShortcuts, DisplayOnly};
|
||||||
|
|
||||||
@@ -17,7 +18,8 @@ const LINUX_CHAINLOAD_ACTION_PREFIX: &str = "linux-chainload-";
|
|||||||
|
|
||||||
/// The locations to scan for kernel pairs.
|
/// The locations to scan for kernel pairs.
|
||||||
/// We will check for symlinks and if this directory is a symlink, we will skip it.
|
/// We will check for symlinks and if this directory is a symlink, we will skip it.
|
||||||
const SCAN_LOCATIONS: &[&str] = &["/boot", "/"];
|
/// The empty string represents the root of the filesystem.
|
||||||
|
const SCAN_LOCATIONS: &[&str] = &["\\boot", "\\"];
|
||||||
|
|
||||||
/// Prefixes of kernel files to scan for.
|
/// Prefixes of kernel files to scan for.
|
||||||
const KERNEL_PREFIXES: &[&str] = &["vmlinuz"];
|
const KERNEL_PREFIXES: &[&str] = &["vmlinuz"];
|
||||||
@@ -39,6 +41,9 @@ fn scan_directory(filesystem: &mut FileSystem, path: &str) -> Result<Vec<KernelP
|
|||||||
// All the discovered kernel pairs.
|
// All the discovered kernel pairs.
|
||||||
let mut pairs = Vec::new();
|
let mut pairs = Vec::new();
|
||||||
|
|
||||||
|
// We have to special-case the root directory due to path logic in the uefi crate.
|
||||||
|
let is_root = path.is_empty() || path == "\\";
|
||||||
|
|
||||||
// Construct a filesystem path from the path string.
|
// Construct a filesystem path from the path string.
|
||||||
let path = CString16::try_from(path).context("unable to convert path to CString16")?;
|
let path = CString16::try_from(path).context("unable to convert path to CString16")?;
|
||||||
let path = Path::new(&path);
|
let path = Path::new(&path);
|
||||||
@@ -62,6 +67,16 @@ fn scan_directory(filesystem: &mut FileSystem, path: &str) -> Result<Vec<KernelP
|
|||||||
return Ok(pairs);
|
return Ok(pairs);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Create a new path used for joining file names below.
|
||||||
|
// All attempts to derive paths for the files in the directory should use this instead.
|
||||||
|
// The uefi crate does not handle push correctly for the root directory.
|
||||||
|
// It will add a second slash, which will cause our path logic to fail.
|
||||||
|
let path_for_join = if is_root {
|
||||||
|
PathBuf::new()
|
||||||
|
} else {
|
||||||
|
path.clone()
|
||||||
|
};
|
||||||
|
|
||||||
// For each item in the directory, find a kernel.
|
// For each item in the directory, find a kernel.
|
||||||
for item in directory {
|
for item in directory {
|
||||||
let item = item.context("unable to read directory item")?;
|
let item = item.context("unable to read directory item")?;
|
||||||
@@ -74,11 +89,14 @@ fn scan_directory(filesystem: &mut FileSystem, path: &str) -> Result<Vec<KernelP
|
|||||||
// Convert the name from a CString16 to a String.
|
// Convert the name from a CString16 to a String.
|
||||||
let name = item.file_name().to_string();
|
let name = item.file_name().to_string();
|
||||||
|
|
||||||
|
// Convert the name to lowercase to make all of this case-insensitive.
|
||||||
|
let name_for_match = name.to_lowercase();
|
||||||
|
|
||||||
// Find a kernel prefix that matches, if any.
|
// Find a kernel prefix that matches, if any.
|
||||||
let Some(prefix) = KERNEL_PREFIXES
|
// This is case-insensitive to ensure we pick up all possibilities.
|
||||||
.iter()
|
let Some(prefix) = KERNEL_PREFIXES.iter().find(|prefix| {
|
||||||
.find(|prefix| name == **prefix || name.starts_with(&format!("{}-", prefix)))
|
name_for_match == **prefix || name_for_match.starts_with(&format!("{}-", prefix))
|
||||||
else {
|
}) else {
|
||||||
// Skip over anything that doesn't match a kernel prefix.
|
// Skip over anything that doesn't match a kernel prefix.
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
@@ -96,8 +114,10 @@ fn scan_directory(filesystem: &mut FileSystem, path: &str) -> Result<Vec<KernelP
|
|||||||
let initramfs = format!("{}{}", prefix, suffix);
|
let initramfs = format!("{}{}", prefix, suffix);
|
||||||
let initramfs = CString16::try_from(initramfs.as_str())
|
let initramfs = CString16::try_from(initramfs.as_str())
|
||||||
.context("unable to convert initramfs name to CString16")?;
|
.context("unable to convert initramfs name to CString16")?;
|
||||||
let mut initramfs_path = path.clone();
|
let mut initramfs_path = path_for_join.clone();
|
||||||
initramfs_path.push(Path::new(&initramfs));
|
initramfs_path.push(Path::new(&initramfs));
|
||||||
|
|
||||||
|
info!("initramfs path: {:?} ({})", initramfs_path, initramfs);
|
||||||
// Check if the initramfs path exists, if it does, break out of the loop.
|
// Check if the initramfs path exists, if it does, break out of the loop.
|
||||||
if filesystem
|
if filesystem
|
||||||
.try_exists(&initramfs_path)
|
.try_exists(&initramfs_path)
|
||||||
@@ -108,7 +128,7 @@ fn scan_directory(filesystem: &mut FileSystem, path: &str) -> Result<Vec<KernelP
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Construct a kernel path from the kernel name.
|
// Construct a kernel path from the kernel name.
|
||||||
let mut kernel = path.clone();
|
let mut kernel = path_for_join.clone();
|
||||||
kernel.push(Path::new(&item.file_name()));
|
kernel.push(Path::new(&item.file_name()));
|
||||||
let kernel = kernel.to_string();
|
let kernel = kernel.to_string();
|
||||||
let initramfs = matched_initramfs_path.map(|initramfs_path| initramfs_path.to_string());
|
let initramfs = matched_initramfs_path.map(|initramfs_path| initramfs_path.to_string());
|
||||||
|
|||||||
Reference in New Issue
Block a user