Skip to content

Commit e44479a

Browse files
committed
various: bail when --profile resolves to invalid path
Signed-off-by: NotAShelf <[email protected]> Change-Id: I6a6a69640fea6789de7fd14d88a130fa0c488933
1 parent a4bdb0f commit e44479a

File tree

3 files changed

+70
-37
lines changed

3 files changed

+70
-37
lines changed

src/darwin.rs

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,15 @@ impl DarwinRebuildArgs {
5757
) -> Result<()> {
5858
use DarwinRebuildVariant::{Build, Switch};
5959

60+
if let Some(profile) = self.profile.as_ref() {
61+
if !std::path::Path::new(profile).exists() {
62+
bail!(
63+
"--profile path provided but does not exist: {}",
64+
profile.display()
65+
);
66+
}
67+
}
68+
6069
if nix::unistd::Uid::effective().is_root() && !self.bypass_root_check {
6170
bail!("Don't run nh os as root. I will call sudo internally as needed");
6271
}
@@ -155,10 +164,11 @@ impl DarwinRebuildArgs {
155164
}
156165

157166
if matches!(variant, Switch) {
158-
let profile_path = self.profile.as_ref().map_or_else(
159-
|| std::ffi::OsStr::new(SYSTEM_PROFILE),
160-
|p| p.as_os_str(),
161-
);
167+
let profile_path = if let Some(profile) = self.profile.as_ref() {
168+
profile.as_os_str()
169+
} else {
170+
std::ffi::OsStr::new(SYSTEM_PROFILE)
171+
};
162172
Command::new("nix")
163173
.args(["build", "--no-link", "--profile"])
164174
.arg(profile_path)

src/home.rs

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
use std::{env, ffi::OsString, path::PathBuf};
22

3+
const USER_PROFILE_PATH: &str = "/nix/var/nix/profiles/per-user";
4+
const HOME_PROFILE_PATH: &str = ".local/state/nix/profiles/home-manager";
5+
36
use color_eyre::{
47
Result,
58
eyre::{Context, bail, eyre},
@@ -99,27 +102,33 @@ impl HomeRebuildArgs {
99102
.run()
100103
.wrap_err("Failed to build Home-Manager configuration")?;
101104

102-
let prev_generation: Option<PathBuf> = if let Some(ref profile) =
103-
self.profile
104-
{
105-
if profile.exists() {
106-
Some(profile.clone())
107-
} else {
108-
None
105+
if let Some(ref profile) = self.profile {
106+
if !profile.exists() {
107+
bail!(
108+
"--profile path provided but does not exist: {}",
109+
profile.display()
110+
);
109111
}
110-
} else {
111-
[
112-
PathBuf::from("/nix/var/nix/profiles/per-user")
112+
}
113+
let prev_generation: Option<PathBuf> =
114+
if let Some(ref profile) = self.profile {
115+
if profile.exists() {
116+
Some(profile.clone())
117+
} else {
118+
None
119+
}
120+
} else {
121+
let user_profile = PathBuf::from(USER_PROFILE_PATH)
113122
.join(env::var("USER").map_err(|_| eyre!("Couldn't get username"))?)
114-
.join("home-manager"),
115-
PathBuf::from(
123+
.join("home-manager");
124+
let home_profile = PathBuf::from(
116125
env::var("HOME").map_err(|_| eyre!("Couldn't get home directory"))?,
117126
)
118-
.join(".local/state/nix/profiles/home-manager"),
119-
]
120-
.into_iter()
121-
.find(|next| next.exists())
122-
};
127+
.join(HOME_PROFILE_PATH);
128+
[user_profile, home_profile]
129+
.into_iter()
130+
.find(|next| next.exists())
131+
};
123132

124133
debug!("Previous generation: {prev_generation:?}");
125134

src/nixos.rs

Lines changed: 30 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,15 @@ impl OsRebuildArgs {
8282
) -> Result<()> {
8383
use OsRebuildVariant::{Boot, Build, BuildVm, Switch, Test};
8484

85+
if let Some(profile) = self.profile.as_ref() {
86+
if !std::path::Path::new(profile).exists() {
87+
bail!(
88+
"--profile path provided but does not exist: {}",
89+
profile.display()
90+
);
91+
}
92+
}
93+
8594
if self.build_host.is_some() || self.target_host.is_some() {
8695
// if it fails its okay
8796
let _ = ensure_ssh_key_login();
@@ -330,10 +339,11 @@ impl OsRebuildArgs {
330339
.canonicalize()
331340
.context("Failed to resolve output path")?;
332341

333-
let system_profile_path = self.profile.as_ref().map_or_else(
334-
|| std::ffi::OsStr::new(SYSTEM_PROFILE),
335-
|p| p.as_os_str(),
336-
);
342+
let system_profile_path = if let Some(profile) = self.profile.as_ref() {
343+
profile.as_os_str()
344+
} else {
345+
std::ffi::OsStr::new(SYSTEM_PROFILE)
346+
};
337347
Command::new("nix")
338348
.elevate(elevate.then_some(elevation.clone()))
339349
.args(["build", "--no-link", "--profile"])
@@ -406,10 +416,11 @@ impl OsRollbackArgs {
406416
info!("Rolling back to generation {}", target_generation.number);
407417

408418
// Construct path to the generation
409-
let system_profile_path = self
410-
.profile
411-
.as_deref()
412-
.unwrap_or_else(|| Path::new(SYSTEM_PROFILE));
419+
let system_profile_path = if let Some(profile) = self.profile.as_ref() {
420+
profile.as_path()
421+
} else {
422+
Path::new(SYSTEM_PROFILE)
423+
};
413424
let profile_dir = system_profile_path.parent().unwrap_or_else(|| {
414425
tracing::warn!(
415426
"SYSTEM_PROFILE has no parent, defaulting to /nix/var/nix/profiles"
@@ -478,10 +489,11 @@ impl OsRollbackArgs {
478489
info!("Setting system profile...");
479490

480491
// Instead of direct symlink operations, use a command with proper elevation
481-
let system_profile_path = self
482-
.profile
483-
.as_deref()
484-
.unwrap_or_else(|| Path::new(SYSTEM_PROFILE));
492+
let system_profile_path = if let Some(profile) = self.profile.as_ref() {
493+
profile.as_path()
494+
} else {
495+
Path::new(SYSTEM_PROFILE)
496+
};
485497
Command::new("ln")
486498
.arg("-sfn") // force, symbolic link
487499
.arg(&generation_link)
@@ -547,10 +559,12 @@ impl OsRollbackArgs {
547559
let current_gen_link =
548560
profile_dir.join(format!("system-{current_gen_number}-link"));
549561

550-
let system_profile_path = self
551-
.profile
552-
.as_deref()
553-
.unwrap_or_else(|| Path::new(SYSTEM_PROFILE));
562+
let system_profile_path = if let Some(profile) = self.profile.as_ref()
563+
{
564+
profile.as_path()
565+
} else {
566+
Path::new(SYSTEM_PROFILE)
567+
};
554568
Command::new("ln")
555569
.arg("-sfn") // Force, symbolic link
556570
.arg(&current_gen_link)

0 commit comments

Comments
 (0)