deb: classify the staged listing through the context
The fallback listing of find_package_directory called Path::is_dir on entries returned by list_files — a host-side stat. For an unshare context (every local build) those paths are rooted inside the chroot and do not exist at the same host path, so every entry came out a non-directory, the 'Found directories' list silently stayed empty and the failure degraded to the list-less 'Could not find package directory' variant, hiding the actual layout (seen building bc from an ubuntu/devel checkout whose staged tree was named 'tree'). Classify entries through the new ContextDriver::is_dir, and log every entry instead of only those matching the broken host stat.
This commit is contained in:
+52
-5
@@ -413,11 +413,13 @@ pub(crate) fn find_package_directory(
|
|||||||
let entries = ctx.list_files(package_parent)?;
|
let entries = ctx.list_files(package_parent)?;
|
||||||
let mut found_dirs = Vec::new();
|
let mut found_dirs = Vec::new();
|
||||||
for entry in entries {
|
for entry in entries {
|
||||||
if entry.is_dir() {
|
// list_files yields context-relative paths (e.g. rooted inside
|
||||||
if let Some(file_name) = entry.file_name() {
|
// the chroot for an unshare context): classify through the
|
||||||
found_dirs.push(file_name.to_string_lossy().into_owned());
|
// context, a host-side stat would miss every entry.
|
||||||
}
|
let is_dir = ctx.is_dir(&entry)?;
|
||||||
log::debug!(" - {}", entry.display());
|
log::debug!(" - {}", entry.display());
|
||||||
|
if is_dir && let Some(file_name) = entry.file_name() {
|
||||||
|
found_dirs.push(file_name.to_string_lossy().into_owned());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -501,6 +503,51 @@ mod tests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// An unshare context mapped over `chroot_root`, parented on a local
|
||||||
|
/// context like the ephemeral build contexts are: exists/list_files/
|
||||||
|
/// is_dir answer through the path mapping, no namespace privileges
|
||||||
|
/// needed.
|
||||||
|
fn unshare_test_context(chroot_root: &Path) -> Context {
|
||||||
|
let base = Context::new(crate::context::ContextConfig::Local).unwrap();
|
||||||
|
Context::with_parent(
|
||||||
|
crate::context::ContextConfig::Unshare {
|
||||||
|
path: chroot_root.to_string_lossy().to_string(),
|
||||||
|
parent: None,
|
||||||
|
},
|
||||||
|
Arc::new(base),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The staging-area listing must classify entries through the context:
|
||||||
|
/// an unshare context returns build-root-relative paths that a host-side
|
||||||
|
/// stat never sees (they live under the chroot root on the host), which
|
||||||
|
/// used to silently empty the 'Found directories' list of the search
|
||||||
|
/// failure message — and with it every hint about the actual layout.
|
||||||
|
#[test]
|
||||||
|
fn find_package_directory_lists_staged_directories_through_the_context() {
|
||||||
|
let chroot = tempfile::tempdir().unwrap();
|
||||||
|
// Staged parent holding a single tree whose name matches none of
|
||||||
|
// the search patterns (the embedded-caller layout: <job>/tree)
|
||||||
|
let staged_parent = chroot.path().join("tmp/pkh-build-1/j-42");
|
||||||
|
std::fs::create_dir_all(staged_parent.join("tree/debian")).unwrap();
|
||||||
|
|
||||||
|
let ctx = unshare_test_context(chroot.path());
|
||||||
|
let err = find_package_directory(
|
||||||
|
Path::new("/tmp/pkh-build-1/j-42"),
|
||||||
|
"bc",
|
||||||
|
"1.07.1-1ubuntu1",
|
||||||
|
"questing",
|
||||||
|
&ctx,
|
||||||
|
)
|
||||||
|
.expect_err("no candidate matches a tree named 'tree'");
|
||||||
|
|
||||||
|
let message = err.to_string();
|
||||||
|
assert!(
|
||||||
|
message.contains("Found directories: tree"),
|
||||||
|
"error should list the staged directories through the context: {message}"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
async fn test_build_end_to_end(
|
async fn test_build_end_to_end(
|
||||||
package: &str,
|
package: &str,
|
||||||
series: &str,
|
series: &str,
|
||||||
|
|||||||
Reference in New Issue
Block a user