lanzatool: improve error handling
This commit is contained in:
parent
1dfa7c7fc8
commit
587e388364
|
@ -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(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -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(())
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue