host: Add get_current_system_profile

This commit is contained in:
Zhaofeng Li 2022-05-22 02:15:33 -07:00
parent c8b79e7e2d
commit e239cbd260
7 changed files with 43 additions and 13 deletions

View file

@ -6,7 +6,7 @@ use std::process::ExitStatus;
use snafu::Snafu;
use validator::ValidationErrors;
use crate::nix::{key, StorePath};
use crate::nix::{key, StorePath, Profile};
pub type ColmenaResult<T> = Result<T, ColmenaError>;
@ -43,8 +43,8 @@ pub enum ColmenaError {
#[snafu(display("Invalid NixOS system profile"))]
InvalidProfile,
#[snafu(display("Unknown active profile: {:?}", store_path))]
ActiveProfileUnknown { store_path: StorePath },
#[snafu(display("Unknown active profile: {:?}", profile))]
ActiveProfileUnknown { profile: Profile },
#[snafu(display("Could not determine current profile"))]
FailedToGetCurrentProfile,

View file

@ -538,13 +538,13 @@ impl Deployment {
let profile = host.get_main_system_profile().await?;
if profile.exists() {
if profile.as_store_path().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(ColmenaError::ActiveProfileUnknown {
store_path: profile,
profile,
});
}
}

View file

@ -92,7 +92,21 @@ impl Host for Local {
result
}
async fn get_main_system_profile(&mut self) -> ColmenaResult<StorePath> {
async fn get_current_system_profile(&mut self) -> ColmenaResult<Profile> {
let paths = Command::new("readlink")
.args(&["-e", CURRENT_PROFILE])
.capture_output()
.await?;
let path = paths.lines().into_iter().next()
.ok_or(ColmenaError::FailedToGetCurrentProfile)?
.to_string()
.try_into()?;
Ok(Profile::from_store_path_unchecked(path))
}
async fn get_main_system_profile(&mut self) -> ColmenaResult<Profile> {
let paths = Command::new("sh")
.args(&["-c", &format!("readlink -e {} || readlink -e {}", SYSTEM_PROFILE, CURRENT_PROFILE)])
.capture_output()
@ -103,7 +117,7 @@ impl Host for Local {
.to_string()
.try_into()?;
Ok(path)
Ok(Profile::from_store_path_unchecked(path))
}
fn set_job(&mut self, job: Option<JobHandle>) {

View file

@ -111,12 +111,15 @@ pub trait Host: Send + Sync + std::fmt::Debug {
Err(ColmenaError::Unsupported)
}
/// Returns the current system profile on the host.
async fn get_current_system_profile(&mut self) -> ColmenaResult<Profile>;
/// 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) -> ColmenaResult<StorePath>;
async fn get_main_system_profile(&mut self) -> ColmenaResult<Profile>;
/// Activates a system profile on the host, if it runs NixOS.
///

View file

@ -82,7 +82,20 @@ impl Host for Ssh {
self.run_command(command).await
}
async fn get_main_system_profile(&mut self) -> ColmenaResult<StorePath> {
async fn get_current_system_profile(&mut self) -> ColmenaResult<Profile> {
let paths = self.ssh(&["readlink", "-e", CURRENT_PROFILE])
.capture_output()
.await?;
let path = paths.lines().into_iter().next()
.ok_or(ColmenaError::FailedToGetCurrentProfile)?
.to_string()
.try_into()?;
Ok(Profile::from_store_path_unchecked(path))
}
async fn get_main_system_profile(&mut self) -> ColmenaResult<Profile> {
let command = format!("\"readlink -e {} || readlink -e {}\"", SYSTEM_PROFILE, CURRENT_PROFILE);
let paths = self.ssh(&["sh", "-c", &command])
@ -94,7 +107,7 @@ impl Host for Ssh {
.to_string()
.try_into()?;
Ok(path)
Ok(Profile::from_store_path_unchecked(path))
}
async fn run_command(&mut self, command: &[&str]) -> ColmenaResult<()> {

View file

@ -16,7 +16,7 @@ use super::{
pub type ProfileDerivation = StoreDerivation<Profile>;
/// A NixOS system profile.
#[derive(Clone, Debug)]
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Profile(StorePath);
impl Profile {
@ -77,7 +77,7 @@ impl Profile {
Ok(())
}
fn from_store_path_unchecked(path: StorePath) -> Self {
pub(super) fn from_store_path_unchecked(path: StorePath) -> Self {
Self(path)
}
}

View file

@ -12,7 +12,7 @@ use crate::util::CommandExt;
use super::Host;
/// A Nix store path.
#[derive(Debug, Clone, Serialize, Deserialize)]
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct StorePath(PathBuf);
/// A store derivation (.drv) that will result in a T when built.