nix: Add NixExpression abstraction

This decouples expression generation from evaluation. `NixExpression`s
that evaluate to a set of derivations can be fed to `DrvSetEvaluator`s
which may be able to parallelize evaluation.
This commit is contained in:
Zhaofeng Li 2022-01-22 17:50:53 -08:00
parent 9fbb6b133b
commit 3e40e84e19
2 changed files with 51 additions and 1 deletions

View file

@ -15,6 +15,7 @@ use super::{
NodeName,
NodeConfig,
NodeFilter,
NixExpression,
ProfileDerivation,
StorePath,
};
@ -74,6 +75,12 @@ struct SerializedNixExpression {
json_file: TempPath,
}
/// An expression to evaluate the system profiles of selected nodes.
struct EvalSelectedExpression<'hive> {
hive: &'hive Hive,
nodes_expr: SerializedNixExpression,
}
impl HivePath {
pub async fn from_path<P: AsRef<Path>>(path: P) -> ColmenaResult<Self> {
let path = path.as_ref();
@ -290,6 +297,16 @@ impl Hive {
.collect()
}
/// Returns the expression to evaluate selected nodes.
pub fn eval_selected_expr(&self, nodes: &[NodeName]) -> ColmenaResult<impl NixExpression + '_> {
let nodes_expr = SerializedNixExpression::new(nodes)?;
Ok(EvalSelectedExpression {
hive: self,
nodes_expr,
})
}
/// Evaluates an expression using values from the configuration.
pub async fn introspect(&self, expression: String, instantiate: bool) -> ColmenaResult<String> {
if instantiate {
@ -419,8 +436,24 @@ impl SerializedNixExpression {
json_file: tmp.into_temp_path(),
})
}
}
pub fn expression(&self) -> String {
impl NixExpression for SerializedNixExpression {
fn expression(&self) -> String {
format!("(builtins.fromJSON (builtins.readFile {}))", self.json_file.to_str().unwrap())
}
}
impl<'hive> NixExpression for EvalSelectedExpression<'hive> {
fn expression(&self) -> String {
format!(
"{} hive.evalSelected {}",
self.hive.get_base_expression(),
self.nodes_expr.expression(),
)
}
fn requires_flakes(&self) -> bool {
self.hive.is_flake()
}
}

View file

@ -97,6 +97,17 @@ pub struct NixOptions {
builders: Option<String>,
}
/// A Nix expression.
pub trait NixExpression : Send + Sync {
/// Returns the full Nix expression to be evaluated.
fn expression(&self) -> String;
/// Returns whether this expression requires the use of flakes.
fn requires_flakes(&self) -> bool {
false
}
}
impl NodeName {
/// Returns the string.
pub fn as_str(&self) -> &str {
@ -203,6 +214,12 @@ impl NixOptions {
}
}
impl NixExpression for String {
fn expression(&self) -> String {
self.clone()
}
}
fn validate_keys(keys: &HashMap<String, Key>) -> Result<(), ValidationErrorType> {
// Bad secret names:
// - /etc/passwd