Revert "deb: run the rootless build step under fakeroot, sharing the state"
This reverts commit 5f36a54db42e0e5b8f5243dded89f68cd93fa689. Fakeroot's IPC degrades under kernel-scale parallel builds: a linux-riscv build with make -j plus LTO floods the faked daemon and libfakeroot prints 'internal error: payload not recognized' per mangled message, with the ownership database losing entries. The benefit the wrap bought is vacuous anyway: the .deb is assembled in the binary step's own fakeroot session, which records files unknown to its database as root-owned — verified with a sysroot package whose build chown fails: the produced .deb still carries root/root. A rules chown failing for the unprivileged build user stays expected and harmless; the visible noise is collapsed at the classifier level instead (next commit). The bare build step also matches modern dpkg semantics: with Rules-Requires-Root: binary-targets (pkh's default export), dpkg-buildpackage itself runs the build targets unprivileged and fakes root only for the binary targets.
This commit is contained in:
+12
-45
@@ -250,14 +250,6 @@ fn rules_command<'a>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The fakeroot state file shared by the rules steps of a rootless
|
|
||||||
/// build, in the upload directory next to the staged tree: outside the
|
|
||||||
/// package tree, so it pollutes neither the sources nor the collected
|
|
||||||
/// artifacts.
|
|
||||||
fn fakeroot_state_file(upload_dir: &str) -> PathBuf {
|
|
||||||
Path::new(upload_dir).join(".pkh-fakeroot.state")
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub async fn build(
|
pub async fn build(
|
||||||
package: &str,
|
package: &str,
|
||||||
@@ -688,10 +680,16 @@ pub async fn build(
|
|||||||
.unwrap_or_else(|| "binary-targets".to_string());
|
.unwrap_or_else(|| "binary-targets".to_string());
|
||||||
env.insert("DEB_RULES_REQUIRES_ROOT".to_string(), rules_requires_root);
|
env.insert("DEB_RULES_REQUIRES_ROOT".to_string(), rules_requires_root);
|
||||||
|
|
||||||
// Rootless builds: the rules (fakeroot-wrapped, see below) run as an
|
// Rootless builds: the rules run as an unprivileged user owning the
|
||||||
// unprivileged user owning the staged tree. Everything before this
|
// staged tree. Everything before this point - dependency installation,
|
||||||
// point - dependency installation, quilt patch application, staging
|
// quilt patch application, staging cleanup - legitimately needs the
|
||||||
// cleanup - legitimately needs the context's root and stays with it.
|
// context's root and stays with it. The build step runs BARE (no
|
||||||
|
// fakeroot): fakeroot's IPC degrades under kernel-scale parallel
|
||||||
|
// builds ('libfakeroot internal error: payload not recognized' per
|
||||||
|
// LTO/make -j process flood), and a rules chown that fails for the
|
||||||
|
// build user is cosmetic — the .deb is assembled in the binary step's
|
||||||
|
// own fakeroot session, where files unknown to its database are
|
||||||
|
// recorded as root-owned anyway.
|
||||||
let rule_ids = match build_user {
|
let rule_ids = match build_user {
|
||||||
Some(_) => {
|
Some(_) => {
|
||||||
let workroot = Path::new(package_dir_str)
|
let workroot = Path::new(package_dir_str)
|
||||||
@@ -704,34 +702,12 @@ pub async fn build(
|
|||||||
None => None,
|
None => None,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Rootless: the rules run under fakeroot with one session state
|
|
||||||
// shared between the build and binary steps, the way
|
|
||||||
// dpkg-buildpackage -rfakeroot wraps every rules target. An
|
|
||||||
// ownership change made during the build (a sysroot chown) then
|
|
||||||
// succeeds — faked — and carries into the .deb, instead of failing
|
|
||||||
// per file with EPERM spam. With the context's own user the build
|
|
||||||
// step runs bare; the binary step keeps its unconditional wrap.
|
|
||||||
let fakeroot_state = fakeroot_state_file(upload_dir);
|
|
||||||
if rule_ids.is_some() {
|
|
||||||
// A state left by an interrupted previous attempt must not
|
|
||||||
// seed this session.
|
|
||||||
let _ = ctx.command("rm").arg("-f").arg(&fakeroot_state).status();
|
|
||||||
}
|
|
||||||
let mut rules = match rule_ids.as_ref() {
|
|
||||||
Some(_) => {
|
|
||||||
let mut cmd = rules_command(&ctx, rule_ids.as_ref(), "fakeroot");
|
|
||||||
cmd.arg("-s").arg(&fakeroot_state).arg("debian/rules");
|
|
||||||
cmd
|
|
||||||
}
|
|
||||||
None => rules_command(&ctx, None, "debian/rules"),
|
|
||||||
};
|
|
||||||
|
|
||||||
// Run the build step
|
// Run the build step
|
||||||
log::debug!("Building (debian/rules build) package...");
|
log::debug!("Building (debian/rules build) package...");
|
||||||
enter_phase(view, Phase::Building, profiler);
|
enter_phase(view, Phase::Building, profiler);
|
||||||
let started = Instant::now();
|
let started = Instant::now();
|
||||||
let status = cap(
|
let status = cap(
|
||||||
rules
|
rules_command(&ctx, rule_ids.as_ref(), "debian/rules")
|
||||||
.current_dir(package_dir_str)
|
.current_dir(package_dir_str)
|
||||||
.envs(env.clone())
|
.envs(env.clone())
|
||||||
.arg("build"),
|
.arg("build"),
|
||||||
@@ -760,17 +736,8 @@ pub async fn build(
|
|||||||
// Run the 'binary' step to produce deb
|
// Run the 'binary' step to produce deb
|
||||||
enter_phase(view, Phase::ProducingBinaries, profiler);
|
enter_phase(view, Phase::ProducingBinaries, profiler);
|
||||||
let started = Instant::now();
|
let started = Instant::now();
|
||||||
let mut rules = rules_command(&ctx, rule_ids.as_ref(), "fakeroot");
|
|
||||||
if rule_ids.is_some() {
|
|
||||||
// Pick up the ownership changes the build step recorded.
|
|
||||||
rules
|
|
||||||
.arg("-i")
|
|
||||||
.arg(&fakeroot_state)
|
|
||||||
.arg("-s")
|
|
||||||
.arg(&fakeroot_state);
|
|
||||||
}
|
|
||||||
let status = cap(
|
let status = cap(
|
||||||
rules
|
rules_command(&ctx, rule_ids.as_ref(), "fakeroot")
|
||||||
.current_dir(package_dir_str)
|
.current_dir(package_dir_str)
|
||||||
.envs(env.clone())
|
.envs(env.clone())
|
||||||
.arg("debian/rules")
|
.arg("debian/rules")
|
||||||
|
|||||||
Reference in New Issue
Block a user