Skip to content

Commit d01e940

Browse files
committed
feat: add --remote-bin-path option (#298)
1 parent 6bc76b8 commit d01e940

File tree

7 files changed

+287
-116
lines changed

7 files changed

+287
-116
lines changed

interface.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@
3838
},
3939
"interactiveSudo": {
4040
"type": "boolean"
41+
},
42+
"remoteBinPath": {
43+
"type": "string"
4144
}
4245
}
4346
},

src/bin/activate.rs

Lines changed: 76 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,10 @@ struct ActivateOpts {
9090
/// Path for any temporary files that may be needed during activation
9191
#[arg(long)]
9292
temp_path: PathBuf,
93+
94+
/// Path to where the nix-store and nix-env binaries are stored
95+
#[arg(long)]
96+
bin_path: Option<PathBuf>,
9397
}
9498

9599
/// Wait for profile activation
@@ -119,6 +123,10 @@ struct RevokeOpts {
119123
/// The profile name
120124
#[arg(long, requires = "profile_user")]
121125
profile_name: Option<String>,
126+
127+
/// Path to where the nix-store and nix-env binaries are stored
128+
#[arg(long)]
129+
bin_path: Option<PathBuf>,
122130
}
123131

124132
#[derive(Error, Debug)]
@@ -143,10 +151,26 @@ pub enum DeactivateError {
143151
ReactivateExit(Option<i32>),
144152
}
145153

