lanzatool: improve error handling

This commit is contained in:
nikstur 2022-11-24 13:33:01 +01:00
parent 1dfa7c7fc8
commit 587e388364
3 changed files with 45 additions and 28 deletions

View File

@ -1,8 +1,7 @@
use std::fs; use std::fs;
use std::path::Path; use std::path::Path;
use anyhow::Result; use anyhow::{Context, Result};
use crate::bootspec::Bootspec; use crate::bootspec::Bootspec;
use crate::esp::EspPaths; use crate::esp::EspPaths;
@ -14,10 +13,16 @@ pub fn install(
lanzaboote_stub: &Path, lanzaboote_stub: &Path,
initrd_stub: &Path, initrd_stub: &Path,
) -> Result<()> { ) -> Result<()> {
let bootspec_doc: Bootspec = serde_json::from_slice(&fs::read(bootspec)?)?; println!("Reading bootspec...");
let bootspec_doc: Bootspec =
serde_json::from_slice(&fs::read(bootspec).context("Failed to read bootspec file")?)
.context("Failed to parse bootspec json")?;
let esp_paths = EspPaths::new(&bootspec_doc.extension.esp); let esp_paths = EspPaths::new(&bootspec_doc.extension.esp);
println!("Assembling lanzaboote image...");
let lanzaboote_image = pe::assemble_image( let lanzaboote_image = pe::assemble_image(
lanzaboote_stub, lanzaboote_stub,
&bootspec_doc.extension.os_release, &bootspec_doc.extension.os_release,
@ -25,29 +30,45 @@ pub fn install(
&esp_paths.kernel, &esp_paths.kernel,
&esp_paths.initrd, &esp_paths.initrd,
) )
.expect("Failed to assemble stub"); .context("Failed to assemble stub")?;
println!("Wrapping initrd into a PE binary...");
let wrapped_initrd = let wrapped_initrd =
pe::wrap_initrd(initrd_stub, &bootspec_doc.initrd).expect("Failed to assemble stub"); pe::wrap_initrd(initrd_stub, &bootspec_doc.initrd).context("Failed to assemble stub")?;
// Copy the files to the ESP println!("Copy files to EFI system partition...");
fs::create_dir_all(&esp_paths.nixos)?;
fs::copy(bootspec_doc.kernel, esp_paths.kernel)?;
fs::copy(wrapped_initrd, esp_paths.initrd)?;
fs::create_dir_all(&esp_paths.linux)?;
fs::copy(lanzaboote_image, esp_paths.lanzaboote_image)?;
let systemd_boot = bootspec_doc let systemd_boot = bootspec_doc
.extension .extension
.systemd .systemd
.join("lib/systemd/boot/efi/systemd-bootx64.efi"); .join("lib/systemd/boot/efi/systemd-bootx64.efi");
fs::create_dir_all(esp_paths.efi_fallback_dir)?; let files_to_copy = [
fs::copy(&systemd_boot, esp_paths.efi_fallback)?; (bootspec_doc.kernel, esp_paths.kernel),
(wrapped_initrd, esp_paths.initrd),
(lanzaboote_image, esp_paths.lanzaboote_image),
(systemd_boot.clone(), esp_paths.efi_fallback),
(systemd_boot, esp_paths.systemd_boot),
];
fs::create_dir_all(&esp_paths.systemd)?; for (source, target) in files_to_copy {
fs::copy(&systemd_boot, esp_paths.systemd_boot)?; copy(&source, &target)?;
}
println!(
"Succesfully installed lanzaboote to '{}'",
esp_paths.esp.display()
);
Ok(())
}
fn copy(from: &Path, to: &Path) -> Result<()> {
match to.parent() {
Some(parent) => fs::create_dir_all(parent).unwrap_or(()),
_ => (),
};
fs::copy(from, to)
.with_context(|| format!("Failed to copy from {} to {}", from.display(), to.display()))?;
Ok(()) Ok(())
} }

View File

@ -4,18 +4,11 @@ mod esp;
mod install; mod install;
mod pe; mod pe;
use std::process;
use anyhow::Result; use anyhow::Result;
use clap::Parser; use clap::Parser;
use cli::Cli; use cli::Cli;
fn main() -> Result<()> { fn main() -> Result<()> {
let cli = Cli::parse(); Cli::parse().call()
if let Err(e) = cli.call() {
eprintln!("{}", e);
process::exit(1)
};
Ok(())
} }

View File

@ -3,7 +3,7 @@ use std::os::unix::fs::MetadataExt;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use std::process::Command; use std::process::Command;
use anyhow::Result; use anyhow::{Context, Result};
use goblin::pe::PE; use goblin::pe::PE;
pub fn assemble_image( pub fn assemble_image(
@ -52,7 +52,10 @@ pub fn assemble_image(
path_to_string(&lanzaboote_image), path_to_string(&lanzaboote_image),
]; ];
let status = Command::new("objcopy").args(&args).status()?; let status = Command::new("objcopy")
.args(&args)
.status()
.context("Failed to run objcopy command")?;
if !status.success() { if !status.success() {
return Err(anyhow::anyhow!("Failed to build stub with args `{:?}`", &args).into()); return Err(anyhow::anyhow!("Failed to build stub with args `{:?}`", &args).into());
} }
@ -100,8 +103,8 @@ pub fn wrap_initrd(initrd_stub: &Path, initrd: &Path) -> Result<PathBuf> {
} }
fn stub_offset(binary: &Path) -> Result<u64> { fn stub_offset(binary: &Path) -> Result<u64> {
let pe_binary = fs::read(binary)?; let pe_binary = fs::read(binary).context("Failed to read PE binary file")?;
let pe = PE::parse(&pe_binary)?; let pe = PE::parse(&pe_binary).context("Failed to parse PE binary file")?;
let image_base = image_base(&pe); let image_base = image_base(&pe);