Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use the stored activate binary appropriate for target platform #14

Merged
merged 9 commits into from
Dec 2, 2020
14 changes: 13 additions & 1 deletion flake.nix
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# SPDX-FileCopyrightText: 2020 Serokell <https://serokell.io/>
# SPDX-FileCopyrightText: 2020 Andreas Fuchs <asf@boinkor.net>
#
# SPDX-License-Identifier: MPL-2.0

Expand Down Expand Up @@ -69,6 +70,15 @@
executable = true;
destination = "/deploy-rs-activate";
})
(pkgs.writeTextFile {
name = base.name + "-activate-rs";
text = ''
#!${pkgs.runtimeShell}
exec ${self.defaultPackage."${system}"}/bin/activate "$@"
'';
executable = true;
destination = "/activate-rs";
})
];
};

Expand All @@ -92,7 +102,9 @@
node_name=$(echo $x | cut -f2 -d:)
profile_name=$(echo $x | cut -f3 -d:)

test -f "$profile_path/deploy-rs-activate" || (echo "#$node_name.$profile_name is missing an activation script" && exit 1);
test -f "$profile_path/deploy-rs-activate" || (echo "#$node_name.$profile_name is missing the deploy-rs-activate activation script" && exit 1);

test -f "$profile_path/activate-rs" || (echo "#$node_name.$profile_name is missing the activate-rs activation script" && exit 1);
done

touch $out
Expand Down
14 changes: 5 additions & 9 deletions src/utils/deploy.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// SPDX-FileCopyrightText: 2020 Serokell <https://serokell.io/>
// SPDX-FileCopyrightText: 2020 Andreas Fuchs <asf@boinkor.net>
//
// SPDX-License-Identifier: MPL-2.0

Expand All @@ -8,7 +9,6 @@ use tokio::process::Command;
use thiserror::Error;

