Skip to content

Commit c12d114

Browse files
committed
treewide: fix nvd diffing; omit warnings on non-VM builds
1 parent 45048d3 commit c12d114

File tree

5 files changed

+103
-24
lines changed

5 files changed

+103
-24
lines changed

src/commands.rs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ pub struct Command {
2929
args: Vec<OsString>,
3030
elevate: bool,
3131
ssh: Option<String>,
32+
show_output: bool,
3233
}
3334

3435
impl Command {
@@ -40,6 +41,7 @@ impl Command {
4041
args: vec![],
4142
elevate: false,
4243
ssh: None,
44+
show_output: false,
4345
}
4446
}
4547

@@ -53,6 +55,11 @@ impl Command {
5355
self
5456
}
5557

58+
pub const fn show_output(mut self, show_output: bool) -> Self {
59+
self.show_output = show_output;
60+
self
61+
}
62+
5663
pub fn ssh(mut self, ssh: Option<String>) -> Self {
5764
self.ssh = ssh;
5865
self
@@ -113,8 +120,15 @@ impl Command {
113120
} else {
114121
Exec::cmd(&self.command).args(&self.args)
115122
};
116-
let cmd =
117-
ssh_wrap(cmd.stderr(Redirection::None), self.ssh.as_deref()).stdout(Redirection::None);
123+
// Configure output redirection based on show_output setting
124+
let cmd = ssh_wrap(
125+
if self.show_output {
126+
cmd.stderr(Redirection::Merge)
127+
} else {
128+
cmd.stderr(Redirection::None).stdout(Redirection::None)
129+
},
130+
self.ssh.as_deref(),
131+
);
118132

119133
if let Some(m) = &self.message {
120134
info!("{}", m);

src/darwin.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,13 +103,24 @@ impl DarwinRebuildArgs {
103103

104104
let target_profile = out_path.get_path().to_owned();
105105

106+
// Take a strong reference to out_path to prevent premature dropping
107+
// We need to keep this alive through the entire function scope to prevent
108+
// the tempdir from being dropped early, which would cause nvd diff to fail
109+
#[allow(unused_variables)]
110+
let keep_alive = out_path.get_path().to_owned();
111+
debug!(
112+
"Registered keep_alive reference to: {}",
113+
keep_alive.display()
114+
);
115+
106116
target_profile.try_exists().context("Doesn't exist")?;
107117

108118
Command::new("nvd")
109119
.arg("diff")
110120
.arg(CURRENT_PROFILE)
111121
.arg(&target_profile)
112122
.message("Comparing changes")
123+
.show_output(true)
113124
.run()?;
114125

115126
if self.common.ask && !self.common.dry && !matches!(variant, Build) {
@@ -151,6 +162,10 @@ impl DarwinRebuildArgs {
151162

152163
// Make sure out_path is not accidentally dropped
153164
// https://docs.rs/tempfile/3.12.0/tempfile/index.html#early-drop-pitfall
165+
debug!(
166+
"Completed operation with output path: {:?}",
167+
out_path.get_path()
168+
);
154169
drop(out_path);
155170

156171
Ok(())

src/generations.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ pub fn from_dir(generation_dir: &Path) -> Option<u64> {
4343
})
4444
}
4545

46-
pub fn describe(generation_dir: &Path, current_profile: &Path) -> Option<GenerationInfo> {
46+
pub fn describe(generation_dir: &Path, _current_profile: &Path) -> Option<GenerationInfo> {
4747
let generation_number = from_dir(generation_dir)?;
4848

4949
// Get metadata once and reuse for both date and existence checks

src/home.rs

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -112,10 +112,17 @@ impl HomeRebuildArgs {
112112

113113
debug!("target_specialisation: {target_specialisation:?}");
114114

115-
let target_profile: Box<dyn crate::util::MaybeTempPath> = match &target_specialisation {
116-
None => out_path,
117-
Some(spec) => Box::new(out_path.get_path().join("specialisation").join(spec)),
118-
};
115+
let target_profile: Box<dyn crate::util::MaybeTempPath> =
116+
if let Some(spec) = &target_specialisation {
117+
Box::new(out_path.get_path().join("specialisation").join(spec))
118+
} else {
119+
out_path
120+
};
121+
122+
// Take a strong reference to ensure the TempDir isn't dropped
123+
// This prevents early dropping of the tempdir, which causes nvd diff to fail
124+
#[allow(unused_variables)]
125+
let keep_alive = target_profile.get_path().to_owned();
119126

120127
// just do nothing for None case (fresh installs)
121128
if let Some(generation) = prev_generation {
@@ -124,6 +131,7 @@ impl HomeRebuildArgs {
124131
.arg(generation)
125132
.arg(target_profile.get_path())
126133
.message("Comparing changes")
134+
.show_output(true)
127135
.run()?;
128136
}
129137

@@ -154,6 +162,10 @@ impl HomeRebuildArgs {
154162

155163
// Make sure out_path is not accidentally dropped
156164
// https://docs.rs/tempfile/3.12.0/tempfile/index.html#early-drop-pitfall
165+
debug!(
166+
"Completed operation with output path: {:?}",
167+
target_profile.get_path()
168+
);
157169
drop(target_profile);
158170

159171
Ok(())

src/nixos.rs

Lines changed: 55 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ enum OsRebuildVariant {
5656
impl OsBuildVmArgs {
5757
fn build_vm(self) -> Result<()> {
5858
let final_attr = get_final_attr(true, self.with_bootloader);
59+
debug!("Building VM with attribute: {}", final_attr);
5960
self.common
6061
.rebuild(OsRebuildVariant::BuildVm, Some(final_attr))
6162
}
@@ -97,7 +98,16 @@ impl OsRebuildArgs {
9798
Some(h) => h.to_owned(),
9899
None => match &system_hostname {
99100
Some(hostname) => {
100-
tracing::warn!("Guessing system is {hostname} for a VM image. If this isn't intended, use --hostname to change.");
101+
// Only show the warning if we're explicitly building a VM
102+
// by directly calling build_vm(), not when the BuildVm variant
103+
// is used internally via other code paths
104+
if matches!(variant, OsRebuildVariant::BuildVm)
105+
&& final_attr
106+
.as_deref()
107+
.map_or(false, |attr| attr == "vm" || attr == "vmWithBootLoader")
108+
{
109+
tracing::warn!("Guessing system is {hostname} for a VM image. If this isn't intended, use --hostname to change.");
110+
}
101111
hostname.clone()
102112
}
103113
None => return Err(eyre!("Unable to fetch hostname, and no hostname supplied.")),
@@ -143,7 +153,6 @@ impl OsRebuildArgs {
143153
BuildVm => "Building NixOS VM image",
144154
_ => "Building NixOS configuration",
145155
};
146-
147156
commands::Build::new(toplevel)
148157
.extra_arg("--out-link")
149158
.extra_arg(out_path.get_path())
@@ -168,20 +177,49 @@ impl OsRebuildArgs {
168177
Some(spec) => out_path.get_path().join("specialisation").join(spec),
169178
};
170179

171-
debug!("exists: {}", target_profile.exists());
180+
debug!("Output path: {}", out_path.get_path().display());
181+
debug!("Target profile path: {}", target_profile.display());
182+
debug!("Target profile exists: {}", target_profile.exists());
183+
184+
// Take a strong reference to out_path to prevent premature dropping
185+
// This prevents the tempdir from being dropped early, which would cause nvd diff to fail
186+
#[allow(unused_variables)]
187+
let keep_alive = out_path.get_path().to_owned();
172188

173-
target_profile.try_exists().context("Doesn't exist")?;
189+
if !target_profile
190+
.try_exists()
191+
.context("Failed to check if target profile exists")?
192+
{
193+
return Err(eyre!(
194+
"Target profile path does not exist: {}",
195+
target_profile.display()
196+
));
197+
}
174198

175199
if self.build_host.is_none()
176200
&& self.target_host.is_none()
177201
&& system_hostname.map_or(true, |h| h == target_hostname)
178202
{
179-
Command::new("nvd")
180-
.arg("diff")
181-
.arg(CURRENT_PROFILE)
182-
.arg(&target_profile)
183-
.message("Comparing changes")
184-
.run()?;
203+
// Verify the target_profile path exists before attempting to use it
204+
if matches!(target_profile.try_exists(), Ok(true)) {
205+
debug!(
206+
"Comparing with target profile: {}",
207+
target_profile.display()
208+
);
209+
210+
Command::new("nvd")
211+
.arg("diff")
212+
.arg(CURRENT_PROFILE)
213+
.arg(&target_profile)
214+
.message("Comparing changes")
215+
.show_output(true)
216+
.run()?;
217+
} else {
218+
warn!(
219+
"Cannot compare changes - target profile path does not exist: {}",
220+
target_profile.display()
221+
);
222+
}
185223
} else {
186224
debug!("Not running nvd as the target hostname is different from the system hostname.");
187225
}
@@ -253,8 +291,12 @@ impl OsRebuildArgs {
253291
.run()?;
254292
}
255293

256-
// Make sure out_path is not accidentally dropped
294+
// Make sure out_path is not acidentally dropped
257295
// https://docs.rs/tempfile/3.12.0/tempfile/index.html#early-drop-pitfall
296+
debug!(
297+
"Completed operation with output path: {:?}",
298+
out_path.get_path()
299+
);
258300
drop(out_path);
259301

260302
Ok(())
@@ -305,6 +347,7 @@ impl OsRollbackArgs {
305347
.arg(CURRENT_PROFILE)
306348
.arg(&generation_link)
307349
.message("Comparing changes")
350+
.show_output(true)
308351
.run()?;
309352

310353
if self.dry {
@@ -345,9 +388,6 @@ impl OsRollbackArgs {
345388
.message("Setting system profile")
346389
.run()?;
347390

348-
// Set up rollback protection flag
349-
let mut rollback_profile = false;
350-
351391
// Determine the correct profile to use with specialisations
352392
let final_profile = match &target_specialisation {
353393
None => generation_link,
@@ -383,10 +423,8 @@ impl OsRollbackArgs {
383423
);
384424
}
385425
Err(e) => {
386-
rollback_profile = true;
387-
388426
// If activation fails, rollback the profile
389-
if rollback_profile && current_gen_number > 0 {
427+
if current_gen_number > 0 {
390428
let current_gen_link =
391429
profile_dir.join(format!("system-{current_gen_number}-link"));
392430

0 commit comments

Comments
 (0)