146-
pub async fn deactivate(profile_path: &str) -> Result<(), DeactivateError> {
154+
fn create_command(program: impl Into<String>, bin_path: &Option<PathBuf>) -> Command {
155+
let mut command = Command::new(program.into());
156+
157+
if let (Some(bin_path), Ok(path_env)) = (bin_path, std::env::var("PATH")) {
158+
command.env(
159+
"PATH",
160+
format!("{}:{}", bin_path.to_string_lossy(), path_env),
161+
);
162+
}
163+
164+
command
165+
}
166+
167+
pub async fn deactivate(
168+
profile_path: &str,
169+
bin_path: Option<PathBuf>,
170+
) -> Result<(), DeactivateError> {
147171
warn!("De-activating due to error");
148172

149-
let nix_env_rollback_exit_status = Command::new("nix-env")
173+
let nix_env_rollback_exit_status = create_command("nix-env", &bin_path)
150174
.arg("-p")
151175
.arg(&profile_path)
152176
.arg("--rollback")
@@ -161,7 +185,7 @@ pub async fn deactivate(profile_path: &str) -> Result<(), DeactivateError> {
161185

162186
debug!("Listing generations");
163187

164-
let nix_env_list_generations_out = Command::new("nix-env")
188+
let nix_env_list_generations_out = create_command("nix-env", &bin_path)
165189
.arg("-p")
166190
.arg(&profile_path)
167191
.arg("--list-generations")
@@ -190,7 +214,7 @@ pub async fn deactivate(profile_path: &str) -> Result<(), DeactivateError> {
190214
debug!("Removing generation entry {}", last_generation_line);
191215
warn!("Removing generation by ID {}", last_generation_id);
192216

193-
let nix_env_delete_generation_exit_status = Command::new("nix-env")
217+
let nix_env_delete_generation_exit_status = create_command("nix-env", &bin_path)
194218
.arg("-p")
195219
.arg(&profile_path)
196220
.arg("--delete-generations")
@@ -206,12 +230,13 @@ pub async fn deactivate(profile_path: &str) -> Result<(), DeactivateError> {
206230

207231
info!("Attempting to re-activate the last generation");
208232

209-
let re_activate_exit_status = Command::new(format!("{}/deploy-rs-activate", profile_path))
210-
.env("PROFILE", &profile_path)
211-
.current_dir(&profile_path)
212-
.status()
213-
.await
214-
.map_err(DeactivateError::Reactivate)?;
233+
let re_activate_exit_status =
234+
create_command(format!("{}/deploy-rs-activate", profile_path), &bin_path)
235+
.env("PROFILE", &profile_path)
236+
.current_dir(&profile_path)
237+
.status()
238+
.await
239+
.map_err(DeactivateError::Reactivate)?;
215240

216241
match re_activate_exit_status.code() {
217242
Some(0) => (),
@@ -315,7 +340,11 @@ pub enum WaitError {
315340
#[error("Error waiting for activation: {0}")]
316341
Waiting(#[from] DangerZoneError),
317342
}
318-
pub async fn wait(temp_path: PathBuf, closure: String, activation_timeout: Option<u16>) -> Result<(), WaitError> {
343+
pub async fn wait(
344+
temp_path: PathBuf,
345+
closure: String,
346+
activation_timeout: Option<u16>,
347+
) -> Result<(), WaitError> {
319348
let lock_path = deploy::make_lock_path(&temp_path, &closure);
320349

321350
let (created, done) = mpsc::channel(1);
@@ -386,14 +415,16 @@ pub async fn activate(
386415
closure: String,
387416
auto_rollback: bool,
388417
temp_path: PathBuf,
418+
bin_path: Option<PathBuf>,
389419
confirm_timeout: u16,
390420
magic_rollback: bool,
391421
dry_activate: bool,
392422
boot: bool,
393423
) -> Result<(), ActivateError> {
394424
if !dry_activate {
395425
info!("Activating profile");
396-
let nix_env_set_exit_status = Command::new("nix-env")
426+
427+
let nix_env_set_exit_status = create_command("nix-env", &bin_path)
397428
.arg("-p")
398429
.arg(&profile_path)
399430
.arg("--set")
@@ -405,7 +436,7 @@ pub async fn activate(
405436
Some(0) => (),
406437
a => {
407438
if auto_rollback && !dry_activate {
408-
deactivate(&profile_path).await?;
439+
deactivate(&profile_path, bin_path).await?;
409440
}
410441
return Err(ActivateError::SetProfileExit(a));
411442
}
@@ -420,19 +451,22 @@ pub async fn activate(
420451
&profile_path
421452
};
422453

423-
let activate_status = match Command::new(format!("{}/deploy-rs-activate", activation_location))
424-
.env("PROFILE", activation_location)
425-
.env("DRY_ACTIVATE", if dry_activate { "1" } else { "0" })
426-
.env("BOOT", if boot { "1" } else { "0" })
427-
.current_dir(activation_location)
428-
.status()
429-
.await
430-
.map_err(ActivateError::RunActivate)
454+
let activate_status = match create_command(
455+
format!("{}/deploy-rs-activate", activation_location),
456+
&bin_path,
457+
)
458+
.env("PROFILE", activation_location)
459+
.env("DRY_ACTIVATE", if dry_activate { "1" } else { "0" })
460+
.env("BOOT", if boot { "1" } else { "0" })
461+
.current_dir(activation_location)
462+
.status()
463+
.await
464+
.map_err(ActivateError::RunActivate)
431465
{
432466
Ok(x) => x,
433467
Err(e) => {
434468
if auto_rollback && !dry_activate {
435-
deactivate(&profile_path).await?;
469+
deactivate(&profile_path, bin_path).await?;
436470
}
437471
return Err(e);
438472
}
@@ -443,7 +477,7 @@ pub async fn activate(
443477
Some(0) => (),
444478
a => {
445479
if auto_rollback {
446-
deactivate(&profile_path).await?;
480+
deactivate(&profile_path, bin_path).await?;
447481
}
448482
return Err(ActivateError::RunActivateExit(a));
449483
}
@@ -456,7 +490,7 @@ pub async fn activate(
456490
if magic_rollback && !boot {
457491
info!("Magic rollback is enabled, setting up confirmation hook...");
458492
if let Err(err) = activation_confirmation(temp_path, confirm_timeout, closure).await {
459-
deactivate(&profile_path).await?;
493+
deactivate(&profile_path, bin_path).await?;
460494
return Err(ActivateError::ActivationConfirmation(err));
461495
}
462496
}
@@ -465,8 +499,8 @@ pub async fn activate(
465499
Ok(())
466500
}
467501

468-
async fn revoke(profile_path: String) -> Result<(), DeactivateError> {
469-
deactivate(profile_path.as_str()).await?;
502+
async fn revoke(profile_path: String, bin_path: Option<PathBuf>) -> Result<(), DeactivateError> {
503+
deactivate(profile_path.as_str(), bin_path).await?;
470504
Ok(())
471505
}
472506

@@ -557,6 +591,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
557591
activate_opts.closure,
558592
activate_opts.auto_rollback,
559593
activate_opts.temp_path,
594+
activate_opts.bin_path,
560595
activate_opts.confirm_timeout,
561596
activate_opts.magic_rollback,
562597
activate_opts.dry_activate,
@@ -565,15 +600,22 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
565600
.await
566601
.map_err(|x| Box::new(x) as Box<dyn std::error::Error>),
567602

568-
SubCommand::Wait(wait_opts) => wait(wait_opts.temp_path, wait_opts.closure, wait_opts.activation_timeout)
569-
.await
570-
.map_err(|x| Box::new(x) as Box<dyn std::error::Error>),
603+
SubCommand::Wait(wait_opts) => wait(
604+
wait_opts.temp_path,
605+
wait_opts.closure,
606+
wait_opts.activation_timeout,
607+
)
608+
.await
609+
.map_err(|x| Box::new(x) as Box<dyn std::error::Error>),
571610

572-
SubCommand::Revoke(revoke_opts) => revoke(get_profile_path(
573-
revoke_opts.profile_path,
574-
revoke_opts.profile_user,
575-
revoke_opts.profile_name,
576-
)?)
611+
SubCommand::Revoke(revoke_opts) => revoke(
612+
get_profile_path(
613+
revoke_opts.profile_path,
614+
revoke_opts.profile_user,
615+
revoke_opts.profile_name,
616+
)?,
617+
revoke_opts.bin_path,
618+
)
577619
.await
578620
.map_err(|x| Box::new(x) as Box<dyn std::error::Error>),
579621
};

0 commit comments

Comments
 (0)