From 70c55363a91572790ba5d49b70c58040f112e55c Mon Sep 17 00:00:00 2001 From: notgne2 Date: Fri, 8 Jan 2021 18:24:04 -0700 Subject: Restructure project --- src/push.rs | 174 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 174 insertions(+) create mode 100644 src/push.rs (limited to 'src/push.rs') diff --git a/src/push.rs b/src/push.rs new file mode 100644 index 0000000..503e062 --- /dev/null +++ b/src/push.rs @@ -0,0 +1,174 @@ +// SPDX-FileCopyrightText: 2020 Serokell +// +// SPDX-License-Identifier: MPL-2.0 + +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), + #[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?")] + ActivateRsDoesntExist, + #[error("Failed to run Nix sign command: {0}")] + SignError(std::io::Error), + #[error("Nix sign command resulted in a bad exit code: {0:?}")] + SignExitError(Option), + #[error("Failed to run Nix copy command: {0}")] + CopyError(std::io::Error), + #[error("Nix copy command resulted in a bad exit code: {0:?}")] + CopyExitError(Option), +} + +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> { + info!( + "Building profile `{}` for node `{}`", + deploy_data.profile_name, deploy_data.node_name + ); + + let mut build_c = if supports_flakes { + Command::new("nix") + } else { + Command::new("nix-build") + }; + + let mut build_command = if supports_flakes { + build_c.arg("build").arg(format!( + "{}#deploy.nodes.\"{}\".profiles.\"{}\".path", + repo, deploy_data.node_name, deploy_data.profile_name + )) + } else { + build_c.arg(&repo).arg("-A").arg(format!( + "deploy.nodes.\"{}\".profiles.\"{}\".path", + deploy_data.node_name, deploy_data.profile_name + )) + }; + + build_command = match (keep_result, supports_flakes) { + (true, _) => { + let result_path = result_path.unwrap_or("./.deploy-gc"); + + build_command.arg("--out-link").arg(format!( + "{}/{}/{}", + result_path, deploy_data.node_name, 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 { + build_command = build_command.arg(extra_arg); + } + + let build_exit_status = build_command + // Logging should be in stderr, this just stops the store path from printing for no reason + .stdout(Stdio::null()) + .status() + .await + .map_err(PushProfileError::BuildError)?; + + match build_exit_status.code() { + Some(0) => (), + a => return Err(PushProfileError::BuildExitError(a)), + }; + + if ! Path::new(format!("{}/deploy-rs-activate", 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() { + 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 + ); + + let sign_exit_status = Command::new("nix") + .arg("sign-paths") + .arg("-r") + .arg("-k") + .arg(local_key) + .arg(&deploy_data.profile.profile_settings.path) + .status() + .await + .map_err(PushProfileError::SignError)?; + + match sign_exit_status.code() { + Some(0) => (), + a => return Err(PushProfileError::SignExitError(a)), + }; + } + + debug!( + "Copying profile `{}` to node `{}`", + deploy_data.profile_name, 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) { + copy_command = copy_command.arg("--substitute-on-destination"); + } + + if !check_sigs { + copy_command = copy_command.arg("--no-check-sigs"); + } + + let ssh_opts_str = deploy_data + .merged_settings + .ssh_opts + // This should provide some extra safety, but it also breaks for some reason, oh well + // .iter() + // .map(|x| format!("'{}'", x)) + // .collect::>() + .join(" "); + + let hostname = match deploy_data.cmd_overrides.hostname { + Some(ref x) => x, + None => &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) + .env("NIX_SSHOPTS", ssh_opts_str) + .status() + .await + .map_err(PushProfileError::CopyError)?; + + match copy_exit_status.code() { + Some(0) => (), + a => return Err(PushProfileError::CopyExitError(a)), + }; + + Ok(()) +} -- cgit v1.2.3 From e03c66ffbafd59932871fda8c79d907030b2d9c3 Mon Sep 17 00:00:00 2001 From: notgne2 Date: Fri, 8 Jan 2021 18:57:16 -0700 Subject: Struct-ify arguments to push_profile --- src/push.rs | 93 +++++++++++++++++++++++++++++++++++++------------------------ 1 file changed, 56 insertions(+), 37 deletions(-) (limited to 'src/push.rs') diff --git a/src/push.rs b/src/push.rs index 503e062..e7456cc 100644 --- a/src/push.rs +++ b/src/push.rs @@ -2,9 +2,9 @@ // // 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; @@ -16,8 +16,10 @@ pub enum PushProfileError { BuildError(std::io::Error), #[error("Nix build command resulted in a bad exit code: {0:?}")] BuildExitError(Option), - #[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 +34,55 @@ pub enum PushProfileError { CopyExitError(Option), } -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 +98,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 +133,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 +146,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 +170,15 @@ pub async fn push_profile( // .collect::>() .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 -- cgit v1.2.3 From dc26fba1bd908fbdf1b3d702ad67cbb351952e7a Mon Sep 17 00:00:00 2001 From: notgne2 Date: Fri, 8 Jan 2021 19:08:34 -0700 Subject: Remove unused DeployPathToActivatePathError --- src/push.rs | 2 -- 1 file changed, 2 deletions(-) (limited to 'src/push.rs') diff --git a/src/push.rs b/src/push.rs index e7456cc..2f83019 100644 --- a/src/push.rs +++ b/src/push.rs @@ -10,8 +10,6 @@ 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:?}")] -- cgit v1.2.3