aboutsummaryrefslogtreecommitdiff
path: root/src/utils
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/data.rs (renamed from src/utils/data.rs)0
-rw-r--r--src/deploy.rs (renamed from src/utils/deploy.rs)111
-rw-r--r--src/lib.rs (renamed from src/utils/mod.rs)22
-rw-r--r--src/push.rs (renamed from src/utils/push.rs)95
4 files changed, 118 insertions, 110 deletions
diff --git a/src/utils/data.rs b/src/data.rs
index f557e41..f557e41 100644
--- a/src/utils/data.rs
+++ b/src/data.rs
diff --git a/src/utils/deploy.rs b/src/deploy.rs
index 3371160..a33721c 100644
--- a/src/utils/deploy.rs
+++ b/src/deploy.rs
@@ -8,46 +8,48 @@ use tokio::process::Command;
use thiserror::Error;
-fn build_activate_command(
- sudo: &Option<String>,
- profile_path: &str,
- closure: &str,
+struct ActivateCommandData<'a> {
+ sudo: &'a Option<String>,
+ profile_path: &'a str,
+ closure: &'a str,
auto_rollback: bool,
- temp_path: &Cow<str>,
+ temp_path: &'a str,
confirm_timeout: u16,
magic_rollback: bool,
debug_logs: bool,
- log_dir: Option<&str>,
-) -> String {
- let mut self_activate_command = format!("{}/activate-rs", closure);
+ log_dir: Option<&'a str>,
+}
+
+fn build_activate_command(data: ActivateCommandData) -> String {
+ let mut self_activate_command = format!("{}/activate-rs", data.closure);
- if debug_logs {
+ if data.debug_logs {
self_activate_command = format!("{} --debug-logs", self_activate_command);
}
- if let Some(log_dir) = log_dir {
+ if let Some(log_dir) = data.log_dir {
self_activate_command = format!("{} --log-dir {}", self_activate_command, log_dir);
}
self_activate_command = format!(
"{} --temp-path '{}' activate '{}' '{}'",
- self_activate_command, temp_path, closure, profile_path
+ self_activate_command, data.temp_path, data.closure, data.profile_path
);
self_activate_command = format!(
"{} --confirm-timeout {}",
- self_activate_command, confirm_timeout
+ self_activate_command, data.confirm_timeout
);
- if magic_rollback {
+ if data.magic_rollback {
self_activate_command = format!("{} --magic-rollback", self_activate_command);
}
- if auto_rollback {
+ if data.auto_rollback {
self_activate_command = format!("{} --auto-rollback", self_activate_command);
}
- if let Some(sudo_cmd) = &sudo {
+ if let Some(sudo_cmd) = &data.sudo {
self_activate_command = format!("{} {}", sudo_cmd, self_activate_command);
}
@@ -60,15 +62,15 @@ fn test_activation_command_builder() {
let profile_path = "/blah/profiles/test";
let closure = "/nix/store/blah/etc";
let auto_rollback = true;
- let temp_path = &"/tmp".into();
+ let temp_path = "/tmp";
let confirm_timeout = 30;
let magic_rollback = true;
let debug_logs = true;
let log_dir = Some("/tmp/something.txt");
assert_eq!(
- build_activate_command(
- &sudo,
+ build_activate_command(ActivateCommandData {
+ sudo: &sudo,
profile_path,
closure,
auto_rollback,
@@ -77,35 +79,37 @@ fn test_activation_command_builder() {
magic_rollback,
debug_logs,
log_dir
- ),
+ }),
"sudo -u test /nix/store/blah/etc/activate-rs --debug-logs --log-dir /tmp/something.txt --temp-path '/tmp' activate '/nix/store/blah/etc' '/blah/profiles/test' --confirm-timeout 30 --magic-rollback --auto-rollback"
.to_string(),
);
}
-fn build_wait_command(
- sudo: &Option<String>,
- closure: &str,
- temp_path: &Cow<str>,
+struct WaitCommandData<'a> {
+ sudo: &'a Option<String>,
+ closure: &'a str,
+ temp_path: &'a str,
debug_logs: bool,
- log_dir: Option<&str>,
-) -> String {
- let mut self_activate_command = format!("{}/activate-rs", closure);
+ log_dir: Option<&'a str>,
+}
- if debug_logs {
+fn build_wait_command(data: WaitCommandData) -> String {
+ let mut self_activate_command = format!("{}/activate-rs", data.closure);
+
+ if data.debug_logs {
self_activate_command = format!("{} --debug-logs", self_activate_command);
}
- if let Some(log_dir) = log_dir {
+ if let Some(log_dir) = data.log_dir {
self_activate_command = format!("{} --log-dir {}", self_activate_command, log_dir);
}
self_activate_command = format!(
"{} --temp-path '{}' wait '{}'",
- self_activate_command, temp_path, closure
+ self_activate_command, data.temp_path, data.closure
);
- if let Some(sudo_cmd) = &sudo {
+ if let Some(sudo_cmd) = &data.sudo {
self_activate_command = format!("{} {}", sudo_cmd, self_activate_command);
}
@@ -116,18 +120,18 @@ fn build_wait_command(
fn test_wait_command_builder() {
let sudo = Some("sudo -u test".to_string());
let closure = "/nix/store/blah/etc";
- let temp_path = &"/tmp".into();
+ let temp_path = "/tmp";
let debug_logs = true;
let log_dir = Some("/tmp/something.txt");
assert_eq!(
- build_wait_command(
- &sudo,
+ build_wait_command(WaitCommandData {
+ sudo: &sudo,
closure,
temp_path,
debug_logs,
log_dir
- ),
+ }),
"sudo -u test /nix/store/blah/etc/activate-rs --debug-logs --log-dir /tmp/something.txt --temp-path '/tmp' wait '/nix/store/blah/etc'"
.to_string(),
);
@@ -135,9 +139,6 @@ fn test_wait_command_builder() {
#[derive(Error, Debug)]
pub enum DeployProfileError {
- #[error("Failed to calculate activate bin path from deploy bin path: {0}")]
- DeployPathToActivatePathError(#[from] super::DeployPathToActivatePathError),
-
#[error("Failed to spawn activation command over SSH: {0}")]
SSHSpawnActivateError(std::io::Error),
@@ -179,30 +180,20 @@ pub async fn deploy_profile(
let auto_rollback = deploy_data.merged_settings.auto_rollback.unwrap_or(true);
- let self_activate_command = build_activate_command(
- &deploy_defs.sudo,
- &deploy_defs.profile_path,
- &deploy_data.profile.profile_settings.path,
+ let self_activate_command = build_activate_command(ActivateCommandData {
+ sudo: &deploy_defs.sudo,
+ profile_path: &deploy_defs.profile_path,
+ closure: &deploy_data.profile.profile_settings.path,
auto_rollback,
- &temp_path,
+ temp_path: &temp_path,
confirm_timeout,
magic_rollback,
- deploy_data.debug_logs,
- deploy_data.log_dir,
- );
+ debug_logs: deploy_data.debug_logs,
+ log_dir: deploy_data.log_dir,
+ });
debug!("Constructed activation command: {}", self_activate_command);
- let self_wait_command = build_wait_command(
- &deploy_defs.sudo,
- &deploy_data.profile.profile_settings.path,
- &temp_path,
- deploy_data.debug_logs,
- deploy_data.log_dir,
- );
-
- debug!("Constructed wait command: {}", self_wait_command);
-
let hostname = match deploy_data.cmd_overrides.hostname {
Some(ref x) => x,
None => &deploy_data.node.node_settings.hostname,
@@ -231,6 +222,16 @@ pub async fn deploy_profile(
info!("Success activating, done!");
} else {
+ let self_wait_command = build_wait_command(WaitCommandData {
+ sudo: &deploy_defs.sudo,
+ closure: &deploy_data.profile.profile_settings.path,
+ temp_path: &temp_path,
+ debug_logs: deploy_data.debug_logs,
+ log_dir: deploy_data.log_dir,
+ });
+
+ debug!("Constructed wait command: {}", self_wait_command);
+
let ssh_activate = ssh_activate_command
.arg(self_activate_command)
.spawn()
diff --git a/src/utils/mod.rs b/src/lib.rs
index bc46f4c..edc0507 100644
--- a/src/utils/mod.rs
+++ b/src/lib.rs
@@ -11,17 +11,15 @@ use thiserror::Error;
use flexi_logger::*;
-#[macro_export]
-macro_rules! good_panic {
- ($($tts:tt)*) => {{
- error!($($tts)*);
- std::process::exit(1);
- }}
-}
+#[macro_use]
+extern crate log;
+
+#[macro_use]
+extern crate serde_derive;
pub fn make_lock_path(temp_path: &str, closure: &str) -> String {
let lock_hash =
- &closure["/nix/store/".len()..closure.find("-").unwrap_or_else(|| closure.len())];
+ &closure["/nix/store/".len()..closure.find('-').unwrap_or_else(|| closure.len())];
format!("{}/deploy-rs-canary-{}", temp_path, lock_hash)
}
@@ -416,11 +414,3 @@ pub fn make_deploy_data<'a, 's>(
log_dir,
}
}
-
-#[derive(Error, Debug)]
-pub enum DeployPathToActivatePathError {
- #[error("Deploy path did not have a parent directory")]
- PathTooShort,
- #[error("Deploy path was not valid utf8")]
- InvalidUtf8,
-}
diff --git a/src/utils/push.rs b/src/push.rs
index 503e062..2f83019 100644
--- a/src/utils/push.rs
+++ b/src/push.rs
@@ -2,22 +2,22 @@
//
// SPDX-License-Identifier: MPL-2.0
+use std::path::Path;
use std::process::Stdio;
use tokio::process::Command;
-use std::path::Path;
use thiserror::Error;
#[derive(Error, Debug)]
pub enum PushProfileError {
- #[error("Failed to calculate activate bin path from deploy bin path: {0}")]
- DeployPathToActivatePathError(#[from] super::DeployPathToActivatePathError),
#[error("Failed to run Nix build command: {0}")]
BuildError(std::io::Error),
#[error("Nix build command resulted in a bad exit code: {0:?}")]
BuildExitError(Option<i32>),
- #[error("Activation script deploy-rs-activate does not exist in profile.\n\
- Did you forget to use deploy-rs#lib.<...>.activate.<...> on your profile path?")]
+ #[error(
+ "Activation script deploy-rs-activate does not exist in profile.\n\
+ Did you forget to use deploy-rs#lib.<...>.activate.<...> on your profile path?"
+ )]
DeployRsActivateDoesntExist,
#[error("Activation script activate-rs does not exist in profile.\n\
Is there a mismatch in deploy-rs used in the flake you're deploying and deploy-rs command you're running?")]
@@ -32,53 +32,55 @@ pub enum PushProfileError {
CopyExitError(Option<i32>),
}
-pub async fn push_profile(
- supports_flakes: bool,
- check_sigs: bool,
- repo: &str,
- deploy_data: &super::DeployData<'_>,
- deploy_defs: &super::DeployDefs,
- keep_result: bool,
- result_path: Option<&str>,
- extra_build_args: &[String],
-) -> Result<(), PushProfileError> {
+pub struct PushProfileData<'a> {
+ pub supports_flakes: bool,
+ pub check_sigs: bool,
+ pub repo: &'a str,
+ pub deploy_data: &'a super::DeployData<'a>,
+ pub deploy_defs: &'a super::DeployDefs,
+ pub keep_result: bool,
+ pub result_path: Option<&'a str>,
+ pub extra_build_args: &'a [String],
+}
+
+pub async fn push_profile(data: PushProfileData<'_>) -> Result<(), PushProfileError> {
info!(
"Building profile `{}` for node `{}`",
- deploy_data.profile_name, deploy_data.node_name
+ data.deploy_data.profile_name, data.deploy_data.node_name
);
- let mut build_c = if supports_flakes {
+ let mut build_c = if data.supports_flakes {
Command::new("nix")
} else {
Command::new("nix-build")
};
- let mut build_command = if supports_flakes {
+ let mut build_command = if data.supports_flakes {
build_c.arg("build").arg(format!(
"{}#deploy.nodes.\"{}\".profiles.\"{}\".path",
- repo, deploy_data.node_name, deploy_data.profile_name
+ data.repo, data.deploy_data.node_name, data.deploy_data.profile_name
))
} else {
- build_c.arg(&repo).arg("-A").arg(format!(
+ build_c.arg(&data.repo).arg("-A").arg(format!(
"deploy.nodes.\"{}\".profiles.\"{}\".path",
- deploy_data.node_name, deploy_data.profile_name
+ data.deploy_data.node_name, data.deploy_data.profile_name
))
};
- build_command = match (keep_result, supports_flakes) {
+ build_command = match (data.keep_result, data.supports_flakes) {
(true, _) => {
- let result_path = result_path.unwrap_or("./.deploy-gc");
+ let result_path = data.result_path.unwrap_or("./.deploy-gc");
build_command.arg("--out-link").arg(format!(
"{}/{}/{}",
- result_path, deploy_data.node_name, deploy_data.profile_name
+ result_path, data.deploy_data.node_name, data.deploy_data.profile_name
))
}
(false, false) => build_command.arg("--no-out-link"),
(false, true) => build_command.arg("--no-link"),
};
- for extra_arg in extra_build_args {
+ for extra_arg in data.extra_build_args {
build_command = build_command.arg(extra_arg);
}
@@ -94,20 +96,34 @@ pub async fn push_profile(
a => return Err(PushProfileError::BuildExitError(a)),
};
- if ! Path::new(format!("{}/deploy-rs-activate", deploy_data.profile.profile_settings.path).as_str()).exists() {
+ if !Path::new(
+ format!(
+ "{}/deploy-rs-activate",
+ data.deploy_data.profile.profile_settings.path
+ )
+ .as_str(),
+ )
+ .exists()
+ {
return Err(PushProfileError::DeployRsActivateDoesntExist);
}
- if ! Path::new(format!("{}/activate-rs", deploy_data.profile.profile_settings.path).as_str()).exists() {
+ if !Path::new(
+ format!(
+ "{}/activate-rs",
+ data.deploy_data.profile.profile_settings.path
+ )
+ .as_str(),
+ )
+ .exists()
+ {
return Err(PushProfileError::ActivateRsDoesntExist);
}
-
-
if let Ok(local_key) = std::env::var("LOCAL_KEY") {
info!(
"Signing key present! Signing profile `{}` for node `{}`",
- deploy_data.profile_name, deploy_data.node_name
+ data.deploy_data.profile_name, data.deploy_data.node_name
);
let sign_exit_status = Command::new("nix")
@@ -115,7 +131,7 @@ pub async fn push_profile(
.arg("-r")
.arg("-k")
.arg(local_key)
- .arg(&deploy_data.profile.profile_settings.path)
+ .arg(&data.deploy_data.profile.profile_settings.path)
.status()
.await
.map_err(PushProfileError::SignError)?;
@@ -128,21 +144,22 @@ pub async fn push_profile(
debug!(
"Copying profile `{}` to node `{}`",
- deploy_data.profile_name, deploy_data.node_name
+ data.deploy_data.profile_name, data.deploy_data.node_name
);
let mut copy_command_ = Command::new("nix");
let mut copy_command = copy_command_.arg("copy");
- if deploy_data.merged_settings.fast_connection != Some(true) {
+ if data.deploy_data.merged_settings.fast_connection != Some(true) {
copy_command = copy_command.arg("--substitute-on-destination");
}
- if !check_sigs {
+ if !data.check_sigs {
copy_command = copy_command.arg("--no-check-sigs");
}
- let ssh_opts_str = deploy_data
+ let ssh_opts_str = data
+ .deploy_data
.merged_settings
.ssh_opts
// This should provide some extra safety, but it also breaks for some reason, oh well
@@ -151,15 +168,15 @@ pub async fn push_profile(
// .collect::<Vec<String>>()
.join(" ");
- let hostname = match deploy_data.cmd_overrides.hostname {
+ let hostname = match data.deploy_data.cmd_overrides.hostname {
Some(ref x) => x,
- None => &deploy_data.node.node_settings.hostname,
+ None => &data.deploy_data.node.node_settings.hostname,
};
let copy_exit_status = copy_command
.arg("--to")
- .arg(format!("ssh://{}@{}", deploy_defs.ssh_user, hostname))
- .arg(&deploy_data.profile.profile_settings.path)
+ .arg(format!("ssh://{}@{}", data.deploy_defs.ssh_user, hostname))
+ .arg(&data.deploy_data.profile.profile_settings.path)
.env("NIX_SSHOPTS", ssh_opts_str)
.status()
.await