forked from lix-project/lix-installer
Compare commits
2 commits
main
...
hoverbear/
Author | SHA1 | Date | |
---|---|---|---|
a8f56d609f | |||
160347e788 |
97
src/action/macos/mac_remote_builder_fix.rs
Normal file
97
src/action/macos/mac_remote_builder_fix.rs
Normal file
|
@ -0,0 +1,97 @@
|
||||||
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
|
use tracing::{span, Span};
|
||||||
|
|
||||||
|
use crate::action::{
|
||||||
|
Action, ActionDescription, ActionError, ActionErrorKind, ActionTag, StatefulAction,
|
||||||
|
};
|
||||||
|
|
||||||
|
const NIX_STORE_SYMLINK_LOCATION: &str = "/usr/local/bin/nix-store";
|
||||||
|
const NIX_STORE_SYMLINK_TARGET: &str = "/nix/var/nix/profiles/default/bin/nix-store";
|
||||||
|
|
||||||
|
/**
|
||||||
|
Perform a remote builder fix for Mac which links `nix-store` into `/usr/local/bin`
|
||||||
|
*/
|
||||||
|
// Previously, the installer suggested users use a workaround: https://github.com/DeterminateSystems/nix-installer/blob/4bfd6c2547dab100cde1dbc60e3d623499ead2c4/README.md?plain=1#L377-L418
|
||||||
|
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
|
||||||
|
pub struct MacRemoteBuilderFix;
|
||||||
|
|
||||||
|
impl MacRemoteBuilderFix {
|
||||||
|
#[tracing::instrument(level = "debug", skip_all)]
|
||||||
|
pub async fn plan() -> Result<StatefulAction<Self>, ActionError> {
|
||||||
|
let nix_path = Path::new(NIX_STORE_SYMLINK_LOCATION);
|
||||||
|
if nix_path.exists() {
|
||||||
|
if !nix_path.is_symlink() {
|
||||||
|
return Err(Self::error(ActionErrorKind::PathWasNotSymlink(
|
||||||
|
nix_path.into(),
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
let link_destination = std::fs::read_link(nix_path)
|
||||||
|
.map_err(|e| ActionErrorKind::ReadSymlink(nix_path.into(), e))
|
||||||
|
.map_err(Self::error)?;
|
||||||
|
if link_destination == Path::new("/nix/var/nix/profiles/default/bin/nix-store") {
|
||||||
|
return Ok(StatefulAction::completed(Self));
|
||||||
|
} else {
|
||||||
|
return Err(Self::error(ActionErrorKind::SymlinkExists(nix_path.into())));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(StatefulAction::uncompleted(Self))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[async_trait::async_trait]
|
||||||
|
#[typetag::serde(name = "mac_remote_builder_fix")]
|
||||||
|
impl Action for MacRemoteBuilderFix {
|
||||||
|
fn action_tag() -> ActionTag {
|
||||||
|
ActionTag("mac_remote_builder_fix")
|
||||||
|
}
|
||||||
|
fn tracing_synopsis(&self) -> String {
|
||||||
|
format!(
|
||||||
|
"Create symlink at `{NIX_STORE_SYMLINK_LOCATION}` to `{NIX_STORE_SYMLINK_TARGET}`",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn tracing_span(&self) -> Span {
|
||||||
|
span!(tracing::Level::DEBUG, "mac_remote_builder_fix",)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn execute_description(&self) -> Vec<ActionDescription> {
|
||||||
|
vec![ActionDescription::new(self.tracing_synopsis(), vec![
|
||||||
|
"In order to support acting as a remote builder (Mac populates the `PATH` environment differently than other environments)".to_string()
|
||||||
|
])]
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tracing::instrument(level = "debug", skip_all)]
|
||||||
|
async fn execute(&mut self) -> Result<(), ActionError> {
|
||||||
|
tokio::fs::symlink(NIX_STORE_SYMLINK_TARGET, NIX_STORE_SYMLINK_LOCATION)
|
||||||
|
.await
|
||||||
|
.map_err(|e| {
|
||||||
|
ActionErrorKind::Symlink(
|
||||||
|
PathBuf::from(NIX_STORE_SYMLINK_LOCATION),
|
||||||
|
PathBuf::from(NIX_STORE_SYMLINK_TARGET),
|
||||||
|
e,
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.map_err(Self::error)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn revert_description(&self) -> Vec<ActionDescription> {
|
||||||
|
vec![ActionDescription::new(
|
||||||
|
format!("Remove symlink at `{NIX_STORE_SYMLINK_LOCATION}`",),
|
||||||
|
vec![],
|
||||||
|
)]
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tracing::instrument(level = "debug", skip_all)]
|
||||||
|
async fn revert(&mut self) -> Result<(), ActionError> {
|
||||||
|
tokio::fs::remove_file(NIX_STORE_SYMLINK_LOCATION)
|
||||||
|
.await
|
||||||
|
.map_err(|e| ActionErrorKind::Remove(PathBuf::from(NIX_STORE_SYMLINK_LOCATION), e))
|
||||||
|
.map_err(Self::error)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
|
@ -10,6 +10,7 @@ pub(crate) mod create_volume_service;
|
||||||
pub(crate) mod enable_ownership;
|
pub(crate) mod enable_ownership;
|
||||||
pub(crate) mod encrypt_apfs_volume;
|
pub(crate) mod encrypt_apfs_volume;
|
||||||
pub(crate) mod kickstart_launchctl_service;
|
pub(crate) mod kickstart_launchctl_service;
|
||||||
|
pub(crate) mod mac_remote_builder_fix;
|
||||||
pub(crate) mod set_tmutil_exclusion;
|
pub(crate) mod set_tmutil_exclusion;
|
||||||
pub(crate) mod set_tmutil_exclusions;
|
pub(crate) mod set_tmutil_exclusions;
|
||||||
pub(crate) mod unmount_apfs_volume;
|
pub(crate) mod unmount_apfs_volume;
|
||||||
|
@ -22,6 +23,7 @@ pub use create_volume_service::CreateVolumeService;
|
||||||
pub use enable_ownership::{EnableOwnership, EnableOwnershipError};
|
pub use enable_ownership::{EnableOwnership, EnableOwnershipError};
|
||||||
pub use encrypt_apfs_volume::EncryptApfsVolume;
|
pub use encrypt_apfs_volume::EncryptApfsVolume;
|
||||||
pub use kickstart_launchctl_service::KickstartLaunchctlService;
|
pub use kickstart_launchctl_service::KickstartLaunchctlService;
|
||||||
|
pub use mac_remote_builder_fix::MacRemoteBuilderFix;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
pub use set_tmutil_exclusion::SetTmutilExclusion;
|
pub use set_tmutil_exclusion::SetTmutilExclusion;
|
||||||
pub use set_tmutil_exclusions::SetTmutilExclusions;
|
pub use set_tmutil_exclusions::SetTmutilExclusions;
|
||||||
|
|
|
@ -409,6 +409,8 @@ pub enum ActionErrorKind {
|
||||||
PathModeMismatch(std::path::PathBuf, u32, u32),
|
PathModeMismatch(std::path::PathBuf, u32, u32),
|
||||||
#[error("Path `{0}` exists, but is not a file, consider removing it with `rm {0}`")]
|
#[error("Path `{0}` exists, but is not a file, consider removing it with `rm {0}`")]
|
||||||
PathWasNotFile(std::path::PathBuf),
|
PathWasNotFile(std::path::PathBuf),
|
||||||
|
#[error("Path `{0}` exists, but is not a symlink, consider removing it with `rm {0}`")]
|
||||||
|
PathWasNotSymlink(std::path::PathBuf),
|
||||||
#[error("Path `{0}` exists, but is not a directory, consider removing it with `rm {0}`")]
|
#[error("Path `{0}` exists, but is not a directory, consider removing it with `rm {0}`")]
|
||||||
PathWasNotDirectory(std::path::PathBuf),
|
PathWasNotDirectory(std::path::PathBuf),
|
||||||
#[error("Getting metadata for {0}`")]
|
#[error("Getting metadata for {0}`")]
|
||||||
|
|
|
@ -10,7 +10,7 @@ use crate::{
|
||||||
action::{
|
action::{
|
||||||
base::RemoveDirectory,
|
base::RemoveDirectory,
|
||||||
common::{ConfigureInitService, ConfigureNix, CreateUsersAndGroups, ProvisionNix},
|
common::{ConfigureInitService, ConfigureNix, CreateUsersAndGroups, ProvisionNix},
|
||||||
macos::{CreateNixVolume, SetTmutilExclusions},
|
macos::{CreateNixVolume, SetTmutilExclusions,MacRemoteBuilderFix},
|
||||||
StatefulAction,
|
StatefulAction,
|
||||||
},
|
},
|
||||||
execute_command,
|
execute_command,
|
||||||
|
@ -161,6 +161,10 @@ impl Planner for Macos {
|
||||||
.await
|
.await
|
||||||
.map_err(PlannerError::Action)?
|
.map_err(PlannerError::Action)?
|
||||||
.boxed(),
|
.boxed(),
|
||||||
|
MacRemoteBuilderFix::plan()
|
||||||
|
.await
|
||||||
|
.map_err(PlannerError::Action)?
|
||||||
|
.boxed(),
|
||||||
RemoveDirectory::plan(crate::settings::SCRATCH_DIR)
|
RemoveDirectory::plan(crate::settings::SCRATCH_DIR)
|
||||||
.await
|
.await
|
||||||
.map_err(PlannerError::Action)?
|
.map_err(PlannerError::Action)?
|
||||||
|
|
Loading…
Reference in a new issue