deb: record per-phase build timings, shown by pkh deb profile
Time every Phase the build flow announces through enter_phase — the chroot bootstrap (tarball download, extraction, finalization), the apt phases, patch application, the build and binary steps and the artifact retrieval — and land the ordered profile in the record's manifest of every run, failed builds included: their profile ends at the phase the error propagated out of. Timing rides the enter_phase choke point instead of new measurement sites, so a phase added later profiles itself. The manifest field is additive (serde default, skipped when absent), so older manifests keep loading without a schema bump. The coarse timings stay the source of the deb list columns: they measure the apt transactions themselves, where the profile measures whole phases. pkh deb profile renders a record's profile through the same read-only record discovery as pkh deb log — the newest record of the tree, or an id prefix as shown by pkh deb list — so record_for_log becomes the neutral find_record. Phase keys are storage names, distinct from the display labels; Phase::from_key turns them back and a test keeps both in sync.
This commit is contained in:
+36
-10
@@ -1,7 +1,7 @@
|
||||
/// Local binary package building
|
||||
/// Directly calling 'debian/rules' in current context
|
||||
use crate::context::{Context, ContextCommand, LineSink};
|
||||
use crate::deb::{Phase, enter_phase, find_dsc_file};
|
||||
use crate::deb::{BuildProfiler, Phase, enter_phase, find_dsc_file};
|
||||
use crate::logfmt::QuiltClassifier;
|
||||
use crate::report::BuildView;
|
||||
use log::warn;
|
||||
@@ -275,6 +275,9 @@ pub async fn build(
|
||||
// Accumulator of the measured dependency-installation and build
|
||||
// durations; the caller records it on the build record.
|
||||
timings: &mut session::BuildTimings,
|
||||
// The per-phase profile the caller records on the build record:
|
||||
// fed by every enter_phase call of the build flow.
|
||||
profiler: &mut BuildProfiler,
|
||||
) -> Result<Vec<PathBuf>, Box<dyn Error>> {
|
||||
let sink: Option<Arc<dyn LineSink>> = view.sink();
|
||||
|
||||
@@ -486,7 +489,7 @@ pub async fn build(
|
||||
|
||||
// Update package lists
|
||||
log::debug!("Updating package lists for local build...");
|
||||
enter_phase(view, Phase::UpdatingPackageLists);
|
||||
enter_phase(view, Phase::UpdatingPackageLists, profiler);
|
||||
let started = Instant::now();
|
||||
let status = cap(
|
||||
ctx.command("apt-get").envs(env.clone()).arg("update"),
|
||||
@@ -532,7 +535,7 @@ pub async fn build(
|
||||
cmd.arg(format!("libc6:{arch}"));
|
||||
cmd.arg(format!("libc6-dev:{arch}"));
|
||||
}
|
||||
enter_phase(view, Phase::InstallingEssentials);
|
||||
enter_phase(view, Phase::InstallingEssentials, profiler);
|
||||
let started = Instant::now();
|
||||
let status = cap(&mut cmd, &sink).status()?;
|
||||
timings.add_deps(started.elapsed());
|
||||
@@ -571,14 +574,30 @@ pub async fn build(
|
||||
.unwrap_or(false);
|
||||
applied && previous != patch_stamp
|
||||
};
|
||||
apply_quilt_patches(package_dir_str, &env, ctx.clone(), view, &sink, pop_patches)?;
|
||||
apply_quilt_patches(
|
||||
package_dir_str,
|
||||
&env,
|
||||
ctx.clone(),
|
||||
view,
|
||||
&sink,
|
||||
pop_patches,
|
||||
profiler,
|
||||
)?;
|
||||
if let Some(s) = session {
|
||||
s.record_phase("patches", patch_stamp);
|
||||
}
|
||||
|
||||
// Install injected packages if specified
|
||||
if !inject_packages.is_empty() {
|
||||
install_injected_packages(inject_packages, &env, ctx.clone(), view, &sink, timings)?;
|
||||
install_injected_packages(
|
||||
inject_packages,
|
||||
&env,
|
||||
ctx.clone(),
|
||||
view,
|
||||
&sink,
|
||||
timings,
|
||||
profiler,
|
||||
)?;
|
||||
}
|
||||
|
||||
// Resolve and install the Build-* dependencies with dpkg's cross
|
||||
@@ -598,6 +617,7 @@ pub async fn build(
|
||||
view,
|
||||
&sink,
|
||||
timings,
|
||||
profiler,
|
||||
)?;
|
||||
// (The build-dependency phase reruns in every fresh chroot: nothing
|
||||
// to journal.)
|
||||
@@ -669,7 +689,7 @@ pub async fn build(
|
||||
|
||||
// Run the build step
|
||||
log::debug!("Building (debian/rules build) package...");
|
||||
enter_phase(view, Phase::Building);
|
||||
enter_phase(view, Phase::Building, profiler);
|
||||
let started = Instant::now();
|
||||
let status = cap(
|
||||
rules_command(&ctx, rule_ids.as_ref(), "debian/rules")
|
||||
@@ -699,7 +719,7 @@ pub async fn build(
|
||||
}
|
||||
|
||||
// Run the 'binary' step to produce deb
|
||||
enter_phase(view, Phase::ProducingBinaries);
|
||||
enter_phase(view, Phase::ProducingBinaries, profiler);
|
||||
let started = Instant::now();
|
||||
let status = cap(
|
||||
rules_command(&ctx, rule_ids.as_ref(), "fakeroot")
|
||||
@@ -1005,8 +1025,9 @@ fn install_build_dependencies(
|
||||
view: &dyn BuildView,
|
||||
sink: &Option<Arc<dyn LineSink>>,
|
||||
timings: &mut session::BuildTimings,
|
||||
profiler: &mut BuildProfiler,
|
||||
) -> Result<(), Box<dyn Error>> {
|
||||
enter_phase(view, Phase::InstallingBuildDeps);
|
||||
enter_phase(view, Phase::InstallingBuildDeps, profiler);
|
||||
|
||||
let host_arch = arch.to_string();
|
||||
let build_arch = context_build_arch(&ctx);
|
||||
@@ -1309,6 +1330,7 @@ fn apply_quilt_patches(
|
||||
view: &dyn BuildView,
|
||||
sink: &Option<Arc<dyn LineSink>>,
|
||||
pop_first: bool,
|
||||
profiler: &mut BuildProfiler,
|
||||
) -> Result<(), Box<dyn Error>> {
|
||||
let series_path = Path::new(package_dir).join("debian/patches/series");
|
||||
if !ctx.exists(&series_path)? {
|
||||
@@ -1409,7 +1431,9 @@ fn apply_quilt_patches(
|
||||
}
|
||||
}
|
||||
|
||||
// Apply all patches listed in the series
|
||||
// Apply all patches listed in the series (a custom classifier: the
|
||||
// phase reports per-patch progress, not the default's raw output)
|
||||
profiler.enter(Phase::ApplyingPatches);
|
||||
view.phase(
|
||||
Phase::ApplyingPatches.label(),
|
||||
Box::new(QuiltClassifier::new(total_patches)),
|
||||
@@ -1488,10 +1512,11 @@ pub(crate) fn install_injected_packages(
|
||||
view: &dyn BuildView,
|
||||
sink: &Option<Arc<dyn LineSink>>,
|
||||
timings: &mut session::BuildTimings,
|
||||
profiler: &mut BuildProfiler,
|
||||
) -> Result<(), Box<dyn Error>> {
|
||||
log::info!("Installing injected packages: {:?}", packages);
|
||||
|
||||
enter_phase(view, Phase::InjectingPackages);
|
||||
enter_phase(view, Phase::InjectingPackages, profiler);
|
||||
|
||||
// Separate .deb files from package names
|
||||
let mut deb_files: Vec<String> = Vec::new();
|
||||
@@ -1955,6 +1980,7 @@ mod tests {
|
||||
&crate::report::Quiet,
|
||||
&None,
|
||||
false,
|
||||
&mut BuildProfiler::new(),
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user