mirror of
https://github.com/NixOS/nixpkgs.git
synced 2024-11-25 08:23:09 +00:00
makeInitrdNGTool: better errors
It's extremely frustrating seeing "Error: Os { code: 13, kind: PermissionDenied, message: "Permission denied" }" without any hint as to where exactly that occurred. This commit fixes that by adding context to most errors.
This commit is contained in:
parent
ddd54024ce
commit
3e63608c7b
23
pkgs/build-support/kernel/make-initrd-ng/Cargo.lock
generated
23
pkgs/build-support/kernel/make-initrd-ng/Cargo.lock
generated
@ -8,6 +8,16 @@ version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "eyre"
|
||||
version = "0.6.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4c2b6b5a29c02cdc822728b7d7b8ae1bab3e3b05d44522770ddd49722eeac7eb"
|
||||
dependencies = [
|
||||
"indenter",
|
||||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "goblin"
|
||||
version = "0.5.3"
|
||||
@ -19,6 +29,12 @@ dependencies = [
|
||||
"scroll",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "indenter"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.17"
|
||||
@ -32,9 +48,16 @@ dependencies = [
|
||||
name = "make-initrd-ng"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"eyre",
|
||||
"goblin",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.17.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3"
|
||||
|
||||
[[package]]
|
||||
name = "plain"
|
||||
version = "0.2.3"
|
||||
|
@ -7,4 +7,5 @@ edition = "2018"
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
eyre = "0.6.8"
|
||||
goblin = "0.5.0"
|
||||
|
@ -3,12 +3,13 @@ use std::env;
|
||||
use std::ffi::{OsStr, OsString};
|
||||
use std::fs;
|
||||
use std::hash::Hash;
|
||||
use std::io::{BufRead, BufReader};
|
||||
use std::iter::FromIterator;
|
||||
use std::io::{BufRead, BufReader, Error};
|
||||
use std::os::unix;
|
||||
use std::path::{Component, Path, PathBuf};
|
||||
use std::process::Command;
|
||||
|
||||
use eyre::Context;
|
||||
use goblin::{elf::Elf, Object};
|
||||
|
||||
struct NonRepeatingQueue<T> {
|
||||
@ -87,22 +88,30 @@ fn add_dependencies<P: AsRef<Path> + AsRef<OsStr>>(
|
||||
}
|
||||
}
|
||||
|
||||
fn copy_file<P: AsRef<Path> + AsRef<OsStr>, S: AsRef<Path> + AsRef<OsStr>>(
|
||||
fn copy_file<
|
||||
P: AsRef<Path> + AsRef<OsStr> + std::fmt::Debug,
|
||||
S: AsRef<Path> + AsRef<OsStr> + std::fmt::Debug,
|
||||
>(
|
||||
source: P,
|
||||
target: S,
|
||||
queue: &mut NonRepeatingQueue<Box<Path>>,
|
||||
) -> Result<(), Error> {
|
||||
fs::copy(&source, &target)?;
|
||||
) -> eyre::Result<()> {
|
||||
fs::copy(&source, &target)
|
||||
.wrap_err_with(|| format!("failed to copy {:?} to {:?}", source, target))?;
|
||||
|
||||
let contents = fs::read(&source)?;
|
||||
let contents =
|
||||
fs::read(&source).wrap_err_with(|| format!("failed to read from {:?}", source))?;
|
||||
|
||||
if let Ok(Object::Elf(e)) = Object::parse(&contents) {
|
||||
add_dependencies(source, e, queue);
|
||||
|
||||
// Make file writable to strip it
|
||||
let mut permissions = fs::metadata(&target)?.permissions();
|
||||
let mut permissions = fs::metadata(&target)
|
||||
.wrap_err_with(|| format!("failed to get metadata for {:?}", target))?
|
||||
.permissions();
|
||||
permissions.set_readonly(false);
|
||||
fs::set_permissions(&target, permissions)?;
|
||||
fs::set_permissions(&target, permissions)
|
||||
.wrap_err_with(|| format!("failed to set readonly flag to false for {:?}", target))?;
|
||||
|
||||
// Strip further than normal
|
||||
if let Ok(strip) = env::var("STRIP") {
|
||||
@ -121,11 +130,13 @@ fn copy_file<P: AsRef<Path> + AsRef<OsStr>, S: AsRef<Path> + AsRef<OsStr>>(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn queue_dir<P: AsRef<Path>>(
|
||||
fn queue_dir<P: AsRef<Path> + std::fmt::Debug>(
|
||||
source: P,
|
||||
queue: &mut NonRepeatingQueue<Box<Path>>,
|
||||
) -> Result<(), Error> {
|
||||
for entry in fs::read_dir(source)? {
|
||||
) -> eyre::Result<()> {
|
||||
for entry in
|
||||
fs::read_dir(&source).wrap_err_with(|| format!("failed to read dir {:?}", source))?
|
||||
{
|
||||
let entry = entry?;
|
||||
// No need to recurse. The queue will bring us back round here on its own.
|
||||
queue.push_back(Box::from(entry.path().as_path()));
|
||||
@ -138,7 +149,7 @@ fn handle_path(
|
||||
root: &Path,
|
||||
p: &Path,
|
||||
queue: &mut NonRepeatingQueue<Box<Path>>,
|
||||
) -> Result<(), Error> {
|
||||
) -> eyre::Result<()> {
|
||||
let mut source = PathBuf::new();
|
||||
let mut target = Path::new(root).to_path_buf();
|
||||
let mut iter = p.components().peekable();
|
||||
@ -161,15 +172,17 @@ fn handle_path(
|
||||
Component::Normal(name) => {
|
||||
target.push(name);
|
||||
source.push(name);
|
||||
let typ = fs::symlink_metadata(&source)?.file_type();
|
||||
let typ = fs::symlink_metadata(&source)
|
||||
.wrap_err_with(|| format!("failed to get symlink metadata for {:?}", source))?
|
||||
.file_type();
|
||||
if typ.is_file() && !target.exists() {
|
||||
copy_file(&source, &target, queue)?;
|
||||
|
||||
if let Some(filename) = source.file_name() {
|
||||
source.set_file_name(OsString::from_iter([
|
||||
OsStr::new("."),
|
||||
filename,
|
||||
OsStr::new("-wrapped"),
|
||||
OsStr::new("."),
|
||||
filename,
|
||||
OsStr::new("-wrapped"),
|
||||
]));
|
||||
|
||||
let wrapped_path = source.as_path();
|
||||
@ -178,11 +191,14 @@ fn handle_path(
|
||||
}
|
||||
}
|
||||
} else if typ.is_symlink() {
|
||||
let link_target = fs::read_link(&source)?;
|
||||
let link_target = fs::read_link(&source)
|
||||
.wrap_err_with(|| format!("failed to resolve symlink of {:?}", source))?;
|
||||
|
||||
// Create the link, then push its target to the queue
|
||||
if !target.exists() {
|
||||
unix::fs::symlink(&link_target, &target)?;
|
||||
unix::fs::symlink(&link_target, &target).wrap_err_with(|| {
|
||||
format!("failed to symlink {:?} to {:?}", link_target, target)
|
||||
})?;
|
||||
}
|
||||
source.pop();
|
||||
source.push(link_target);
|
||||
@ -196,12 +212,14 @@ fn handle_path(
|
||||
break;
|
||||
} else if typ.is_dir() {
|
||||
if !target.exists() {
|
||||
fs::create_dir(&target)?;
|
||||
fs::create_dir(&target)
|
||||
.wrap_err_with(|| format!("failed to create dir {:?}", target))?;
|
||||
}
|
||||
|
||||
// Only recursively copy if the directory is the target object
|
||||
if iter.peek().is_none() {
|
||||
queue_dir(&source, queue)?;
|
||||
queue_dir(&source, queue)
|
||||
.wrap_err_with(|| format!("failed to queue dir {:?}", source))?;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -211,9 +229,10 @@ fn handle_path(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn main() -> Result<(), Error> {
|
||||
fn main() -> eyre::Result<()> {
|
||||
let args: Vec<String> = env::args().collect();
|
||||
let input = fs::File::open(&args[1])?;
|
||||
let input =
|
||||
fs::File::open(&args[1]).wrap_err_with(|| format!("failed to open file {:?}", &args[1]))?;
|
||||
let output = &args[2];
|
||||
let out_path = Path::new(output);
|
||||
|
||||
@ -235,8 +254,10 @@ fn main() -> Result<(), Error> {
|
||||
let link_path = Path::new(&link_string);
|
||||
let mut link_parent = link_path.to_path_buf();
|
||||
link_parent.pop();
|
||||
fs::create_dir_all(link_parent)?;
|
||||
unix::fs::symlink(obj_path, link_path)?;
|
||||
fs::create_dir_all(&link_parent)
|
||||
.wrap_err_with(|| format!("failed to create directories to {:?}", link_parent))?;
|
||||
unix::fs::symlink(obj_path, link_path)
|
||||
.wrap_err_with(|| format!("failed to symlink {:?} to {:?}", obj_path, link_path))?;
|
||||
}
|
||||
}
|
||||
while let Some(obj) = queue.pop_front() {
|
||||
|
Loading…
Reference in New Issue
Block a user