@@ -90,6 +90,10 @@ struct ActivateOpts {
90
90
/// Path for any temporary files that may be needed during activation
91
91
#[ arg( long) ]
92
92
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 > ,
93
97
}
94
98
95
99
/// Wait for profile activation
@@ -119,6 +123,10 @@ struct RevokeOpts {
119
123
/// The profile name
120
124
#[ arg( long, requires = "profile_user" ) ]
121
125
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 > ,
122
130
}
123
131
124
132
#[ derive( Error , Debug ) ]
@@ -143,10 +151,26 @@ pub enum DeactivateError {
143
151
ReactivateExit ( Option < i32 > ) ,
144
152
}
145
153
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 > {
147
171
warn ! ( "De-activating due to error" ) ;
148
172
149
- let nix_env_rollback_exit_status = Command :: new ( "nix-env" )
173
+ let nix_env_rollback_exit_status = create_command ( "nix-env" , & bin_path )
150
174
. arg ( "-p" )
151
175
. arg ( & profile_path)
152
176
. arg ( "--rollback" )
@@ -161,7 +185,7 @@ pub async fn deactivate(profile_path: &str) -> Result<(), DeactivateError> {
161
185
162
186
debug ! ( "Listing generations" ) ;
163
187
164
- let nix_env_list_generations_out = Command :: new ( "nix-env" )
188
+ let nix_env_list_generations_out = create_command ( "nix-env" , & bin_path )
165
189
. arg ( "-p" )
166
190
. arg ( & profile_path)
167
191
. arg ( "--list-generations" )
@@ -190,7 +214,7 @@ pub async fn deactivate(profile_path: &str) -> Result<(), DeactivateError> {
190
214
debug ! ( "Removing generation entry {}" , last_generation_line) ;
191
215
warn ! ( "Removing generation by ID {}" , last_generation_id) ;
192
216
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 )
194
218
. arg ( "-p" )
195
219
. arg ( & profile_path)
196
220
. arg ( "--delete-generations" )
@@ -206,12 +230,13 @@ pub async fn deactivate(profile_path: &str) -> Result<(), DeactivateError> {
206
230
207
231
info ! ( "Attempting to re-activate the last generation" ) ;
208
232
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 ) ?;
215
240
216
241
match re_activate_exit_status. code ( ) {
217
242
Some ( 0 ) => ( ) ,
@@ -315,7 +340,11 @@ pub enum WaitError {
315
340
#[ error( "Error waiting for activation: {0}" ) ]
316
341
Waiting ( #[ from] DangerZoneError ) ,
317
342
}
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 > {
319
348
let lock_path = deploy:: make_lock_path ( & temp_path, & closure) ;
320
349
321
350
let ( created, done) = mpsc:: channel ( 1 ) ;
@@ -386,14 +415,16 @@ pub async fn activate(
386
415
closure : String ,
387
416
auto_rollback : bool ,
388
417
temp_path : PathBuf ,
418
+ bin_path : Option < PathBuf > ,
389
419
confirm_timeout : u16 ,
390
420
magic_rollback : bool ,
391
421
dry_activate : bool ,
392
422
boot : bool ,
393
423
) -> Result < ( ) , ActivateError > {
394
424
if !dry_activate {
395
425
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)
397
428
. arg ( "-p" )
398
429
. arg ( & profile_path)
399
430
. arg ( "--set" )
@@ -405,7 +436,7 @@ pub async fn activate(
405
436
Some ( 0 ) => ( ) ,
406
437
a => {
407
438
if auto_rollback && !dry_activate {
408
- deactivate ( & profile_path) . await ?;
439
+ deactivate ( & profile_path, bin_path ) . await ?;
409
440
}
410
441
return Err ( ActivateError :: SetProfileExit ( a) ) ;
411
442
}
@@ -420,19 +451,22 @@ pub async fn activate(
420
451
& profile_path
421
452
} ;
422
453
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 )
431
465
{
432
466
Ok ( x) => x,
433
467
Err ( e) => {
434
468
if auto_rollback && !dry_activate {
435
- deactivate ( & profile_path) . await ?;
469
+ deactivate ( & profile_path, bin_path ) . await ?;
436
470
}
437
471
return Err ( e) ;
438
472
}
@@ -443,7 +477,7 @@ pub async fn activate(
443
477
Some ( 0 ) => ( ) ,
444
478
a => {
445
479
if auto_rollback {
446
- deactivate ( & profile_path) . await ?;
480
+ deactivate ( & profile_path, bin_path ) . await ?;
447
481
}
448
482
return Err ( ActivateError :: RunActivateExit ( a) ) ;
449
483
}
@@ -456,7 +490,7 @@ pub async fn activate(
456
490
if magic_rollback && !boot {
457
491
info ! ( "Magic rollback is enabled, setting up confirmation hook..." ) ;
458
492
if let Err ( err) = activation_confirmation ( temp_path, confirm_timeout, closure) . await {
459
- deactivate ( & profile_path) . await ?;
493
+ deactivate ( & profile_path, bin_path ) . await ?;
460
494
return Err ( ActivateError :: ActivationConfirmation ( err) ) ;
461
495
}
462
496
}
@@ -465,8 +499,8 @@ pub async fn activate(
465
499
Ok ( ( ) )
466
500
}
467
501
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 ?;
470
504
Ok ( ( ) )
471
505
}
472
506
@@ -557,6 +591,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
557
591
activate_opts. closure ,
558
592
activate_opts. auto_rollback ,
559
593
activate_opts. temp_path ,
594
+ activate_opts. bin_path ,
560
595
activate_opts. confirm_timeout ,
561
596
activate_opts. magic_rollback ,
562
597
activate_opts. dry_activate ,
@@ -565,15 +600,22 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
565
600
. await
566
601
. map_err ( |x| Box :: new ( x) as Box < dyn std:: error:: Error > ) ,
567
602
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 > ) ,
571
610
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
+ )
577
619
. await
578
620
. map_err ( |x| Box :: new ( x) as Box < dyn std:: error:: Error > ) ,
579
621
} ;
0 commit comments