forked from DGNum/colmena
hive: Clean up, make way for nix-eval-jobs
This commit is contained in:
parent
3fa0dee6b0
commit
82361e5ea5
1 changed files with 73 additions and 67 deletions
|
@ -39,6 +39,41 @@ pub enum HivePath {
|
||||||
Legacy(PathBuf),
|
Legacy(PathBuf),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct Hive {
|
||||||
|
/// Path to the hive.
|
||||||
|
path: HivePath,
|
||||||
|
|
||||||
|
/// Path to the context directory.
|
||||||
|
///
|
||||||
|
/// Normally this is directory containing the "hive.nix"
|
||||||
|
/// or "flake.nix".
|
||||||
|
context_dir: Option<PathBuf>,
|
||||||
|
|
||||||
|
/// Path to temporary file containing eval.nix.
|
||||||
|
eval_nix: TempPath,
|
||||||
|
|
||||||
|
/// Whether to pass --show-trace in Nix commands.
|
||||||
|
show_trace: bool,
|
||||||
|
|
||||||
|
/// The cached machines_file expression.
|
||||||
|
machines_file: RwLock<Option<Option<String>>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct NixInstantiate<'hive> {
|
||||||
|
hive: &'hive Hive,
|
||||||
|
expression: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A serialized Nix expression.
|
||||||
|
///
|
||||||
|
/// Very hacky so should be avoided as much as possible. But I suppose it's
|
||||||
|
/// more robust than attempting to generate Nix expressions directly or
|
||||||
|
/// escaping a JSON string to strip off Nix interpolation.
|
||||||
|
struct SerializedNixExpression {
|
||||||
|
json_file: TempPath,
|
||||||
|
}
|
||||||
|
|
||||||
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();
|
||||||
|
@ -66,27 +101,6 @@ impl HivePath {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct Hive {
|
|
||||||
/// Path to the hive.
|
|
||||||
path: HivePath,
|
|
||||||
|
|
||||||
/// Path to the context directory.
|
|
||||||
///
|
|
||||||
/// Normally this is directory containing the "hive.nix"
|
|
||||||
/// or "flake.nix".
|
|
||||||
context_dir: Option<PathBuf>,
|
|
||||||
|
|
||||||
/// Path to temporary file containing eval.nix.
|
|
||||||
eval_nix: TempPath,
|
|
||||||
|
|
||||||
/// Whether to pass --show-trace in Nix commands.
|
|
||||||
show_trace: bool,
|
|
||||||
|
|
||||||
/// The cached machines_file expression.
|
|
||||||
machines_file: RwLock<Option<Option<String>>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Hive {
|
impl Hive {
|
||||||
pub fn new(path: HivePath) -> ColmenaResult<Self> {
|
pub fn new(path: HivePath) -> ColmenaResult<Self> {
|
||||||
let mut eval_nix = NamedTempFile::new()?;
|
let mut eval_nix = NamedTempFile::new()?;
|
||||||
|
@ -235,7 +249,7 @@ impl Hive {
|
||||||
|
|
||||||
/// Retrieve deployment info for a list of nodes.
|
/// Retrieve deployment info for a list of nodes.
|
||||||
pub async fn deployment_info_selected(&self, nodes: &[NodeName]) -> ColmenaResult<HashMap<NodeName, NodeConfig>> {
|
pub async fn deployment_info_selected(&self, nodes: &[NodeName]) -> ColmenaResult<HashMap<NodeName, NodeConfig>> {
|
||||||
let nodes_expr = SerializedNixExpresssion::new(nodes)?;
|
let nodes_expr = SerializedNixExpression::new(nodes)?;
|
||||||
|
|
||||||
let configs: HashMap<NodeName, NodeConfig> = self.nix_instantiate(&format!("hive.deploymentConfigSelected {}", nodes_expr.expression()))
|
let configs: HashMap<NodeName, NodeConfig> = self.nix_instantiate(&format!("hive.deploymentConfigSelected {}", nodes_expr.expression()))
|
||||||
.eval_with_builders().await?
|
.eval_with_builders().await?
|
||||||
|
@ -257,7 +271,7 @@ impl Hive {
|
||||||
/// to split up the evaluation process into chunks and run them
|
/// to split up the evaluation process into chunks and run them
|
||||||
/// concurrently with other processes (e.g., build and apply).
|
/// concurrently with other processes (e.g., build and apply).
|
||||||
pub async fn eval_selected(&self, nodes: &[NodeName], job: Option<JobHandle>) -> ColmenaResult<HashMap<NodeName, ProfileDerivation>> {
|
pub async fn eval_selected(&self, nodes: &[NodeName], job: Option<JobHandle>) -> ColmenaResult<HashMap<NodeName, ProfileDerivation>> {
|
||||||
let nodes_expr = SerializedNixExpresssion::new(nodes)?;
|
let nodes_expr = SerializedNixExpression::new(nodes)?;
|
||||||
|
|
||||||
let expr = format!("hive.evalSelectedDrvPaths {}", nodes_expr.expression());
|
let expr = format!("hive.evalSelectedDrvPaths {}", nodes_expr.expression());
|
||||||
|
|
||||||
|
@ -305,6 +319,31 @@ impl Hive {
|
||||||
Ok(parsed)
|
Ok(parsed)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the base expression from which the evaluated Hive can be used.
|
||||||
|
fn get_base_expression(&self) -> String {
|
||||||
|
match self.path() {
|
||||||
|
HivePath::Legacy(path) => {
|
||||||
|
format!(
|
||||||
|
"with builtins; let eval = import {}; hive = eval {{ rawHive = import {}; }}; in ",
|
||||||
|
self.eval_nix.to_str().unwrap(),
|
||||||
|
path.to_str().unwrap(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
HivePath::Flake(flake) => {
|
||||||
|
format!(
|
||||||
|
"with builtins; let eval = import {}; hive = eval {{ flakeUri = \"{}\"; }}; in ",
|
||||||
|
self.eval_nix.to_str().unwrap(),
|
||||||
|
flake.uri(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns whether this Hive is a flake.
|
||||||
|
fn is_flake(&self) -> bool {
|
||||||
|
matches!(self.path(), HivePath::Flake(_))
|
||||||
|
}
|
||||||
|
|
||||||
fn nix_instantiate(&self, expression: &str) -> NixInstantiate {
|
fn nix_instantiate(&self, expression: &str) -> NixInstantiate {
|
||||||
NixInstantiate::new(self, expression.to_owned())
|
NixInstantiate::new(self, expression.to_owned())
|
||||||
}
|
}
|
||||||
|
@ -314,11 +353,6 @@ impl Hive {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct NixInstantiate<'hive> {
|
|
||||||
hive: &'hive Hive,
|
|
||||||
expression: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'hive> NixInstantiate<'hive> {
|
impl<'hive> NixInstantiate<'hive> {
|
||||||
fn new(hive: &'hive Hive, expression: String) -> Self {
|
fn new(hive: &'hive Hive, expression: String) -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
@ -328,38 +362,20 @@ impl<'hive> NixInstantiate<'hive> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn instantiate(&self) -> Command {
|
fn instantiate(&self) -> Command {
|
||||||
// FIXME: unwrap
|
|
||||||
// Technically filenames can be arbitrary byte strings (OsStr),
|
|
||||||
// but Nix may not like it...
|
|
||||||
|
|
||||||
let mut command = Command::new("nix-instantiate");
|
let mut command = Command::new("nix-instantiate");
|
||||||
|
|
||||||
match self.hive.path() {
|
if self.hive.is_flake() {
|
||||||
HivePath::Legacy(path) => {
|
command.args(&["--experimental-features", "flakes"]);
|
||||||
command
|
|
||||||
.arg("--no-gc-warning")
|
|
||||||
.arg("-E")
|
|
||||||
.arg(format!(
|
|
||||||
"with builtins; let eval = import {}; hive = eval {{ rawHive = import {}; }}; in {}",
|
|
||||||
self.hive.eval_nix.to_str().unwrap(),
|
|
||||||
path.to_str().unwrap(),
|
|
||||||
self.expression,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
HivePath::Flake(flake) => {
|
|
||||||
command
|
|
||||||
.args(&["--experimental-features", "flakes"])
|
|
||||||
.arg("--no-gc-warning")
|
|
||||||
.arg("-E")
|
|
||||||
.arg(format!(
|
|
||||||
"with builtins; let eval = import {}; hive = eval {{ flakeUri = \"{}\"; }}; in {}",
|
|
||||||
self.hive.eval_nix.to_str().unwrap(),
|
|
||||||
flake.uri(),
|
|
||||||
self.expression,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let mut full_expression = self.hive.get_base_expression();
|
||||||
|
full_expression += &self.expression;
|
||||||
|
|
||||||
|
command
|
||||||
|
.arg("--no-gc-warning")
|
||||||
|
.arg("-E")
|
||||||
|
.arg(&full_expression);
|
||||||
|
|
||||||
command
|
command
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -393,17 +409,7 @@ impl<'hive> NixInstantiate<'hive> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A serialized Nix expression.
|
impl SerializedNixExpression {
|
||||||
///
|
|
||||||
/// Very hacky and involves an Import From Derivation, so should be
|
|
||||||
/// avoided as much as possible. But I suppose it's more robust than attempting
|
|
||||||
/// to generate Nix expressions directly or escaping a JSON string to strip
|
|
||||||
/// off Nix interpolation.
|
|
||||||
struct SerializedNixExpresssion {
|
|
||||||
json_file: TempPath,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SerializedNixExpresssion {
|
|
||||||
pub fn new<T>(data: T) -> ColmenaResult<Self> where T: Serialize {
|
pub fn new<T>(data: T) -> ColmenaResult<Self> where T: Serialize {
|
||||||
let mut tmp = NamedTempFile::new()?;
|
let mut tmp = NamedTempFile::new()?;
|
||||||
let json = serde_json::to_vec(&data).expect("Could not serialize data");
|
let json = serde_json::to_vec(&data).expect("Could not serialize data");
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue