deb: stage the pointed-at tree, not its parent

The staged tree was the parent of the tree the caller pointed at,
so building a tree sitting in a busy directory dragged every
sibling into the chroot: a /tmp checkout copied the whole host /tmp
(snap sockets, other jobs' scratch), and the build user's chown -R
then failed per foreign-owned file, or aborted the build outright.

Stage the tree itself: its content is the merge point of the build
root, the overlay lower is the tree and the record's upper stacks
on top. The package resolution treats the staged root as the
package when it carries debian/, keeping the pattern search for
nested layouts. The .debs, the upload metadata and the dose3
scratch follow dh_builddeb's .. (the package directory's parent)
instead of assuming the build root, and the host-tree snapshot
covers the tree only. Records staged the old way self-heal: their
snapshots carry parent-relative paths, so the next incremental
run's sync wipes the stale upper entries and rebuilds once.

Siblings are no longer visible to debian/rules — dpkg packaging
never crosses that boundary, and pkh test already staged the tree
alone.
This commit is contained in:
2026-10-02 17:55:22 +02:00
parent 5f36a54e7c
commit b8adb318bd
3 changed files with 95 additions and 83 deletions
+5 -5
View File
@@ -1933,8 +1933,8 @@ pub(crate) fn load_snapshot(path: &Path) -> Option<BTreeMap<String, EntryMeta>>
}
/// Record the host tree snapshot for a fresh staging.
pub(crate) fn take_snapshot(host_parent: &Path, session: &Session) -> io::Result<()> {
let meta = walk_tree_meta(host_parent)?;
pub(crate) fn take_snapshot(host_tree: &Path, session: &Session) -> io::Result<()> {
let meta = walk_tree_meta(host_tree)?;
write_snapshot(&meta, &session.snapshot_file())
}
@@ -2114,17 +2114,17 @@ pub(crate) fn apply_upper_sync(upper_root: &Path, ops: &[UpperOp]) -> io::Result
/// possible (a usable snapshot existed and the upper was synced):
/// without a snapshot the upper is wiped and the build stages cold,
/// but safely.
pub(crate) fn sync_upper_for_resume(session: &Session, host_parent: &Path) -> io::Result<bool> {
pub(crate) fn sync_upper_for_resume(session: &Session, host_tree: &Path) -> io::Result<bool> {
let Some(snapshot) = load_snapshot(&session.snapshot_file()) else {
log::info!(
"No host-tree snapshot in the record: build artifacts are \
discarded, the environment is still reused"
);
session.wipe_build_artifacts();
take_snapshot(host_parent, session)?;
take_snapshot(host_tree, session)?;
return Ok(false);
};
let current = walk_tree_meta(host_parent)?;
let current = walk_tree_meta(host_tree)?;
let upper_entries = walk_upper(&session.upper_dir()).unwrap_or_default();
let ops = plan_upper_sync(&snapshot, &current, &upper_entries);
let removed = apply_upper_sync(&session.upper_dir(), &ops)?;