fn build_activate_command(
activate_path_str: String,
sudo: &Option<String>,
profile_path: &str,
closure: &str,
Expand All @@ -18,8 +18,8 @@ fn build_activate_command(
magic_rollback: bool,
) -> String {
let mut self_activate_command = format!(
"{} '{}' '{}' --temp-path {} --confirm-timeout {}",
activate_path_str, profile_path, closure, temp_path, confirm_timeout
"{}/activate-rs '{}' '{}' --temp-path {} --confirm-timeout {}",
closure, profile_path, closure, temp_path, confirm_timeout
);

if magic_rollback {
Expand All @@ -42,15 +42,14 @@ fn test_activation_command_builder() {
let activate_path_str = "/blah/bin/activate".to_string();
let sudo = Some("sudo -u test".to_string());
let profile_path = "/blah/profiles/test";
let closure = "/blah/etc";
let closure = "/nix/store/blah/etc";
let auto_rollback = true;
let temp_path = &"/tmp".into();
let confirm_timeout = 30;
let magic_rollback = true;

assert_eq!(
build_activate_command(
activate_path_str,
&sudo,
profile_path,
closure,
Expand All @@ -59,7 +58,7 @@ fn test_activation_command_builder() {
confirm_timeout,
magic_rollback
),
"sudo -u test /blah/bin/activate '/blah/profiles/test' '/blah/etc' --temp-path /tmp --confirm-timeout 30 --magic-rollback --auto-rollback"
"sudo -u test /nix/store/blah/etc/activate-rs '/blah/profiles/test' '/nix/store/blah/etc' --temp-path /tmp --confirm-timeout 30 --magic-rollback --auto-rollback"
.to_string(),
);
}
Expand Down Expand Up @@ -89,8 +88,6 @@ pub async fn deploy_profile(
deploy_data.profile_name, deploy_data.node_name
);

let activate_path_str = super::deploy_path_to_activate_path_str(&deploy_defs.current_exe)?;

let temp_path: Cow<str> = match &deploy_data.merged_settings.temp_path {
Some(x) => x.into(),
None => "/tmp".into(),
Expand All @@ -103,7 +100,6 @@ pub async fn deploy_profile(
let auto_rollback = deploy_data.merged_settings.auto_rollback.unwrap_or(true);

let self_activate_command = build_activate_command(
activate_path_str,
&deploy_defs.sudo,
&deploy_defs.profile_path,
&deploy_data.profile.profile_settings.path,
Expand Down
38 changes: 1 addition & 37 deletions src/utils/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// SPDX-FileCopyrightText: 2020 Serokell <https://serokell.io/>
// SPDX-FileCopyrightText: 2020 Andreas Fuchs <asf@boinkor.net>
//
// SPDX-License-Identifier: MPL-2.0

Expand Down Expand Up @@ -112,18 +113,13 @@ pub struct DeployDefs {
pub ssh_user: String,
pub profile_user: String,
pub profile_path: String,
pub current_exe: PathBuf,
pub sudo: Option<String>,
}

#[derive(Error, Debug)]
pub enum DeployDataDefsError {
#[error("Neither `user` nor `sshUser` are set for profile {0} of node {1}")]
NoProfileUser(String, String),
#[error("Error reading current executable path: {0}")]
ExecutablePathNotFound(std::io::Error),
#[error("Executable was not in the Nix store")]
NotNixStored,
}

impl<'a> DeployData<'a> {
Expand Down Expand Up @@ -162,18 +158,10 @@ impl<'a> DeployData<'a> {
_ => None,
};

let current_exe =
std::env::current_exe().map_err(DeployDataDefsError::ExecutablePathNotFound)?;

if !current_exe.starts_with("/nix/store/") {
return Err(DeployDataDefsError::NotNixStored);
}

Ok(DeployDefs {
ssh_user,
profile_user,
profile_path,
current_exe,
sudo,
})
}
Expand Down Expand Up @@ -229,27 +217,3 @@ pub enum DeployPathToActivatePathError {
#[error("Deploy path was not valid utf8")]
InvalidUtf8,
}

pub fn deploy_path_to_activate_path_str(
deploy_path: &std::path::Path,
) -> Result<String, DeployPathToActivatePathError> {
Ok(format!(
"{}/activate",
deploy_path
.parent()
.ok_or(DeployPathToActivatePathError::PathTooShort)?
.to_str()
.ok_or(DeployPathToActivatePathError::InvalidUtf8)?
.to_owned()
))
}

#[test]
fn test_activate_path_generation() {
match deploy_path_to_activate_path_str(&std::path::PathBuf::from(
"/blah/blah/deploy-rs/bin/deploy",
)) {
Err(_) => panic!(""),
Ok(x) => assert_eq!(x, "/blah/blah/deploy-rs/bin/activate".to_string()),
}
}
23 changes: 17 additions & 6 deletions src/utils/push.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use std::process::Stdio;
use tokio::process::Command;
use std::path::Path;

use thiserror::Error;

Expand All @@ -15,6 +16,12 @@ pub enum PushProfileError {
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?")]
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:?}")]
Expand Down Expand Up @@ -91,6 +98,16 @@ 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() {
return Err(PushProfileError::DeployRsActivateDoesntExist);
}

if ! Path::new(format!("{}/activate-rs", deploy_data.profile.profile_settings.path).as_str()).exists() {
notgne2 marked this conversation as resolved.
Show resolved Hide resolved
return Err(PushProfileError::ActivateRsDoesntExist);
}



if let Ok(local_key) = std::env::var("LOCAL_KEY") {
info!(
"Signing key present! Signing profile `{}` for node `{}`",
Expand All @@ -103,9 +120,6 @@ pub async fn push_profile(
.arg("-k")
.arg(local_key)
.arg(&deploy_data.profile.profile_settings.path)
.arg(&super::deploy_path_to_activate_path_str(
&deploy_defs.current_exe,
)?)
.status()
.await
.map_err(PushProfileError::SignError)?;
Expand Down Expand Up @@ -150,9 +164,6 @@ pub async fn push_profile(
.arg("--to")
.arg(format!("ssh://{}@{}", deploy_defs.ssh_user, hostname))
.arg(&deploy_data.profile.profile_settings.path)
.arg(&super::deploy_path_to_activate_path_str(
&deploy_defs.current_exe,
)?)
.env("NIX_SSHOPTS", ssh_opts_str)
.status()
.await
Expand Down