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, NodeName,
NodeConfig, NodeConfig,
NodeFilter, NodeFilter,
NixExpression,
ProfileDerivation, ProfileDerivation,
StorePath, StorePath,
}; };
@ -74,6 +75,12 @@ struct SerializedNixExpression {
json_file: TempPath, json_file: TempPath,
} }
/// An expression to evaluate the system profiles of selected nodes.
struct EvalSelectedExpression<'hive> {
hive: &'hive Hive,
nodes_expr: SerializedNixExpression,
}
impl HivePath { impl HivePath {
pub async fn from_path<P: AsRef<Path>>(path: P) -> ColmenaResult<Self> { pub async fn from_path<P: AsRef<Path>>(path: P) -> ColmenaResult<Self> {
let path = path.as_ref(); let path = path.as_ref();
@ -290,6 +297,16 @@ impl Hive {
.collect() .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. /// Evaluates an expression using values from the configuration.
pub async fn introspect(&self, expression: String, instantiate: bool) -> ColmenaResult<String> { pub async fn introspect(&self, expression: String, instantiate: bool) -> ColmenaResult<String> {
if instantiate { if instantiate {
@ -419,8 +436,24 @@ impl SerializedNixExpression {
json_file: tmp.into_temp_path(), 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()) 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>, 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 { impl NodeName {
/// Returns the string. /// Returns the string.
pub fn as_str(&self) -> &str { 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> { fn validate_keys(keys: &HashMap<String, Key>) -> Result<(), ValidationErrorType> {
// Bad secret names: // Bad secret names:
// - /etc/passwd // - /etc/passwd