aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Bantyev2021-06-25 11:28:52 +0300
committerAlexander Bantyev2021-07-02 19:28:49 +0300
commit220f07199e6442370ccbf8bd970306b8378ae100 (patch)
tree0b8fd9cf73df0637e3b7ddc8eec88a9ab9629372
parentf973cb571caa194f38c0c60771ad23eb11a12b10 (diff)
Evaluate only once, and then only realise
-rw-r--r--src/push.rs56
1 files changed, 47 insertions, 9 deletions
diff --git a/src/push.rs b/src/push.rs
index 4879372..fbf6ed7 100644
--- a/src/push.rs
+++ b/src/push.rs
@@ -3,6 +3,7 @@
// SPDX-License-Identifier: MPL-2.0
use log::{debug, info};
+use std::collections::HashMap;
use std::path::Path;
use std::process::Stdio;
use thiserror::Error;
@@ -10,6 +11,16 @@ use tokio::process::Command;
#[derive(Error, Debug)]
pub enum PushProfileError {
+ #[error("Failed to run Nix show-derivation command: {0}")]
+ ShowDerivationError(std::io::Error),
+ #[error("Nix show-derivation command resulted in a bad exit code: {0:?}")]
+ ShowDerivationExitError(Option<i32>),
+ #[error("Nix show-derivation command output contained an invalid UTF-8 sequence: {0}")]
+ ShowDerivationUtf8Error(std::str::Utf8Error),
+ #[error("Failed to parse the output of nix show-derivation: {0}")]
+ ShowDerivationParseError(serde_json::Error),
+ #[error("Nix show-derivation output is empty")]
+ ShowDerivationEmpty,
#[error("Failed to run Nix build command: {0}")]
BuildError(std::io::Error),
#[error("Nix build command resulted in a bad exit code: {0:?}")]
@@ -44,6 +55,39 @@ pub struct PushProfileData<'a> {
}
pub async fn push_profile(data: PushProfileData<'_>) -> Result<(), PushProfileError> {
+ debug!(
+ "Finding the deriver of store path for {}",
+ &data.deploy_data.profile.profile_settings.path
+ );
+
+ // `nix-store --query --deriver` doesn't work on invalid paths, so we parse output of show-derivation :(
+ let mut show_derivation_command = Command::new("nix");
+
+ show_derivation_command
+ .arg("show-derivation")
+ .arg(&data.deploy_data.profile.profile_settings.path);
+
+ let show_derivation_output = show_derivation_command
+ .output()
+ .await
+ .map_err(PushProfileError::ShowDerivationError)?;
+
+ match show_derivation_output.status.code() {
+ Some(0) => (),
+ a => return Err(PushProfileError::ShowDerivationExitError(a)),
+ };
+
+ let derivation_info: HashMap<&str, serde_json::value::Value> = serde_json::from_str(
+ std::str::from_utf8(&show_derivation_output.stdout)
+ .map_err(PushProfileError::ShowDerivationUtf8Error)?,
+ )
+ .map_err(PushProfileError::ShowDerivationParseError)?;
+
+ let derivation_name = derivation_info
+ .keys()
+ .next()
+ .ok_or(PushProfileError::ShowDerivationEmpty)?;
+
info!(
"Building profile `{}` for node `{}`",
data.deploy_data.profile_name, data.deploy_data.node_name
@@ -56,15 +100,9 @@ pub async fn push_profile(data: PushProfileData<'_>) -> Result<(), PushProfileEr
};
if data.supports_flakes {
- build_command.arg("build").arg(format!(
- "{}#deploy.nodes.\"{}\".profiles.\"{}\".path",
- data.repo, data.deploy_data.node_name, data.deploy_data.profile_name
- ))
+ build_command.arg("build").arg(derivation_name)
} else {
- build_command.arg(&data.repo).arg("-A").arg(format!(
- "deploy.nodes.\"{}\".profiles.\"{}\".path",
- data.deploy_data.node_name, data.deploy_data.profile_name
- ))
+ build_command.arg(derivation_name)
};
match (data.keep_result, data.supports_flakes) {
@@ -142,7 +180,7 @@ pub async fn push_profile(data: PushProfileData<'_>) -> Result<(), PushProfileEr
};
}
- debug!(
+ info!(
"Copying profile `{}` to node `{}`",
data.deploy_data.profile_name, data.deploy_data.node_name
);