From 5dc2221155972c58060d742692714a23a60ff119 Mon Sep 17 00:00:00 2001 From: Daiderd Jordan Date: Tue, 5 May 2020 22:20:16 +0200 Subject: [PATCH] skip stdenv rebuilds Before attempting builds check if the stdenv for this branch is available in the cache. If this is not the case then either the merge request is a mass rebuild or it's targeting a branch like staging. --- ofborg/src/nix.rs | 44 +++++++++++++++++++++++++++++++++++++++ ofborg/src/tasks/build.rs | 24 +++++++++++++++++---- 2 files changed, 64 insertions(+), 4 deletions(-) diff --git a/ofborg/src/nix.rs b/ofborg/src/nix.rs index 1180e37f..ed7800b2 100644 --- a/ofborg/src/nix.rs +++ b/ofborg/src/nix.rs @@ -4,12 +4,15 @@ use crate::ofborg::partition_result; use std::collections::HashMap; use std::env; +use std::error::Error; use std::ffi::OsStr; use std::fmt; use std::fs; +use std::io; use std::io::{BufRead, BufReader, Seek, SeekFrom}; use std::path::Path; use std::process::{Command, Stdio}; +use tracing::{debug, info}; use tempfile::tempfile; @@ -137,6 +140,47 @@ impl Nix { n } + pub fn safely_query_cache_for_attr( + &self, + nixpkgs: &Path, + file: File, + attr: String, + ) -> Result> { + let mut command = self.safe_command::<&OsStr>(&Operation::Instantiate, nixpkgs, &[], &[]); + self.set_attrs_command(&mut command, file, vec![attr]); + let output = command + .stderr(Stdio::piped()) + .stdout(Stdio::piped()) + .output()?; + debug!("{}", String::from_utf8(output.stderr)?.trim()); + + let drv = String::from_utf8(output.stdout)?; + let output = Command::new("nix-store") + .args(&["-q", "--binding", "out"]) + .arg(drv.trim()) + .stderr(Stdio::piped()) + .stdout(Stdio::piped()) + .output()?; + debug!("{}", String::from_utf8(output.stderr)?.trim()); + if !output.status.success() { + let err = io::Error::new(io::ErrorKind::Other, "Could not evaluate stdenv"); + return Err(Box::new(err)); + } + + let out = String::from_utf8(output.stdout)?; + info!("stdenv {}", out); + let output = Command::new("nix-store") + .args(&["--option", "store", "https://cache.nixos.org"]) + .args(&["-q", "--size"]) + .arg(out.trim()) + .stderr(Stdio::piped()) + .stdout(Stdio::null()) + .output()?; + debug!("{}", String::from_utf8(output.stderr)?.trim()); + + Ok(output.status.success()) + } + pub fn safely_partition_instantiable_attrs( &self, nixpkgs: &Path, diff --git a/ofborg/src/tasks/build.rs b/ofborg/src/tasks/build.rs index 597d9cc5..3c859678 100644 --- a/ofborg/src/tasks/build.rs +++ b/ofborg/src/tasks/build.rs @@ -325,10 +325,7 @@ impl notifyworker::SimpleNotifyWorker for BuildWorker { return; } - info!( - "Got path: {:?}, determining which ones we can build ", - refpath - ); + info!("Determining which attributes we can build"); let (can_build, cannot_build) = self.nix.safely_partition_instantiable_attrs( refpath.as_ref(), buildfile, @@ -341,6 +338,25 @@ impl notifyworker::SimpleNotifyWorker for BuildWorker { .map(|(attr, _)| attr) .collect(); + info!("Checking for stdenv rebuild"); + match self.nix.safely_query_cache_for_attr( + refpath.as_ref(), + buildfile, + String::from("stdenv"), + ) { + Ok(false) => { + info!( + "Skip build: '{}', Cannot build: '{}'", + can_build.join(", "), + cannot_build_attrs.join(", ") + ); + actions.build_not_attempted(cannot_build_attrs); + return; + } + Ok(true) => (), + Err(err) => error!("Failed to detect stdenv rebuild: {:?}", err), + } + info!( "Can build: '{}', Cannot build: '{}'", can_build.join(", "),