Refactor current profile detection
This commit is contained in:
parent
6401ce4c3c
commit
f92236da46
5 changed files with 54 additions and 37 deletions
|
@ -428,16 +428,18 @@ impl Deployment {
|
|||
|
||||
if !target.config.replace_unknown_profiles {
|
||||
job.message("Checking remote profile...".to_string())?;
|
||||
match host.active_derivation_known().await {
|
||||
Ok(_) => {
|
||||
job.message("Remote profile known".to_string())?;
|
||||
}
|
||||
Err(e) => {
|
||||
if arc_self.options.force_replace_unknown_profiles {
|
||||
job.message("warning: remote profile is unknown, but unknown profiles are being ignored".to_string())?;
|
||||
} else {
|
||||
return Err(e);
|
||||
}
|
||||
|
||||
let profile = host.get_main_system_profile().await?;
|
||||
|
||||
if profile.exists() {
|
||||
job.message("Remote profile known".to_string())?;
|
||||
} else {
|
||||
if arc_self.options.force_replace_unknown_profiles {
|
||||
job.message("Warning: Remote profile is unknown, but unknown profiles are being ignored".to_string())?;
|
||||
} else {
|
||||
return Err(NixError::ActiveProfileUnknown {
|
||||
store_path: profile,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ use async_trait::async_trait;
|
|||
use tokio::process::Command;
|
||||
|
||||
use super::{CopyDirection, CopyOptions, Host, key_uploader};
|
||||
use crate::nix::{StorePath, Profile, Goal, NixError, NixResult, NixCommand, Key, SYSTEM_PROFILE};
|
||||
use crate::nix::{StorePath, Profile, Goal, NixError, NixResult, NixCommand, Key, SYSTEM_PROFILE, CURRENT_PROFILE};
|
||||
use crate::util::CommandExecution;
|
||||
use crate::job::JobHandle;
|
||||
|
||||
|
@ -90,8 +90,19 @@ impl Host for Local {
|
|||
|
||||
result
|
||||
}
|
||||
async fn active_derivation_known(&mut self) -> NixResult<bool> {
|
||||
Ok(true)
|
||||
|
||||
async fn get_main_system_profile(&mut self) -> NixResult<StorePath> {
|
||||
let paths = Command::new("sh")
|
||||
.args(&["-c", &format!("readlink -e {} || readlink -e {}", SYSTEM_PROFILE, CURRENT_PROFILE)])
|
||||
.capture_output()
|
||||
.await?;
|
||||
|
||||
let path = paths.lines().into_iter().next()
|
||||
.ok_or(NixError::FailedToGetCurrentProfile)?
|
||||
.to_string()
|
||||
.try_into()?;
|
||||
|
||||
Ok(path)
|
||||
}
|
||||
|
||||
fn set_job(&mut self, job: Option<JobHandle>) {
|
||||
|
|
|
@ -110,8 +110,12 @@ pub trait Host: Send + Sync + std::fmt::Debug {
|
|||
Err(NixError::Unsupported)
|
||||
}
|
||||
|
||||
/// Check if the active profile is known to the host running Colmena
|
||||
async fn active_derivation_known(&mut self) -> NixResult<bool>;
|
||||
/// Returns the main system profile on the host.
|
||||
///
|
||||
/// This may _not_ be the system profile that's currently activated!
|
||||
/// It will first try `/nix/var/nix/profiles/system`, falling back
|
||||
/// to `/run/current-system` if it doesn't exist.
|
||||
async fn get_main_system_profile(&mut self) -> NixResult<StorePath>;
|
||||
|
||||
/// Activates a system profile on the host, if it runs NixOS.
|
||||
///
|
||||
|
|
|
@ -7,7 +7,7 @@ use async_trait::async_trait;
|
|||
use tokio::process::Command;
|
||||
|
||||
use super::{CopyDirection, CopyOptions, Host, key_uploader};
|
||||
use crate::nix::{StorePath, Profile, Goal, NixResult, NixCommand, NixError, Key, SYSTEM_PROFILE};
|
||||
use crate::nix::{StorePath, Profile, Goal, NixResult, NixCommand, NixError, Key, SYSTEM_PROFILE, CURRENT_PROFILE};
|
||||
use crate::util::CommandExecution;
|
||||
use crate::job::JobHandle;
|
||||
|
||||
|
@ -78,26 +78,19 @@ impl Host for Ssh {
|
|||
let command = self.ssh(command);
|
||||
self.run_command(command).await
|
||||
}
|
||||
async fn active_derivation_known(&mut self) -> NixResult<bool> {
|
||||
let paths = self.ssh(&["realpath", SYSTEM_PROFILE])
|
||||
.capture_output()
|
||||
.await;
|
||||
async fn get_main_system_profile(&mut self) -> NixResult<StorePath> {
|
||||
let command = format!("\"readlink -e {} || readlink -e {}\"", SYSTEM_PROFILE, CURRENT_PROFILE);
|
||||
|
||||
match paths {
|
||||
Ok(paths) => {
|
||||
if let Some(path) = paths.lines().into_iter().next() {
|
||||
let remote_profile: StorePath = path.to_string().try_into().unwrap();
|
||||
if remote_profile.exists() {
|
||||
return Ok(true);
|
||||
}
|
||||
return Err(NixError::ActiveProfileUnknown {
|
||||
store_path: path.to_string(),
|
||||
});
|
||||
}
|
||||
return Ok(false);
|
||||
}
|
||||
Err(e) => Err(e),
|
||||
}
|
||||
let paths = self.ssh(&["sh", "-c", &command])
|
||||
.capture_output()
|
||||
.await?;
|
||||
|
||||
let path = paths.lines().into_iter().next()
|
||||
.ok_or(NixError::FailedToGetCurrentProfile)?
|
||||
.to_string()
|
||||
.try_into()?;
|
||||
|
||||
Ok(path)
|
||||
}
|
||||
fn set_job(&mut self, job: Option<JobHandle>) {
|
||||
self.job = job;
|
||||
|
|
|
@ -44,8 +44,12 @@ pub use flake::Flake;
|
|||
pub mod node_filter;
|
||||
pub use node_filter::NodeFilter;
|
||||
|
||||
/// Path to the main system profile.
|
||||
pub const SYSTEM_PROFILE: &str = "/nix/var/nix/profiles/system";
|
||||
|
||||
/// Path to the system profile that's currently active.
|
||||
pub const CURRENT_PROFILE: &str = "/run/current-system";
|
||||
|
||||
pub type NixResult<T> = Result<T, NixError>;
|
||||
|
||||
#[non_exhaustive]
|
||||
|
@ -81,8 +85,11 @@ pub enum NixError {
|
|||
#[snafu(display("Invalid NixOS system profile"))]
|
||||
InvalidProfile,
|
||||
|
||||
#[snafu(display("Unknown active profile: {}", store_path))]
|
||||
ActiveProfileUnknown { store_path: String },
|
||||
#[snafu(display("Unknown active profile: {:?}", store_path))]
|
||||
ActiveProfileUnknown { store_path: StorePath },
|
||||
|
||||
#[snafu(display("Could not determine current profile"))]
|
||||
FailedToGetCurrentProfile,
|
||||
|
||||
#[snafu(display("Current Nix version does not support Flakes"))]
|
||||
NoFlakesSupport,
|
||||
|
|
Loading…
Reference in a new issue