deb: give the build-user setup and resume cleanup their own phases

The profile's build-dependency phase spanned everything between the
apt passes and the build step, and for a kernel incremental build
that hid ~13 minutes of housekeeping: the recursive chown handing
the staged tree to the build user, and the resume_clear quirk
dropping the previous attempt's stamp caches. Both now enter the
profiler (ClearingResumeCaches only when the quirk has paths and a
tree is carried, PreparingBuildUser only for rootless builds), so
the status bar and pkh deb profile show where the time actually
goes — on a large carried tree the chown dominates, which is the
honest answer to a 6m30s DEPS column next to a 19m19s phase.
This commit is contained in:
2026-10-02 20:39:24 +02:00
parent 4535255844
commit e4612ca128
3 changed files with 31 additions and 7 deletions
+4 -4
View File
@@ -175,10 +175,10 @@ pkh deb list # the records of this tree: id, outcome,
pkh deb log [-f] [<id>] # print a record's build log; -f follows a
# live build
pkh deb profile [<id>] # a record's per-phase timing profile: how
# long the chroot bootstrap, each apt phase,
# patch application, the build and binary
# steps and the artifact retrieval took, with
# their shares of the total
# long every step took (chroot bootstrap,
# apt phases, patch application, build-user
# setup, build and binary steps, artifact
# retrieval), with their shares of the total
pkh deb --no-ccache # build without the shared compile cache
```
+10 -3
View File
@@ -639,8 +639,10 @@ pub async fn build(
// with no config prerequisite) would build from the previous
// attempt's configuration: drop the listed caches so the wrapper
// steps re-run over the incremental inner builds.
if build_resume {
for rel in crate::quirks::get_resume_clear_paths(package, series) {
let resume_clear_paths = crate::quirks::get_resume_clear_paths(package, series);
if build_resume && !resume_clear_paths.is_empty() {
enter_phase(view, Phase::ClearingResumeCaches, profiler);
for rel in resume_clear_paths {
let path = Path::new(package_dir_str).join(&rel);
if !ctx.exists(&path).unwrap_or(false) {
continue;
@@ -689,7 +691,12 @@ pub async fn build(
// 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.
// recorded as root-owned anyway. Handing the tree over is a recursive
// chown that can take minutes on a large carried tree, so it is a
// phase of its own in the status bar and the profile.
if build_user.is_some() {
enter_phase(view, Phase::PreparingBuildUser, profiler);
}
let rule_ids = match build_user {
Some(_) => {
let workroot = Path::new(package_dir_str)
+17
View File
@@ -43,6 +43,12 @@ pub enum Phase {
InjectingPackages,
/// apt-get build-dep
InstallingBuildDeps,
/// Drop the resumed tree's input-untracked stamp caches (quirk:
/// `resume_clear`)
ClearingResumeCaches,
/// Create the unprivileged build user and hand the staged tree to
/// it (rootless builds)
PreparingBuildUser,
/// debian/rules build
Building,
/// fakeroot debian/rules binary
@@ -63,6 +69,8 @@ impl Phase {
Phase::ApplyingPatches => "Applying patches",
Phase::InjectingPackages => "Injecting packages",
Phase::InstallingBuildDeps => "Installing build dependencies",
Phase::ClearingResumeCaches => "Clearing resumed build caches",
Phase::PreparingBuildUser => "Preparing the build user",
Phase::Building => "Building package",
Phase::ProducingBinaries => "Producing binary packages",
Phase::RetrievingArtifacts => "Retrieving artifacts",
@@ -82,6 +90,8 @@ impl Phase {
Phase::ApplyingPatches => "applying_patches",
Phase::InjectingPackages => "injecting_packages",
Phase::InstallingBuildDeps => "installing_build_deps",
Phase::ClearingResumeCaches => "clearing_resume_caches",
Phase::PreparingBuildUser => "preparing_build_user",
Phase::Building => "building",
Phase::ProducingBinaries => "producing_binaries",
Phase::RetrievingArtifacts => "retrieving_artifacts",
@@ -101,6 +111,8 @@ impl Phase {
"applying_patches" => Phase::ApplyingPatches,
"injecting_packages" => Phase::InjectingPackages,
"installing_build_deps" => Phase::InstallingBuildDeps,
"clearing_resume_caches" => Phase::ClearingResumeCaches,
"preparing_build_user" => Phase::PreparingBuildUser,
"building" => Phase::Building,
"producing_binaries" => Phase::ProducingBinaries,
"retrieving_artifacts" => Phase::RetrievingArtifacts,
@@ -122,6 +134,9 @@ fn default_classifier(phase: Phase) -> Box<dyn Classifier> {
Phase::InstallingBuildDeps => {
Box::new(AptInstallClassifier::new("Installing build dependencies"))
}
Phase::ClearingResumeCaches | Phase::PreparingBuildUser => {
Box::new(GenericClassifier::new())
}
Phase::Building | Phase::ProducingBinaries => Box::new(MakeClassifier::new()),
Phase::RetrievingArtifacts => Box::new(GenericClassifier::new()),
}
@@ -1147,6 +1162,8 @@ mod tests {
Phase::ApplyingPatches,
Phase::InjectingPackages,
Phase::InstallingBuildDeps,
Phase::ClearingResumeCaches,
Phase::PreparingBuildUser,
Phase::Building,
Phase::ProducingBinaries,
Phase::RetrievingArtifacts,