aboutsummaryrefslogtreecommitdiff
path: root/src/deploy.rs
diff options
context:
space:
mode:
authorRoman Melnikov2023-09-06 14:54:22 +0200
committerRoman Melnikov2023-09-12 12:00:17 +0200
commitf26e888c41d28107de9dbc5b4e1553c1dfcf83db (patch)
treee3a76bfd3b13bcd2888cabfc7cd6cada32129139 /src/deploy.rs
parent724463b5a94daa810abfc64a4f87faef4e00f984 (diff)
[#201] Deduce profile directory during activation
Problem: Since https://github.com/NixOS/nix/pull/5226 nix profiles for users are stored in 'XDG_STATE_HOME' or 'HOME' directory. However, 'deploy-rs' still expects profiles to be present in '/nix/var/nix/profiles/per-user'. As a result, an attempt to deploy a profile with newer nix may fail with an error about non-existing files. Solution: Instead of deducing the profile path prior to ssh'ing and actual activation, deduce the path to the profile during as a part of 'activate-rs' invocation. Now if the profile path is not specified explicitly as an attribute in profile within the deploy flake, the path to the profile is determined based on the user to which the profile belongs and on the values of 'XDG_STATE_HOME' and 'HOME' variables. Additionally, if the old profile directory (in '/nix/var/nix/profiles/per-user') for a given user already exists, it is used instead for the sake of backward compatibility.
Diffstat (limited to 'src/deploy.rs')
-rw-r--r--src/deploy.rs65
1 files changed, 50 insertions, 15 deletions
diff --git a/src/deploy.rs b/src/deploy.rs
index 574e9b2..41cd58b 100644
--- a/src/deploy.rs
+++ b/src/deploy.rs
@@ -9,11 +9,11 @@ use std::path::Path;
use thiserror::Error;
use tokio::process::Command;
-use crate::DeployDataDefsError;
+use crate::{DeployDataDefsError, ProfileInfo};
struct ActivateCommandData<'a> {
sudo: &'a Option<String>,
- profile_path: &'a str,
+ profile_info: &'a ProfileInfo,
closure: &'a str,
auto_rollback: bool,
temp_path: &'a Path,
@@ -37,8 +37,21 @@ fn build_activate_command(data: &ActivateCommandData) -> String {
}
self_activate_command = format!(
- "{} activate '{}' '{}' --temp-path '{}'",
- self_activate_command, data.closure, data.profile_path, data.temp_path.display()
+ "{} activate '{}' {} --temp-path '{}'",
+ self_activate_command,
+ data.closure,
+ match data.profile_info {
+ ProfileInfo::ProfilePath { profile_path } =>
+ format!("--profile-path '{}'", profile_path),
+ ProfileInfo::ProfileUserAndName {
+ profile_user,
+ profile_name,
+ } => format!(
+ "--profile-user {} --profile-name {}",
+ profile_user, profile_name
+ ),
+ },
+ data.temp_path.display()
);
self_activate_command = format!(
@@ -72,7 +85,9 @@ fn build_activate_command(data: &ActivateCommandData) -> String {
#[test]
fn test_activation_command_builder() {
let sudo = Some("sudo -u test".to_string());
- let profile_path = "/blah/profiles/test";
+ let profile_info = &ProfileInfo::ProfilePath {
+ profile_path: "/blah/profiles/test".to_string(),
+ };
let closure = "/nix/store/blah/etc";
let auto_rollback = true;
let dry_activate = false;
@@ -86,7 +101,7 @@ fn test_activation_command_builder() {
assert_eq!(
build_activate_command(&ActivateCommandData {
sudo: &sudo,
- profile_path,
+ profile_info,
closure,
auto_rollback,
temp_path,
@@ -97,7 +112,7 @@ fn test_activation_command_builder() {
dry_activate,
boot,
}),
- "sudo -u test /nix/store/blah/etc/activate-rs --debug-logs --log-dir /tmp/something.txt activate '/nix/store/blah/etc' '/blah/profiles/test' --temp-path '/tmp' --confirm-timeout 30 --magic-rollback --auto-rollback"
+ "sudo -u test /nix/store/blah/etc/activate-rs --debug-logs --log-dir /tmp/something.txt activate '/nix/store/blah/etc' --profile-path '/blah/profiles/test' --temp-path '/tmp' --confirm-timeout 30 --magic-rollback --auto-rollback"
.to_string(),
);
}
@@ -123,7 +138,9 @@ fn build_wait_command(data: &WaitCommandData) -> String {
self_activate_command = format!(
"{} wait '{}' --temp-path '{}'",
- self_activate_command, data.closure, data.temp_path.display(),
+ self_activate_command,
+ data.closure,
+ data.temp_path.display(),
);
if let Some(sudo_cmd) = &data.sudo {
@@ -157,7 +174,7 @@ fn test_wait_command_builder() {
struct RevokeCommandData<'a> {
sudo: &'a Option<String>,
closure: &'a str,
- profile_path: &'a str,
+ profile_info: ProfileInfo,
debug_logs: bool,
log_dir: Option<&'a str>,
}
@@ -173,7 +190,21 @@ fn build_revoke_command(data: &RevokeCommandData) -> String {
self_activate_command = format!("{} --log-dir {}", self_activate_command, log_dir);
}
- self_activate_command = format!("{} revoke '{}'", self_activate_command, data.profile_path);
+ self_activate_command = format!(
+ "{} revoke {}",
+ self_activate_command,
+ match &data.profile_info {
+ ProfileInfo::ProfilePath { profile_path } =>
+ format!("--profile-path '{}'", profile_path),
+ ProfileInfo::ProfileUserAndName {
+ profile_user,
+ profile_name,
+ } => format!(
+ "--profile-user {} --profile-name {}",
+ profile_user, profile_name
+ ),
+ }
+ );
if let Some(sudo_cmd) = &data.sudo {
self_activate_command = format!("{} {}", sudo_cmd, self_activate_command);
@@ -186,7 +217,9 @@ fn build_revoke_command(data: &RevokeCommandData) -> String {
fn test_revoke_command_builder() {
let sudo = Some("sudo -u test".to_string());
let closure = "/nix/store/blah/etc";
- let profile_path = "/nix/var/nix/per-user/user/profile";
+ let profile_info = ProfileInfo::ProfilePath {
+ profile_path: "/nix/var/nix/per-user/user/profile".to_string(),
+ };
let debug_logs = true;
let log_dir = Some("/tmp/something.txt");
@@ -194,11 +227,11 @@ fn test_revoke_command_builder() {
build_revoke_command(&RevokeCommandData {
sudo: &sudo,
closure,
- profile_path,
+ profile_info,
debug_logs,
log_dir
}),
- "sudo -u test /nix/store/blah/etc/activate-rs --debug-logs --log-dir /tmp/something.txt revoke '/nix/var/nix/per-user/user/profile'"
+ "sudo -u test /nix/store/blah/etc/activate-rs --debug-logs --log-dir /tmp/something.txt revoke --profile-path '/nix/var/nix/per-user/user/profile'"
.to_string(),
);
}
@@ -271,6 +304,8 @@ pub enum DeployProfileError {
#[error("Error confirming deployment: {0}")]
Confirm(#[from] ConfirmProfileError),
+ #[error("Deployment data invalid: {0}")]
+ InvalidDeployDataDefs(#[from] DeployDataDefsError),
}
pub async fn deploy_profile(
@@ -299,7 +334,7 @@ pub async fn deploy_profile(
let self_activate_command = build_activate_command(&ActivateCommandData {
sudo: &deploy_defs.sudo,
- profile_path: &deploy_defs.profile_path,
+ profile_info: &deploy_data.get_profile_info()?,
closure: &deploy_data.profile.profile_settings.path,
auto_rollback,
temp_path: temp_path,
@@ -439,7 +474,7 @@ pub async fn revoke(
let self_revoke_command = build_revoke_command(&RevokeCommandData {
sudo: &deploy_defs.sudo,
closure: &deploy_data.profile.profile_settings.path,
- profile_path: &deploy_data.get_profile_path()?,
+ profile_info: deploy_data.get_profile_info()?,
debug_logs: deploy_data.debug_logs,
log_dir: deploy_data.log_dir,
});