forked from lix-project/lix-installer
fmt
This commit is contained in:
parent
878a071183
commit
72a4356a8b
22 changed files with 159 additions and 94 deletions
|
@ -98,7 +98,7 @@ impl Actionable for ConfigureNixDaemonService {
|
|||
vec![ActionDescription::new(
|
||||
"Unconfigure Nix daemon related settings with systemd".to_string(),
|
||||
vec![
|
||||
"Run `systemctl disable {SOCKET_SRC}`".to_string(),
|
||||
"Run `systemctl disable {SOCKET_SRC}`".to_string(),
|
||||
"Run `systemctl disable {SERVICE_SRC}`".to_string(),
|
||||
"Run `systemd-tempfiles --remove --prefix=/nix/var/nix`".to_string(),
|
||||
"Run `systemctl daemon-reload`".to_string(),
|
||||
|
|
|
@ -28,12 +28,10 @@ impl CreateDirectory {
|
|||
let path = path.as_ref();
|
||||
|
||||
if path.exists() && !force {
|
||||
return Err(CreateDirectoryError::Exists(
|
||||
std::io::Error::new(
|
||||
std::io::ErrorKind::AlreadyExists,
|
||||
format!("Directory `{}` already exists", path.display()),
|
||||
),
|
||||
));
|
||||
return Err(CreateDirectoryError::Exists(std::io::Error::new(
|
||||
std::io::ErrorKind::AlreadyExists,
|
||||
format!("Directory `{}` already exists", path.display()),
|
||||
)));
|
||||
}
|
||||
|
||||
Ok(Self {
|
||||
|
@ -114,7 +112,6 @@ impl Actionable for CreateDirectory {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
fn describe_revert(&self) -> Vec<ActionDescription> {
|
||||
let Self {
|
||||
path,
|
||||
|
@ -173,10 +170,7 @@ impl From<CreateDirectory> for Action {
|
|||
#[derive(Debug, thiserror::Error, Serialize)]
|
||||
pub enum CreateDirectoryError {
|
||||
#[error(transparent)]
|
||||
Exists(
|
||||
#[serde(serialize_with = "crate::serialize_error_to_display")]
|
||||
std::io::Error,
|
||||
),
|
||||
Exists(#[serde(serialize_with = "crate::serialize_error_to_display")] std::io::Error),
|
||||
#[error("Creating directory `{0}`")]
|
||||
Creating(
|
||||
std::path::PathBuf,
|
||||
|
|
|
@ -126,7 +126,6 @@ impl Actionable for CreateFile {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
fn describe_revert(&self) -> Vec<ActionDescription> {
|
||||
let Self {
|
||||
path,
|
||||
|
@ -142,9 +141,7 @@ impl Actionable for CreateFile {
|
|||
} else {
|
||||
vec![ActionDescription::new(
|
||||
format!("Delete file `{}`", path.display()),
|
||||
vec![format!(
|
||||
"Delete file `{}`", path.display()
|
||||
)],
|
||||
vec![format!("Delete file `{}`", path.display())],
|
||||
)]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -70,7 +70,6 @@ impl Actionable for CreateGroup {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
fn describe_revert(&self) -> Vec<ActionDescription> {
|
||||
let Self {
|
||||
name,
|
||||
|
|
|
@ -143,7 +143,8 @@ impl Actionable for CreateOrAppendFile {
|
|||
vec![ActionDescription::new(
|
||||
format!("Delete Nix related fragment from file `{}`", path.display()),
|
||||
vec![format!(
|
||||
"Delete Nix related fragment from file `{}`. Fragment: `{buf}`", path.display()
|
||||
"Delete Nix related fragment from file `{}`. Fragment: `{buf}`",
|
||||
path.display()
|
||||
)],
|
||||
)]
|
||||
}
|
||||
|
@ -192,7 +193,7 @@ impl Actionable for CreateOrAppendFile {
|
|||
remove_file(&path)
|
||||
.await
|
||||
.map_err(|e| Self::Error::RemoveFile(path.to_owned(), e))?;
|
||||
|
||||
|
||||
tracing::trace!("Removed file (since all content was removed)");
|
||||
} else {
|
||||
file.seek(SeekFrom::Start(0))
|
||||
|
|
|
@ -33,7 +33,12 @@ impl Actionable for CreateUser {
|
|||
if self.action_state == ActionState::Completed {
|
||||
vec![]
|
||||
} else {
|
||||
let Self { name, uid, gid, action_state: _ } = self;
|
||||
let Self {
|
||||
name,
|
||||
uid,
|
||||
gid,
|
||||
action_state: _,
|
||||
} = self;
|
||||
|
||||
vec![ActionDescription::new(
|
||||
format!("Create user {name} with UID {uid} with group {gid}"),
|
||||
|
@ -89,12 +94,16 @@ impl Actionable for CreateUser {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
fn describe_revert(&self) -> Vec<ActionDescription> {
|
||||
if self.action_state == ActionState::Uncompleted {
|
||||
vec![]
|
||||
} else {
|
||||
let Self { name, uid, gid, action_state: _ } = self;
|
||||
let Self {
|
||||
name,
|
||||
uid,
|
||||
gid,
|
||||
action_state: _,
|
||||
} = self;
|
||||
|
||||
vec![ActionDescription::new(
|
||||
format!("Delete user {name} with UID {uid} with group {gid}"),
|
||||
|
|
|
@ -43,10 +43,7 @@ impl Actionable for FetchNix {
|
|||
} else {
|
||||
vec![ActionDescription::new(
|
||||
format!("Fetch Nix from `{url}`"),
|
||||
vec![format!(
|
||||
"Unpack it to `{}` (moved later)",
|
||||
dest.display()
|
||||
)],
|
||||
vec![format!("Unpack it to `{}` (moved later)", dest.display())],
|
||||
)]
|
||||
}
|
||||
}
|
||||
|
@ -77,7 +74,9 @@ impl Actionable for FetchNix {
|
|||
let handle: Result<(), Self::Error> = spawn_blocking(move || {
|
||||
let decoder = xz2::read::XzDecoder::new(bytes.reader());
|
||||
let mut archive = tar::Archive::new(decoder);
|
||||
archive.unpack(&dest_clone).map_err(Self::Error::Unarchive)?;
|
||||
archive
|
||||
.unpack(&dest_clone)
|
||||
.map_err(Self::Error::Unarchive)?;
|
||||
tracing::debug!(dest = %dest_clone.display(), "Downloaded & extracted Nix");
|
||||
Ok(())
|
||||
})
|
||||
|
|
|
@ -46,10 +46,7 @@ impl Actionable for MoveUnpackedNix {
|
|||
dest = DEST,
|
||||
))]
|
||||
async fn execute(&mut self) -> Result<(), Self::Error> {
|
||||
let Self {
|
||||
src,
|
||||
action_state,
|
||||
} = self;
|
||||
let Self { src, action_state } = self;
|
||||
if *action_state == ActionState::Completed {
|
||||
tracing::trace!("Already completed: Moving Nix");
|
||||
return Ok(());
|
||||
|
@ -84,7 +81,6 @@ impl Actionable for MoveUnpackedNix {
|
|||
vec![/* Deliberately empty -- this is a noop */]
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[tracing::instrument(skip_all, fields(
|
||||
src = %self.src.display(),
|
||||
|
|
|
@ -29,16 +29,13 @@ impl SetupDefaultProfile {
|
|||
impl Actionable for SetupDefaultProfile {
|
||||
type Error = SetupDefaultProfileError;
|
||||
|
||||
|
||||
fn describe_execute(&self) -> Vec<ActionDescription> {
|
||||
if self.action_state == ActionState::Completed {
|
||||
vec![]
|
||||
} else {
|
||||
vec![ActionDescription::new(
|
||||
"Setup the default Nix profile".to_string(),
|
||||
vec![
|
||||
"TODO".to_string()
|
||||
]
|
||||
vec!["TODO".to_string()],
|
||||
)]
|
||||
}
|
||||
}
|
||||
|
@ -145,9 +142,7 @@ impl Actionable for SetupDefaultProfile {
|
|||
} else {
|
||||
vec![ActionDescription::new(
|
||||
"Unset the default Nix profile".to_string(),
|
||||
vec![
|
||||
"TODO".to_string()
|
||||
]
|
||||
vec!["TODO".to_string()],
|
||||
)]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,13 +2,12 @@ use serde::Serialize;
|
|||
|
||||
use crate::actions::{
|
||||
base::{
|
||||
ConfigureNixDaemonService, ConfigureNixDaemonServiceError,
|
||||
SetupDefaultProfile, SetupDefaultProfileError,
|
||||
ConfigureNixDaemonService, ConfigureNixDaemonServiceError, SetupDefaultProfile,
|
||||
SetupDefaultProfileError,
|
||||
},
|
||||
meta::{
|
||||
ConfigureShellProfile, ConfigureShellProfileError,
|
||||
PlaceChannelConfiguration, PlaceChannelConfigurationError,
|
||||
PlaceNixConfiguration, PlaceNixConfigurationError,
|
||||
ConfigureShellProfile, ConfigureShellProfileError, PlaceChannelConfiguration,
|
||||
PlaceChannelConfigurationError, PlaceNixConfiguration, PlaceNixConfigurationError,
|
||||
},
|
||||
Action, ActionState,
|
||||
};
|
||||
|
@ -189,7 +188,6 @@ impl Actionable for ConfigureNix {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
#[tracing::instrument(skip_all)]
|
||||
async fn revert(&mut self) -> Result<(), Self::Error> {
|
||||
let Self {
|
||||
|
@ -230,13 +228,33 @@ impl From<ConfigureNix> for Action {
|
|||
#[derive(Debug, thiserror::Error, Serialize)]
|
||||
pub enum ConfigureNixError {
|
||||
#[error("Setting up default profile")]
|
||||
SetupDefaultProfile(#[source] #[from] SetupDefaultProfileError),
|
||||
SetupDefaultProfile(
|
||||
#[source]
|
||||
#[from]
|
||||
SetupDefaultProfileError,
|
||||
),
|
||||
#[error("Placing Nix configuration")]
|
||||
PlaceNixConfiguration(#[source] #[from] PlaceNixConfigurationError),
|
||||
PlaceNixConfiguration(
|
||||
#[source]
|
||||
#[from]
|
||||
PlaceNixConfigurationError,
|
||||
),
|
||||
#[error("Placing channel configuration")]
|
||||
PlaceChannelConfiguration(#[source] #[from] PlaceChannelConfigurationError),
|
||||
PlaceChannelConfiguration(
|
||||
#[source]
|
||||
#[from]
|
||||
PlaceChannelConfigurationError,
|
||||
),
|
||||
#[error("Configuring Nix daemon")]
|
||||
ConfigureNixDaemonService(#[source] #[from] ConfigureNixDaemonServiceError),
|
||||
ConfigureNixDaemonService(
|
||||
#[source]
|
||||
#[from]
|
||||
ConfigureNixDaemonServiceError,
|
||||
),
|
||||
#[error("Configuring shell profile")]
|
||||
ConfigureShellProfile(#[source] #[from] ConfigureShellProfileError),
|
||||
ConfigureShellProfile(
|
||||
#[source]
|
||||
#[from]
|
||||
ConfigureShellProfileError,
|
||||
),
|
||||
}
|
||||
|
|
|
@ -129,7 +129,6 @@ impl Actionable for ConfigureShellProfile {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
#[tracing::instrument(skip_all)]
|
||||
async fn revert(&mut self) -> Result<(), Self::Error> {
|
||||
let Self {
|
||||
|
@ -192,7 +191,7 @@ pub enum ConfigureShellProfileError {
|
|||
CreateOrAppendFile(
|
||||
#[from]
|
||||
#[source]
|
||||
CreateOrAppendFileError
|
||||
CreateOrAppendFileError,
|
||||
),
|
||||
#[error("Multiple errors: {}", .0.iter().map(|v| format!("{v}")).collect::<Vec<_>>().join(" & "))]
|
||||
MultipleCreateOrAppendFile(Vec<CreateOrAppendFileError>),
|
||||
|
|
|
@ -151,5 +151,9 @@ impl From<CreateNixTree> for Action {
|
|||
#[derive(Debug, thiserror::Error, Serialize)]
|
||||
pub enum CreateNixTreeError {
|
||||
#[error("Creating directory")]
|
||||
CreateDirectory(#[source] #[from] CreateDirectoryError),
|
||||
CreateDirectory(
|
||||
#[source]
|
||||
#[from]
|
||||
CreateDirectoryError,
|
||||
),
|
||||
}
|
||||
|
|
|
@ -241,11 +241,19 @@ impl From<CreateUsersAndGroup> for Action {
|
|||
#[derive(Debug, thiserror::Error, Serialize)]
|
||||
pub enum CreateUsersAndGroupError {
|
||||
#[error("Creating user")]
|
||||
CreateUser(#[source] #[from] CreateUserError),
|
||||
CreateUser(
|
||||
#[source]
|
||||
#[from]
|
||||
CreateUserError,
|
||||
),
|
||||
#[error("Multiple errors: {}", .0.iter().map(|v| format!("{v}")).collect::<Vec<_>>().join(" & "))]
|
||||
CreateUsers(Vec<CreateUserError>),
|
||||
#[error("Creating group")]
|
||||
CreateGroup(#[source] #[from] CreateGroupError),
|
||||
CreateGroup(
|
||||
#[source]
|
||||
#[from]
|
||||
CreateGroupError,
|
||||
),
|
||||
#[error("Joining spawned async task")]
|
||||
Join(
|
||||
#[source]
|
||||
|
|
|
@ -57,7 +57,9 @@ impl Actionable for PlaceChannelConfiguration {
|
|||
} else {
|
||||
vec![ActionDescription::new(
|
||||
format!("Place channel configuration at `{NIX_CHANNELS_PATH}`"),
|
||||
vec![format!("Place channel configuration at `{NIX_CHANNELS_PATH}`")],
|
||||
vec![format!(
|
||||
"Place channel configuration at `{NIX_CHANNELS_PATH}`"
|
||||
)],
|
||||
)]
|
||||
}
|
||||
}
|
||||
|
@ -96,7 +98,9 @@ impl Actionable for PlaceChannelConfiguration {
|
|||
} else {
|
||||
vec![ActionDescription::new(
|
||||
format!("Remove channel configuration at `{NIX_CHANNELS_PATH}`"),
|
||||
vec![format!("Remove channel configuration at `{NIX_CHANNELS_PATH}`")],
|
||||
vec![format!(
|
||||
"Remove channel configuration at `{NIX_CHANNELS_PATH}`"
|
||||
)],
|
||||
)]
|
||||
}
|
||||
}
|
||||
|
@ -116,7 +120,7 @@ impl Actionable for PlaceChannelConfiguration {
|
|||
}
|
||||
*action_state = ActionState::Progress;
|
||||
tracing::debug!("Removing channel configuration");
|
||||
|
||||
|
||||
create_file.revert().await?;
|
||||
|
||||
tracing::debug!("Removed channel configuration");
|
||||
|
@ -134,5 +138,9 @@ impl From<PlaceChannelConfiguration> for Action {
|
|||
#[derive(Debug, thiserror::Error, Serialize)]
|
||||
pub enum PlaceChannelConfigurationError {
|
||||
#[error("Creating file")]
|
||||
CreateFile(#[source] #[from] CreateFileError),
|
||||
CreateFile(
|
||||
#[source]
|
||||
#[from]
|
||||
CreateFileError,
|
||||
),
|
||||
}
|
||||
|
|
|
@ -131,7 +131,15 @@ impl From<PlaceNixConfiguration> for Action {
|
|||
#[derive(Debug, thiserror::Error, Serialize)]
|
||||
pub enum PlaceNixConfigurationError {
|
||||
#[error("Creating file")]
|
||||
CreateFile(#[source] #[from] CreateFileError),
|
||||
CreateFile(
|
||||
#[source]
|
||||
#[from]
|
||||
CreateFileError,
|
||||
),
|
||||
#[error("Creating directory")]
|
||||
CreateDirectory(#[source] #[from] CreateDirectoryError),
|
||||
CreateDirectory(
|
||||
#[source]
|
||||
#[from]
|
||||
CreateDirectoryError,
|
||||
),
|
||||
}
|
||||
|
|
|
@ -59,7 +59,7 @@ impl Actionable for ProvisionNix {
|
|||
buf.append(&mut create_users_and_group.describe_execute());
|
||||
buf.append(&mut create_nix_tree.describe_execute());
|
||||
buf.append(&mut move_unpacked_nix.describe_execute());
|
||||
|
||||
|
||||
buf
|
||||
}
|
||||
}
|
||||
|
@ -121,7 +121,6 @@ impl Actionable for ProvisionNix {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
#[tracing::instrument(skip_all)]
|
||||
async fn revert(&mut self) -> Result<(), Self::Error> {
|
||||
let Self {
|
||||
|
@ -175,7 +174,11 @@ pub enum ProvisionNixError {
|
|||
std::io::Error,
|
||||
),
|
||||
#[error("Fetching Nix")]
|
||||
FetchNix(#[source] #[from] FetchNixError),
|
||||
FetchNix(
|
||||
#[source]
|
||||
#[from]
|
||||
FetchNixError,
|
||||
),
|
||||
#[error("Joining spawned async task")]
|
||||
Join(
|
||||
#[source]
|
||||
|
@ -184,9 +187,21 @@ pub enum ProvisionNixError {
|
|||
JoinError,
|
||||
),
|
||||
#[error("Creating users and group")]
|
||||
CreateUsersAndGroup(#[source] #[from] CreateUsersAndGroupError),
|
||||
CreateUsersAndGroup(
|
||||
#[source]
|
||||
#[from]
|
||||
CreateUsersAndGroupError,
|
||||
),
|
||||
#[error("Creating nix tree")]
|
||||
CreateNixTree(#[source] #[from] CreateNixTreeError),
|
||||
CreateNixTree(
|
||||
#[source]
|
||||
#[from]
|
||||
CreateNixTreeError,
|
||||
),
|
||||
#[error("Moving unpacked nix")]
|
||||
MoveUnpackedNix(#[source] #[from] MoveUnpackedNixError),
|
||||
MoveUnpackedNix(
|
||||
#[source]
|
||||
#[from]
|
||||
MoveUnpackedNixError,
|
||||
),
|
||||
}
|
||||
|
|
|
@ -93,5 +93,9 @@ impl From<StartNixDaemon> for Action {
|
|||
#[derive(Debug, thiserror::Error, Serialize)]
|
||||
pub enum StartNixDaemonError {
|
||||
#[error("Starting systemd unit")]
|
||||
StartSystemdUnit(#[source] #[from] StartSystemdUnitError),
|
||||
StartSystemdUnit(
|
||||
#[source]
|
||||
#[from]
|
||||
StartSystemdUnitError,
|
||||
),
|
||||
}
|
||||
|
|
|
@ -5,15 +5,15 @@ use base::{
|
|||
ConfigureNixDaemonService, ConfigureNixDaemonServiceError, CreateDirectory,
|
||||
CreateDirectoryError, CreateFile, CreateFileError, CreateGroup, CreateGroupError,
|
||||
CreateOrAppendFile, CreateOrAppendFileError, CreateUser, CreateUserError, FetchNix,
|
||||
FetchNixError, MoveUnpackedNix, MoveUnpackedNixError,
|
||||
SetupDefaultProfile, SetupDefaultProfileError,
|
||||
FetchNixError, MoveUnpackedNix, MoveUnpackedNixError, SetupDefaultProfile,
|
||||
SetupDefaultProfileError,
|
||||
};
|
||||
use meta::{
|
||||
ConfigureNix, ConfigureNixError, ConfigureShellProfile, ConfigureShellProfileError,
|
||||
CreateNixTree, CreateNixTreeError, CreateUsersAndGroup, PlaceChannelConfiguration,
|
||||
PlaceNixConfiguration, PlaceNixConfigurationError,
|
||||
PlaceChannelConfigurationError, CreateUsersAndGroupError, ProvisionNix,
|
||||
ProvisionNixError, StartNixDaemon, StartNixDaemonError,
|
||||
CreateNixTree, CreateNixTreeError, CreateUsersAndGroup, CreateUsersAndGroupError,
|
||||
PlaceChannelConfiguration, PlaceChannelConfigurationError, PlaceNixConfiguration,
|
||||
PlaceNixConfigurationError, ProvisionNix, ProvisionNixError, StartNixDaemon,
|
||||
StartNixDaemonError,
|
||||
};
|
||||
use serde::{de::DeserializeOwned, Deserialize, Serialize};
|
||||
|
||||
|
|
|
@ -3,8 +3,8 @@ pub(crate) mod subcommand;
|
|||
|
||||
use crate::{cli::arg::ChannelValue, interaction};
|
||||
use clap::{ArgAction, Parser};
|
||||
use harmonic::{InstallPlan, InstallSettings};
|
||||
use eyre::eyre;
|
||||
use harmonic::{InstallPlan, InstallSettings};
|
||||
use std::process::ExitCode;
|
||||
|
||||
use self::subcommand::HarmonicSubcommand;
|
||||
|
@ -100,11 +100,12 @@ impl CommandExecute for HarmonicCli {
|
|||
if !interaction::confirm(plan.describe_execute()).await? {
|
||||
interaction::clean_exit_with_message("Okay, didn't do anything! Bye!").await;
|
||||
}
|
||||
|
||||
|
||||
if let Err(err) = plan.install().await {
|
||||
tracing::error!("{:?}", eyre!(err));
|
||||
if !interaction::confirm(plan.describe_revert()).await? {
|
||||
interaction::clean_exit_with_message("Okay, didn't do anything! Bye!").await;
|
||||
interaction::clean_exit_with_message("Okay, didn't do anything! Bye!")
|
||||
.await;
|
||||
}
|
||||
plan.revert().await?
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use std::{path::PathBuf, process::ExitCode};
|
||||
|
||||
use clap::{ArgAction, Parser};
|
||||
use eyre::{WrapErr, eyre};
|
||||
use eyre::{eyre, WrapErr};
|
||||
use harmonic::InstallPlan;
|
||||
|
||||
use crate::{cli::CommandExecute, interaction};
|
||||
|
|
|
@ -20,7 +20,7 @@ pub(crate) async fn confirm(question: impl AsRef<str>) -> eyre::Result<bool> {
|
|||
|
||||
stdout.write_all(with_confirm.as_bytes()).await?;
|
||||
stdout.flush().await?;
|
||||
|
||||
|
||||
crossterm::terminal::enable_raw_mode()?;
|
||||
let mut reader = EventStream::new();
|
||||
let retval = loop {
|
||||
|
@ -30,7 +30,7 @@ pub(crate) async fn confirm(question: impl AsRef<str>) -> eyre::Result<bool> {
|
|||
if let crossterm::event::Event::Key(key) = event {
|
||||
match key.code {
|
||||
KeyCode::Enter => continue, // Many users will hit enter accidently when they are agreeing/declining prompts.
|
||||
// TODO(@hoverbear): Should maybe actually even wait for it?
|
||||
// TODO(@hoverbear): Should maybe actually even wait for it?
|
||||
KeyCode::Char('y') => break Ok(true),
|
||||
_ => {
|
||||
stdout
|
||||
|
|
38
src/plan.rs
38
src/plan.rs
|
@ -53,7 +53,12 @@ impl InstallPlan {
|
|||
|
||||
#[tracing::instrument(skip_all)]
|
||||
pub fn describe_execute(&self) -> String {
|
||||
let Self { settings, provision_nix, configure_nix, start_nix_daemon } = self;
|
||||
let Self {
|
||||
settings,
|
||||
provision_nix,
|
||||
configure_nix,
|
||||
start_nix_daemon,
|
||||
} = self;
|
||||
format!(
|
||||
"\
|
||||
This Nix install is for:\n\
|
||||
|
@ -98,36 +103,40 @@ impl InstallPlan {
|
|||
)
|
||||
}
|
||||
|
||||
|
||||
#[tracing::instrument(skip_all)]
|
||||
pub async fn install(&mut self) -> Result<(), HarmonicError> {
|
||||
// This is **deliberately sequential**.
|
||||
// Actions which are parallelizable are represented by "group actions" like CreateUsers
|
||||
// The plan itself represents the concept of the sequence of stages.
|
||||
|
||||
|
||||
if let Err(err) = self.provision_nix.execute().await {
|
||||
write_receipt(self.clone()).await?;
|
||||
return Err(ActionError::from(err).into())
|
||||
return Err(ActionError::from(err).into());
|
||||
}
|
||||
|
||||
|
||||
if let Err(err) = self.configure_nix.execute().await {
|
||||
write_receipt(self.clone()).await?;
|
||||
return Err(ActionError::from(err).into())
|
||||
return Err(ActionError::from(err).into());
|
||||
}
|
||||
|
||||
|
||||
if let Err(err) = self.start_nix_daemon.execute().await {
|
||||
write_receipt(self.clone()).await?;
|
||||
return Err(ActionError::from(err).into())
|
||||
return Err(ActionError::from(err).into());
|
||||
}
|
||||
|
||||
write_receipt(self.clone()).await?;
|
||||
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip_all)]
|
||||
pub fn describe_revert(&self) -> String {
|
||||
let Self { settings, provision_nix, configure_nix, start_nix_daemon } = self;
|
||||
let Self {
|
||||
settings,
|
||||
provision_nix,
|
||||
configure_nix,
|
||||
start_nix_daemon,
|
||||
} = self;
|
||||
format!(
|
||||
"\
|
||||
This Nix uninstall is for:\n\
|
||||
|
@ -179,17 +188,17 @@ impl InstallPlan {
|
|||
// The plan itself represents the concept of the sequence of stages.
|
||||
if let Err(err) = self.start_nix_daemon.revert().await {
|
||||
write_receipt(self.clone()).await?;
|
||||
return Err(ActionError::from(err).into())
|
||||
return Err(ActionError::from(err).into());
|
||||
}
|
||||
|
||||
if let Err(err) = self.configure_nix.revert().await {
|
||||
write_receipt(self.clone()).await?;
|
||||
return Err(ActionError::from(err).into())
|
||||
return Err(ActionError::from(err).into());
|
||||
}
|
||||
|
||||
if let Err(err) = self.provision_nix.revert().await {
|
||||
write_receipt(self.clone()).await?;
|
||||
return Err(ActionError::from(err).into())
|
||||
return Err(ActionError::from(err).into());
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
@ -197,7 +206,8 @@ impl InstallPlan {
|
|||
}
|
||||
|
||||
async fn write_receipt(plan: InstallPlan) -> Result<(), HarmonicError> {
|
||||
tokio::fs::create_dir_all("/nix").await
|
||||
tokio::fs::create_dir_all("/nix")
|
||||
.await
|
||||
.map_err(|e| HarmonicError::RecordingReceipt(PathBuf::from("/nix"), e))?;
|
||||
let install_receipt_path = PathBuf::from("/nix/receipt.json");
|
||||
let self_json =
|
||||
|
|
Loading…
Reference in a new issue