Skip to content

Simplified disk builder #320

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 33 commits into from
Mar 12, 2023
Merged
Changes from 1 commit
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
164d015
Replace UefiBoot and BiosBoot with DiskImageBuilder
jasoncouture Jan 4, 2023
85779d3
Update DiskImageBuilder to remove lifetime requirement by cloning, an…
jasoncouture Jan 29, 2023
5786d9b
Reimplement BiosBoot and UefiBoot as wrappers around DiskImageBuilder
jasoncouture Jan 29, 2023
131130b
cargo fmt
jasoncouture Jan 29, 2023
2a7a25c
Add abi_efiapi feature
jasoncouture Jan 29, 2023
25536d2
Fix build errors due to rebase
jasoncouture Jan 29, 2023
b472297
Fix clippy failures
jasoncouture Jan 29, 2023
d1a2391
Remove unnecessary feature abi_efiapi
jasoncouture Jan 29, 2023
37c5539
Rename image_filename to image_path
jasoncouture Mar 4, 2023
2af185f
Create enum to hold different sources of file data
jasoncouture Mar 4, 2023
81e9d80
Update code to use FileDataSource
jasoncouture Mar 4, 2023
c0fab37
Format code
jasoncouture Mar 4, 2023
c193f9f
Add public method to set source directly
jasoncouture Mar 4, 2023
d4e9a5f
Format files after changes
jasoncouture Mar 4, 2023
42b5895
Refactor set methods to take destination first
jasoncouture Mar 4, 2023
dd87c00
Fix warnings with
jasoncouture Mar 4, 2023
3a7fcf7
Add documentation comments to set_file_* methods
jasoncouture Mar 4, 2023
502967b
Add documentation comments to FileDataSource and it's public methods.
jasoncouture Mar 4, 2023
ad34510
Remove code comments to pass doc test.
jasoncouture Mar 4, 2023
a93ce32
Final formatting pass
jasoncouture Mar 4, 2023
3ce9598
Remove DiskImageFile in favor of a BTreeMap
jasoncouture Mar 5, 2023
6b8d970
Improve docs
phil-opp Mar 12, 2023
5cabc0c
Make `set_file_source` private
phil-opp Mar 12, 2023
2923ad8
Take arguments as owned values in `set_file` and `set_file_contents`
phil-opp Mar 12, 2023
1a5cdf6
Reorder methods (public first)
phil-opp Mar 12, 2023
6e9b6a3
Document that only the kernel and ramdisk are loaded into memory
phil-opp Mar 12, 2023
c4714ce
Apply clippy suggestion
phil-opp Mar 12, 2023
075f22d
Take `FileDataSource` by reference in `create_fat_filesystem`
phil-opp Mar 12, 2023
692d39f
Serialize boot config to `Vec` directly
phil-opp Mar 12, 2023
bd5047c
Take file paths by value to avoid internal cloning
phil-opp Mar 12, 2023
f0328e6
Follow-up fixes for by-value arguments
phil-opp Mar 12, 2023
ac934c4
Adjust test runner for new owned arguments
phil-opp Mar 12, 2023
e3dd6fc
Fix unused import
phil-opp Mar 12, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Take file paths by value to avoid internal cloning
Also: Store file paths as `Cow<'static, str>` internally to avoid cloning for const paths.
  • Loading branch information
phil-opp committed Mar 12, 2023
commit bd5047c21ce98308c53b47554a3b1ddf55b3e1c8
36 changes: 24 additions & 12 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ mod fat;
mod file_data_source;

use std::{
borrow::Cow,
collections::BTreeMap,
fs,
path::{Path, PathBuf},
Expand All @@ -45,12 +46,12 @@ const CONFIG_FILE_NAME: &str = "boot.json";
///
/// It can currently create `MBR` (BIOS), `GPT` (UEFI), and `TFTP` (UEFI) images.
pub struct DiskImageBuilder {
files: BTreeMap<String, FileDataSource>,
files: BTreeMap<Cow<'static, str>, FileDataSource>,
}

impl DiskImageBuilder {
/// Create a new instance of DiskImageBuilder, with the specified kernel.
pub fn new(kernel: &Path) -> Self {
pub fn new(kernel: PathBuf) -> Self {
let mut obj = Self::empty();
obj.set_kernel(kernel);
obj
Expand All @@ -64,13 +65,19 @@ impl DiskImageBuilder {
}

/// Add or replace a kernel to be included in the final image.
pub fn set_kernel(&mut self, path: &Path) -> &mut Self {
self.set_file_source(KERNEL_FILE_NAME, FileDataSource::File(path.to_path_buf()))
pub fn set_kernel(&mut self, path: PathBuf) -> &mut Self {
self.set_file_source(
KERNEL_FILE_NAME.into(),
FileDataSource::File(path.to_path_buf()),
)
}

/// Add or replace a ramdisk to be included in the final image.
pub fn set_ramdisk(&mut self, path: &Path) -> &mut Self {
self.set_file_source(RAMDISK_FILE_NAME, FileDataSource::File(path.to_path_buf()))
pub fn set_ramdisk(&mut self, path: PathBuf) -> &mut Self {
self.set_file_source(
RAMDISK_FILE_NAME.into(),
FileDataSource::File(path.to_path_buf()),
)
}

/// Configures the runtime behavior of the bootloader.
Expand All @@ -83,16 +90,16 @@ impl DiskImageBuilder {
///
/// Note that the bootloader only loads the kernel and ramdisk files into memory on boot.
/// Other files need to be loaded manually by the kernel.
pub fn set_file_contents(&mut self, destination: &str, data: Vec<u8>) -> &mut Self {
self.set_file_source(destination, FileDataSource::Data(data))
pub fn set_file_contents(&mut self, destination: String, data: Vec<u8>) -> &mut Self {
self.set_file_source(destination.into(), FileDataSource::Data(data))
}

/// Add a file with the specified source file to the disk image
///
/// Note that the bootloader only loads the kernel and ramdisk files into memory on boot.
/// Other files need to be loaded manually by the kernel.
pub fn set_file(&mut self, destination: &str, file_path: PathBuf) -> &mut Self {
self.set_file_source(destination, FileDataSource::File(file_path))
self.set_file_source(destination.into(), FileDataSource::File(file_path))
}

#[cfg(feature = "bios")]
Expand Down Expand Up @@ -156,6 +163,8 @@ impl DiskImageBuilder {
#[cfg(feature = "uefi")]
/// Create a folder containing the needed files for UEFI TFTP/PXE booting.
pub fn create_uefi_tftp_folder(&self, tftp_path: &Path) -> anyhow::Result<()> {
use std::ops::Deref;

const UEFI_TFTP_BOOT_FILENAME: &str = "bootloader";
let bootloader_path = Path::new(env!("UEFI_BOOTLOADER_PATH"));
fs::create_dir_all(tftp_path)
Expand All @@ -171,7 +180,7 @@ impl DiskImageBuilder {
})?;

for f in &self.files {
let to = tftp_path.join(f.0.clone());
let to = tftp_path.join(f.0.deref());

let mut new_file = fs::OpenOptions::new()
.read(true)
Expand All @@ -187,8 +196,11 @@ impl DiskImageBuilder {
}

/// Add a file source to the disk image
fn set_file_source(&mut self, destination: &str, source: FileDataSource) -> &mut Self {
let destination = destination.to_string();
fn set_file_source(
&mut self,
destination: Cow<'static, str>,
source: FileDataSource,
) -> &mut Self {
self.files.insert(destination, source);
self
}
Expand Down