More scaffolding
Signed-off-by: Ana Hobden <operator@hoverbear.org>
This commit is contained in:
parent
38cc094381
commit
8addef670d
|
@ -1,6 +1,6 @@
|
|||
use crate::HarmonicError;
|
||||
|
||||
use super::{ActionDescription, ActionReceipt, Actionable, Revertable};
|
||||
use crate::actions::{ActionDescription, ActionReceipt, Actionable, Revertable};
|
||||
|
||||
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
|
||||
pub struct ConfigureNixDaemonService {}
|
||||
|
@ -13,6 +13,7 @@ impl ConfigureNixDaemonService {
|
|||
|
||||
#[async_trait::async_trait]
|
||||
impl<'a> Actionable<'a> for ConfigureNixDaemonService {
|
||||
type Receipt = ConfigureNixDaemonServiceReceipt;
|
||||
fn description(&self) -> Vec<ActionDescription> {
|
||||
vec![
|
||||
ActionDescription::new(
|
||||
|
@ -24,7 +25,7 @@ impl<'a> Actionable<'a> for ConfigureNixDaemonService {
|
|||
]
|
||||
}
|
||||
|
||||
async fn execute(self) -> Result<ActionReceipt, HarmonicError> {
|
||||
async fn execute(self) -> Result<Self::Receipt, HarmonicError> {
|
||||
todo!()
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
use crate::HarmonicError;
|
||||
|
||||
use super::{ActionDescription, ActionReceipt, Actionable, Revertable};
|
||||
use crate::actions::{ActionDescription, ActionReceipt, Actionable, Revertable};
|
||||
|
||||
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
|
||||
pub struct ConfigureShellProfile {}
|
||||
|
@ -13,6 +13,7 @@ impl ConfigureShellProfile {
|
|||
|
||||
#[async_trait::async_trait]
|
||||
impl<'a> Actionable<'a> for ConfigureShellProfile {
|
||||
type Receipt = ConfigureShellProfileReceipt;
|
||||
fn description(&self) -> Vec<ActionDescription> {
|
||||
vec![
|
||||
ActionDescription::new(
|
||||
|
@ -24,7 +25,7 @@ impl<'a> Actionable<'a> for ConfigureShellProfile {
|
|||
]
|
||||
}
|
||||
|
||||
async fn execute(self) -> Result<ActionReceipt, HarmonicError> {
|
||||
async fn execute(self) -> Result<Self::Receipt, HarmonicError> {
|
||||
todo!()
|
||||
}
|
||||
}
|
|
@ -5,7 +5,7 @@ use std::{
|
|||
|
||||
use crate::HarmonicError;
|
||||
|
||||
use super::{ActionDescription, ActionReceipt, Actionable, Revertable};
|
||||
use crate::actions::{ActionDescription, ActionReceipt, Actionable, Revertable};
|
||||
|
||||
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
|
||||
pub struct CreateDirectory {
|
||||
|
@ -29,6 +29,7 @@ impl CreateDirectory {
|
|||
|
||||
#[async_trait::async_trait]
|
||||
impl<'a> Actionable<'a> for CreateDirectory {
|
||||
type Receipt = CreateDirectoryReceipt;
|
||||
fn description(&self) -> Vec<ActionDescription> {
|
||||
vec![ActionDescription::new(
|
||||
format!("Create the directory `/nix`"),
|
||||
|
@ -38,7 +39,7 @@ impl<'a> Actionable<'a> for CreateDirectory {
|
|||
)]
|
||||
}
|
||||
|
||||
async fn execute(self) -> Result<ActionReceipt, HarmonicError> {
|
||||
async fn execute(self) -> Result<CreateDirectoryReceipt, HarmonicError> {
|
||||
let Self {
|
||||
path,
|
||||
user,
|
||||
|
@ -46,12 +47,12 @@ impl<'a> Actionable<'a> for CreateDirectory {
|
|||
mode,
|
||||
} = self;
|
||||
todo!();
|
||||
Ok(ActionReceipt::CreateDirectory(CreateDirectoryReceipt {
|
||||
Ok(CreateDirectoryReceipt {
|
||||
path,
|
||||
user,
|
||||
group,
|
||||
mode,
|
||||
}))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
use crate::HarmonicError;
|
||||
|
||||
use super::{ActionDescription, ActionReceipt, Actionable, Revertable};
|
||||
use crate::actions::{ActionDescription, ActionReceipt, Actionable, Revertable};
|
||||
|
||||
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
|
||||
pub struct CreateGroup {
|
||||
|
@ -16,6 +16,7 @@ impl CreateGroup {
|
|||
|
||||
#[async_trait::async_trait]
|
||||
impl<'a> Actionable<'a> for CreateGroup {
|
||||
type Receipt = CreateGroupReceipt;
|
||||
fn description(&self) -> Vec<ActionDescription> {
|
||||
let name = &self.name;
|
||||
let uid = &self.uid;
|
||||
|
@ -27,9 +28,9 @@ impl<'a> Actionable<'a> for CreateGroup {
|
|||
)]
|
||||
}
|
||||
|
||||
async fn execute(self) -> Result<ActionReceipt, HarmonicError> {
|
||||
async fn execute(self) -> Result<Self::Receipt, HarmonicError> {
|
||||
let Self { name, uid } = self;
|
||||
Ok(ActionReceipt::CreateGroup(CreateGroupReceipt { name, uid }))
|
||||
Ok(CreateGroupReceipt { name, uid })
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
use crate::HarmonicError;
|
||||
|
||||
use super::{ActionDescription, ActionReceipt, Actionable, Revertable};
|
||||
use crate::actions::{ActionDescription, ActionReceipt, Actionable, Revertable};
|
||||
|
||||
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
|
||||
pub struct CreateUser {
|
||||
|
@ -16,6 +16,7 @@ impl CreateUser {
|
|||
|
||||
#[async_trait::async_trait]
|
||||
impl<'a> Actionable<'a> for CreateUser {
|
||||
type Receipt = CreateUserReceipt;
|
||||
fn description(&self) -> Vec<ActionDescription> {
|
||||
let name = &self.name;
|
||||
let uid = &self.uid;
|
||||
|
@ -27,9 +28,9 @@ impl<'a> Actionable<'a> for CreateUser {
|
|||
)]
|
||||
}
|
||||
|
||||
async fn execute(self) -> Result<ActionReceipt, HarmonicError> {
|
||||
async fn execute(self) -> Result<Self::Receipt, HarmonicError> {
|
||||
let Self { name, uid } = self;
|
||||
Ok(ActionReceipt::CreateUser(CreateUserReceipt { name, uid }))
|
||||
Ok(CreateUserReceipt { name, uid })
|
||||
}
|
||||
}
|
||||
|
59
src/actions/base/fetch_nix.rs
Normal file
59
src/actions/base/fetch_nix.rs
Normal file
|
@ -0,0 +1,59 @@
|
|||
use std::path::{Path, PathBuf};
|
||||
|
||||
use reqwest::Url;
|
||||
|
||||
use crate::HarmonicError;
|
||||
|
||||
use crate::actions::{ActionDescription, ActionReceipt, Actionable, Revertable};
|
||||
|
||||
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
|
||||
pub struct FetchNix {
|
||||
url: Url,
|
||||
destination: PathBuf,
|
||||
}
|
||||
|
||||
impl FetchNix {
|
||||
pub fn plan(url: Url, destination: PathBuf) -> Self {
|
||||
Self { url, destination }
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl<'a> Actionable<'a> for FetchNix {
|
||||
type Receipt = FetchNixReceipt;
|
||||
fn description(&self) -> Vec<ActionDescription> {
|
||||
let Self {
|
||||
url, destination
|
||||
} = &self;
|
||||
vec![ActionDescription::new(
|
||||
format!("Fetch Nix from `{url}`"),
|
||||
vec![format!(
|
||||
"Fetch a Nix archive and unpack it to `{}`", destination.display()
|
||||
)],
|
||||
)]
|
||||
}
|
||||
|
||||
async fn execute(self) -> Result<Self::Receipt, HarmonicError> {
|
||||
let Self { url, destination } = self;
|
||||
Ok(FetchNixReceipt { url, destination })
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
|
||||
pub struct FetchNixReceipt {
|
||||
url: Url,
|
||||
destination: PathBuf,
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl<'a> Revertable<'a> for FetchNixReceipt {
|
||||
fn description(&self) -> Vec<ActionDescription> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn revert(self) -> Result<(), HarmonicError> {
|
||||
todo!();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
29
src/actions/base/mod.rs
Normal file
29
src/actions/base/mod.rs
Normal file
|
@ -0,0 +1,29 @@
|
|||
/*! Actions which do not only call other base plugins. */
|
||||
|
||||
mod configure_nix_daemon_service;
|
||||
mod configure_shell_profile;
|
||||
mod create_directory;
|
||||
mod create_group;
|
||||
mod create_user;
|
||||
mod fetch_nix;
|
||||
mod move_unpacked_nix;
|
||||
mod place_channel_configuration;
|
||||
mod place_nix_configuration;
|
||||
mod setup_default_profile;
|
||||
mod start_systemd_service;
|
||||
|
||||
pub use configure_nix_daemon_service::{
|
||||
ConfigureNixDaemonService, ConfigureNixDaemonServiceReceipt,
|
||||
};
|
||||
pub use configure_shell_profile::{ConfigureShellProfile, ConfigureShellProfileReceipt};
|
||||
pub use create_directory::{CreateDirectory, CreateDirectoryReceipt};
|
||||
pub use create_group::{CreateGroup, CreateGroupReceipt};
|
||||
pub use create_user::{CreateUser, CreateUserReceipt};
|
||||
pub use fetch_nix::{FetchNix, FetchNixReceipt};
|
||||
pub use move_unpacked_nix::{MoveUnpackedNix, MoveUnpackedNixReceipt};
|
||||
pub use place_channel_configuration::{
|
||||
PlaceChannelConfiguration, PlaceChannelConfigurationReceipt,
|
||||
};
|
||||
pub use place_nix_configuration::{PlaceNixConfiguration, PlaceNixConfigurationReceipt};
|
||||
pub use setup_default_profile::{SetupDefaultProfile, SetupDefaultProfileReceipt};
|
||||
pub use start_systemd_service::{StartSystemdService, StartSystemdServiceReceipt};
|
53
src/actions/base/move_unpacked_nix.rs
Normal file
53
src/actions/base/move_unpacked_nix.rs
Normal file
|
@ -0,0 +1,53 @@
|
|||
use std::path::PathBuf;
|
||||
|
||||
use crate::HarmonicError;
|
||||
|
||||
use crate::actions::{ActionDescription, ActionReceipt, Actionable, Revertable};
|
||||
|
||||
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
|
||||
pub struct MoveUnpackedNix {
|
||||
source: PathBuf,
|
||||
}
|
||||
|
||||
impl MoveUnpackedNix {
|
||||
pub fn plan(source: PathBuf) -> Self {
|
||||
Self { source, }
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl<'a> Actionable<'a> for MoveUnpackedNix {
|
||||
type Receipt = MoveUnpackedNixReceipt;
|
||||
fn description(&self) -> Vec<ActionDescription> {
|
||||
let Self { source } = &self;
|
||||
vec![ActionDescription::new(
|
||||
format!("Move the downloaded Nix into `/nix`"),
|
||||
vec![format!(
|
||||
"Nix is downloaded to `{}` and should be in `nix`", source.display(),
|
||||
)],
|
||||
)]
|
||||
}
|
||||
|
||||
async fn execute(self) -> Result<Self::Receipt, HarmonicError> {
|
||||
let Self { source } = self;
|
||||
Ok(MoveUnpackedNixReceipt { })
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
|
||||
pub struct MoveUnpackedNixReceipt {
|
||||
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl<'a> Revertable<'a> for MoveUnpackedNixReceipt {
|
||||
fn description(&self) -> Vec<ActionDescription> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn revert(self) -> Result<(), HarmonicError> {
|
||||
todo!();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
use crate::HarmonicError;
|
||||
|
||||
use super::{ActionDescription, ActionReceipt, Actionable, Revertable};
|
||||
use crate::actions::{ActionDescription, ActionReceipt, Actionable, Revertable};
|
||||
|
||||
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
|
||||
pub struct PlaceChannelConfiguration {}
|
||||
|
@ -13,6 +13,7 @@ impl PlaceChannelConfiguration {
|
|||
|
||||
#[async_trait::async_trait]
|
||||
impl<'a> Actionable<'a> for PlaceChannelConfiguration {
|
||||
type Receipt = PlaceChannelConfigurationReceipt;
|
||||
fn description(&self) -> Vec<ActionDescription> {
|
||||
vec![
|
||||
ActionDescription::new(
|
||||
|
@ -24,7 +25,7 @@ impl<'a> Actionable<'a> for PlaceChannelConfiguration {
|
|||
]
|
||||
}
|
||||
|
||||
async fn execute(self) -> Result<ActionReceipt, HarmonicError> {
|
||||
async fn execute(self) -> Result<Self::Receipt, HarmonicError> {
|
||||
todo!()
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
use crate::HarmonicError;
|
||||
|
||||
use super::{ActionDescription, ActionReceipt, Actionable, Revertable};
|
||||
use crate::actions::{ActionDescription, ActionReceipt, Actionable, Revertable};
|
||||
|
||||
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
|
||||
pub struct PlaceNixConfiguration {}
|
||||
|
@ -13,6 +13,7 @@ impl PlaceNixConfiguration {
|
|||
|
||||
#[async_trait::async_trait]
|
||||
impl<'a> Actionable<'a> for PlaceNixConfiguration {
|
||||
type Receipt = PlaceNixConfigurationReceipt;
|
||||
fn description(&self) -> Vec<ActionDescription> {
|
||||
vec![
|
||||
ActionDescription::new(
|
||||
|
@ -24,7 +25,7 @@ impl<'a> Actionable<'a> for PlaceNixConfiguration {
|
|||
]
|
||||
}
|
||||
|
||||
async fn execute(self) -> Result<ActionReceipt, HarmonicError> {
|
||||
async fn execute(self) -> Result<Self::Receipt, HarmonicError> {
|
||||
todo!()
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
use crate::HarmonicError;
|
||||
|
||||
use super::{ActionDescription, ActionReceipt, Actionable, Revertable};
|
||||
use crate::actions::{ActionDescription, ActionReceipt, Actionable, Revertable};
|
||||
|
||||
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
|
||||
pub struct SetupDefaultProfile {}
|
||||
|
@ -13,6 +13,7 @@ impl SetupDefaultProfile {
|
|||
|
||||
#[async_trait::async_trait]
|
||||
impl<'a> Actionable<'a> for SetupDefaultProfile {
|
||||
type Receipt = SetupDefaultProfileReceipt;
|
||||
fn description(&self) -> Vec<ActionDescription> {
|
||||
vec![
|
||||
ActionDescription::new(
|
||||
|
@ -24,7 +25,7 @@ impl<'a> Actionable<'a> for SetupDefaultProfile {
|
|||
]
|
||||
}
|
||||
|
||||
async fn execute(self) -> Result<ActionReceipt, HarmonicError> {
|
||||
async fn execute(self) -> Result<Self::Receipt, HarmonicError> {
|
||||
todo!()
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
use crate::HarmonicError;
|
||||
|
||||
use super::{ActionDescription, ActionReceipt, Actionable, Revertable};
|
||||
use crate::actions::{ActionDescription, ActionReceipt, Actionable, Revertable};
|
||||
|
||||
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
|
||||
pub struct StartSystemdService {}
|
||||
|
@ -13,6 +13,7 @@ impl StartSystemdService {
|
|||
|
||||
#[async_trait::async_trait]
|
||||
impl<'a> Actionable<'a> for StartSystemdService {
|
||||
type Receipt = StartSystemdServiceReceipt;
|
||||
fn description(&self) -> Vec<ActionDescription> {
|
||||
vec![
|
||||
ActionDescription::new(
|
||||
|
@ -24,7 +25,7 @@ impl<'a> Actionable<'a> for StartSystemdService {
|
|||
]
|
||||
}
|
||||
|
||||
async fn execute(self) -> Result<ActionReceipt, HarmonicError> {
|
||||
async fn execute(self) -> Result<Self::Receipt, HarmonicError> {
|
||||
todo!()
|
||||
}
|
||||
}
|
|
@ -1,117 +0,0 @@
|
|||
use tokio::task::JoinSet;
|
||||
|
||||
use crate::HarmonicError;
|
||||
|
||||
use super::{ActionDescription, ActionReceipt, Actionable, CreateUser, Revertable};
|
||||
|
||||
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
|
||||
pub struct CreateUsers {
|
||||
nix_build_user_prefix: String,
|
||||
nix_build_user_id_base: usize,
|
||||
daemon_user_count: usize,
|
||||
children: Vec<CreateUser>,
|
||||
}
|
||||
|
||||
impl CreateUsers {
|
||||
pub fn plan(
|
||||
nix_build_user_prefix: String,
|
||||
nix_build_user_id_base: usize,
|
||||
daemon_user_count: usize,
|
||||
) -> Self {
|
||||
let children = (0..daemon_user_count)
|
||||
.map(|count| {
|
||||
CreateUser::plan(
|
||||
format!("{nix_build_user_prefix}{count}"),
|
||||
nix_build_user_id_base + count,
|
||||
)
|
||||
})
|
||||
.collect();
|
||||
Self {
|
||||
nix_build_user_prefix,
|
||||
nix_build_user_id_base,
|
||||
daemon_user_count,
|
||||
children,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl<'a> Actionable<'a> for CreateUsers {
|
||||
fn description(&self) -> Vec<ActionDescription> {
|
||||
let nix_build_user_prefix = &self.nix_build_user_prefix;
|
||||
let nix_build_user_id_base = &self.nix_build_user_id_base;
|
||||
let daemon_user_count = &self.daemon_user_count;
|
||||
vec![
|
||||
ActionDescription::new(
|
||||
format!("Create build users"),
|
||||
vec![
|
||||
format!("The nix daemon requires system users it can act as in order to build"),
|
||||
format!("This action will create {daemon_user_count} users with prefix `{nix_build_user_prefix}` starting at uid `{nix_build_user_id_base}`"),
|
||||
],
|
||||
)
|
||||
]
|
||||
}
|
||||
|
||||
async fn execute(self) -> Result<ActionReceipt, HarmonicError> {
|
||||
// TODO(@hoverbear): Abstract this, it will be common
|
||||
let Self { children, .. } = self;
|
||||
let mut set = JoinSet::new();
|
||||
let mut successes = Vec::with_capacity(children.len());
|
||||
let mut errors = Vec::default();
|
||||
|
||||
for child in children {
|
||||
let _abort_handle = set.spawn(async move { child.execute().await });
|
||||
}
|
||||
|
||||
while let Some(result) = set.join_next().await {
|
||||
match result {
|
||||
Ok(Ok(success)) => successes.push(success),
|
||||
Ok(Err(e)) => errors.push(e),
|
||||
Err(e) => errors.push(e.into()),
|
||||
};
|
||||
}
|
||||
|
||||
if !errors.is_empty() {
|
||||
// If we got an error in a child, we need to revert the successful ones:
|
||||
let mut failed_reverts = Vec::default();
|
||||
for success in successes {
|
||||
match success.revert().await {
|
||||
Ok(()) => (),
|
||||
Err(e) => failed_reverts.push(e),
|
||||
}
|
||||
}
|
||||
|
||||
if !failed_reverts.is_empty() {
|
||||
return Err(HarmonicError::FailedReverts(errors, failed_reverts));
|
||||
}
|
||||
|
||||
if errors.len() == 1 {
|
||||
return Err(errors.into_iter().next().unwrap());
|
||||
} else {
|
||||
return Err(HarmonicError::Multiple(errors));
|
||||
}
|
||||
}
|
||||
|
||||
Ok(ActionReceipt::CreateUsers(CreateUsersReceipt {
|
||||
children: successes,
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
|
||||
pub struct CreateUsersReceipt {
|
||||
children: Vec<ActionReceipt>,
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl<'a> Revertable<'a> for CreateUsersReceipt {
|
||||
fn description(&self) -> Vec<ActionDescription> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn revert(self) -> Result<(), HarmonicError> {
|
||||
todo!();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
use crate::{HarmonicError, InstallSettings};
|
||||
|
||||
use super::{ActionDescription, ActionReceipt, Actionable, Revertable};
|
||||
use crate::actions::{ActionDescription, ActionReceipt, Actionable, Revertable};
|
||||
|
||||
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
|
||||
pub struct ConfigureNix {}
|
||||
|
@ -13,18 +13,19 @@ impl ConfigureNix {
|
|||
|
||||
#[async_trait::async_trait]
|
||||
impl<'a> Actionable<'a> for ConfigureNix {
|
||||
type Receipt = ConfigureNixReceipt;
|
||||
fn description(&self) -> Vec<ActionDescription> {
|
||||
vec![
|
||||
ActionDescription::new(
|
||||
"Start the systemd Nix daemon".to_string(),
|
||||
"Configure the Nix daemon".to_string(),
|
||||
vec![
|
||||
"The `nix` command line tool communicates with a running Nix daemon managed by your init system".to_string()
|
||||
"Blah".to_string()
|
||||
]
|
||||
),
|
||||
]
|
||||
}
|
||||
|
||||
async fn execute(self) -> Result<ActionReceipt, HarmonicError> {
|
||||
async fn execute(self) -> Result<Self::Receipt, HarmonicError> {
|
||||
todo!()
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
use crate::{HarmonicError, InstallSettings};
|
||||
|
||||
use super::{ActionDescription, ActionReceipt, Actionable, Revertable};
|
||||
use crate::actions::{ActionDescription, ActionReceipt, Actionable, Revertable};
|
||||
|
||||
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
|
||||
pub struct CreateNixTree {
|
||||
|
@ -15,6 +15,7 @@ impl CreateNixTree {
|
|||
|
||||
#[async_trait::async_trait]
|
||||
impl<'a> Actionable<'a> for CreateNixTree {
|
||||
type Receipt = CreateNixTreeReceipt;
|
||||
fn description(&self) -> Vec<ActionDescription> {
|
||||
vec![ActionDescription::new(
|
||||
format!("Create a directory tree in `/nix`"),
|
||||
|
@ -24,9 +25,9 @@ impl<'a> Actionable<'a> for CreateNixTree {
|
|||
)]
|
||||
}
|
||||
|
||||
async fn execute(self) -> Result<ActionReceipt, HarmonicError> {
|
||||
async fn execute(self) -> Result<Self::Receipt, HarmonicError> {
|
||||
let Self { settings: _ } = self;
|
||||
Ok(ActionReceipt::CreateNixTree(CreateNixTreeReceipt {}))
|
||||
Ok(CreateNixTreeReceipt {})
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
use crate::HarmonicError;
|
||||
|
||||
use super::{ActionDescription, ActionReceipt, Actionable, Revertable};
|
||||
use crate::actions::{ActionDescription, ActionReceipt, Actionable, Revertable};
|
||||
|
||||
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
|
||||
pub struct CreateNixTreeDirs {}
|
||||
|
@ -13,6 +13,7 @@ impl CreateNixTreeDirs {
|
|||
|
||||
#[async_trait::async_trait]
|
||||
impl<'a> Actionable<'a> for CreateNixTreeDirs {
|
||||
type Receipt = CreateNixTreeDirsReceipt;
|
||||
fn description(&self) -> Vec<ActionDescription> {
|
||||
vec![ActionDescription::new(
|
||||
format!("Create a directory tree in `/nix`"),
|
||||
|
@ -22,11 +23,9 @@ impl<'a> Actionable<'a> for CreateNixTreeDirs {
|
|||
)]
|
||||
}
|
||||
|
||||
async fn execute(self) -> Result<ActionReceipt, HarmonicError> {
|
||||
async fn execute(self) -> Result<Self::Receipt, HarmonicError> {
|
||||
let Self {} = self;
|
||||
Ok(ActionReceipt::CreateNixTreeDirs(
|
||||
CreateNixTreeDirsReceipt {},
|
||||
))
|
||||
Ok(CreateNixTreeDirsReceipt {})
|
||||
}
|
||||
}
|
||||
|
137
src/actions/meta/create_users_and_group.rs
Normal file
137
src/actions/meta/create_users_and_group.rs
Normal file
|
@ -0,0 +1,137 @@
|
|||
use tokio::task::JoinSet;
|
||||
|
||||
use crate::{HarmonicError, InstallSettings};
|
||||
|
||||
use crate::actions::base::{CreateGroup, CreateUserReceipt, CreateGroupReceipt};
|
||||
use crate::actions::{ActionDescription, ActionReceipt, Actionable, CreateUser, Revertable};
|
||||
|
||||
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
|
||||
pub struct CreateUsersAndGroup {
|
||||
settings: InstallSettings,
|
||||
create_group: CreateGroup,
|
||||
create_users: Vec<CreateUser>,
|
||||
}
|
||||
|
||||
impl CreateUsersAndGroup {
|
||||
pub fn plan(
|
||||
settings: InstallSettings
|
||||
) -> Self {
|
||||
let create_group = CreateGroup::plan(settings.nix_build_group_name.clone(), settings.nix_build_group_id);
|
||||
let create_users = (0..settings.daemon_user_count)
|
||||
.map(|count| {
|
||||
CreateUser::plan(
|
||||
format!("{}{count}", settings.nix_build_user_prefix),
|
||||
settings.nix_build_user_id_base + count,
|
||||
)
|
||||
})
|
||||
.collect();
|
||||
Self {
|
||||
settings,
|
||||
create_group,
|
||||
create_users,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl<'a> Actionable<'a> for CreateUsersAndGroup {
|
||||
type Receipt = CreateUsersAndGroupReceipt;
|
||||
fn description(&self) -> Vec<ActionDescription> {
|
||||
let Self {
|
||||
create_users: _,
|
||||
create_group: _,
|
||||
settings: InstallSettings {
|
||||
explain: _,
|
||||
daemon_user_count,
|
||||
channels: _,
|
||||
modify_profile: _,
|
||||
nix_build_group_name,
|
||||
nix_build_group_id,
|
||||
nix_build_user_prefix,
|
||||
nix_build_user_id_base,
|
||||
nix_package_url,
|
||||
}
|
||||
} = &self;
|
||||
|
||||
vec![
|
||||
ActionDescription::new(
|
||||
format!("Create build users and group"),
|
||||
vec![
|
||||
format!("The nix daemon requires system users it can act as in order to build"),
|
||||
format!("This action will create group `{nix_build_group_name}` with uid `{nix_build_group_id}`"),
|
||||
format!("This action will create {daemon_user_count} users with prefix `{nix_build_user_prefix}` starting at uid `{nix_build_user_id_base}`"),
|
||||
],
|
||||
)
|
||||
]
|
||||
}
|
||||
|
||||
async fn execute(self) -> Result<Self::Receipt, HarmonicError> {
|
||||
let Self { create_users, create_group, settings: _ } = self;
|
||||
|
||||
// Create group
|
||||
let create_group = create_group.execute().await?;
|
||||
|
||||
// Create users
|
||||
// TODO(@hoverbear): Abstract this, it will be common
|
||||
let mut set = JoinSet::new();
|
||||
let mut successes = Vec::with_capacity(create_users.len());
|
||||
let mut errors = Vec::default();
|
||||
|
||||
for create_user in create_users {
|
||||
let _abort_handle = set.spawn(async move { create_user.execute().await });
|
||||
}
|
||||
|
||||
while let Some(result) = set.join_next().await {
|
||||
match result {
|
||||
Ok(Ok(success)) => successes.push(success),
|
||||
Ok(Err(e)) => errors.push(e),
|
||||
Err(e) => errors.push(e.into()),
|
||||
};
|
||||
}
|
||||
|
||||
if !errors.is_empty() {
|
||||
// If we got an error in a child, we need to revert the successful ones:
|
||||
let mut failed_reverts = Vec::default();
|
||||
for success in successes {
|
||||
match success.revert().await {
|
||||
Ok(()) => (),
|
||||
Err(e) => failed_reverts.push(e),
|
||||
}
|
||||
}
|
||||
|
||||
if !failed_reverts.is_empty() {
|
||||
return Err(HarmonicError::FailedReverts(errors, failed_reverts));
|
||||
}
|
||||
|
||||
if errors.len() == 1 {
|
||||
return Err(errors.into_iter().next().unwrap());
|
||||
} else {
|
||||
return Err(HarmonicError::Multiple(errors));
|
||||
}
|
||||
}
|
||||
|
||||
Ok(CreateUsersAndGroupReceipt {
|
||||
create_group,
|
||||
create_users: successes,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
|
||||
pub struct CreateUsersAndGroupReceipt {
|
||||
create_group: CreateGroupReceipt,
|
||||
create_users: Vec<CreateUserReceipt>,
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl<'a> Revertable<'a> for CreateUsersAndGroupReceipt {
|
||||
fn description(&self) -> Vec<ActionDescription> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn revert(self) -> Result<(), HarmonicError> {
|
||||
todo!();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
15
src/actions/meta/mod.rs
Normal file
15
src/actions/meta/mod.rs
Normal file
|
@ -0,0 +1,15 @@
|
|||
/*! Actions which only call other base plugins. */
|
||||
|
||||
mod create_nix_tree;
|
||||
mod create_nix_tree_dirs;
|
||||
mod create_users_and_group;
|
||||
mod configure_nix;
|
||||
mod start_nix_daemon;
|
||||
mod provision_nix;
|
||||
|
||||
pub use create_nix_tree::{CreateNixTree, CreateNixTreeReceipt};
|
||||
pub use create_nix_tree_dirs::{CreateNixTreeDirs, CreateNixTreeDirsReceipt};
|
||||
pub use create_users_and_group::{CreateUsersAndGroup, CreateUsersAndGroupReceipt};
|
||||
pub use configure_nix::{ConfigureNix, ConfigureNixReceipt};
|
||||
pub use start_nix_daemon::{StartNixDaemon, StartNixDaemonReceipt};
|
||||
pub use provision_nix::{ProvisionNix, ProvisionNixReceipt};
|
79
src/actions/meta/provision_nix.rs
Normal file
79
src/actions/meta/provision_nix.rs
Normal file
|
@ -0,0 +1,79 @@
|
|||
use tempdir::TempDir;
|
||||
|
||||
use crate::actions::base::{FetchNix, MoveUnpackedNix, FetchNixReceipt, MoveUnpackedNixReceipt};
|
||||
use crate::{HarmonicError, InstallSettings};
|
||||
|
||||
use crate::actions::{ActionDescription, ActionReceipt, Actionable, Revertable};
|
||||
|
||||
use super::{CreateUsersAndGroup, CreateNixTree, create_users_and_group, create_nix_tree, CreateUsersAndGroupReceipt, CreateNixTreeReceipt};
|
||||
|
||||
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
|
||||
pub struct ProvisionNix {
|
||||
fetch_nix: FetchNix,
|
||||
create_users_and_group: CreateUsersAndGroup,
|
||||
create_nix_tree: CreateNixTree,
|
||||
move_unpacked_nix: MoveUnpackedNix,
|
||||
}
|
||||
|
||||
impl ProvisionNix {
|
||||
pub fn plan(settings: InstallSettings) -> Result<Self, HarmonicError> {
|
||||
let tempdir = TempDir::new("nix").map_err(HarmonicError::TempDir)?;
|
||||
|
||||
let fetch_nix = FetchNix::plan(settings.nix_package_url.clone(), tempdir.path().to_path_buf());
|
||||
let create_users_and_group = CreateUsersAndGroup::plan(settings.clone());
|
||||
let create_nix_tree = CreateNixTree::plan(settings.clone());
|
||||
let move_unpacked_nix = MoveUnpackedNix::plan(tempdir.path().to_path_buf());
|
||||
Ok(Self { fetch_nix, create_users_and_group, create_nix_tree, move_unpacked_nix })
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl<'a> Actionable<'a> for ProvisionNix {
|
||||
type Receipt = ProvisionNixReceipt;
|
||||
fn description(&self) -> Vec<ActionDescription> {
|
||||
let Self { fetch_nix, create_users_and_group, create_nix_tree, move_unpacked_nix } = &self;
|
||||
|
||||
let mut buf = fetch_nix.description();
|
||||
buf.append(&mut create_users_and_group.description());
|
||||
buf.append(&mut create_nix_tree.description());
|
||||
buf.append(&mut move_unpacked_nix.description());
|
||||
|
||||
buf
|
||||
}
|
||||
|
||||
async fn execute(self) -> Result<Self::Receipt, HarmonicError> {
|
||||
let Self { fetch_nix, create_nix_tree, create_users_and_group, move_unpacked_nix } = self;
|
||||
|
||||
// We fetch nix while doing the rest, then move it over.
|
||||
let fetch_nix_handle = tokio::spawn(async move { fetch_nix.execute().await });
|
||||
|
||||
let create_users_and_group = create_users_and_group.execute().await?;
|
||||
let create_nix_tree = create_nix_tree.execute().await?;
|
||||
|
||||
let fetch_nix = fetch_nix_handle.await??;
|
||||
let move_unpacked_nix = move_unpacked_nix.execute().await?;
|
||||
|
||||
Ok(ProvisionNixReceipt { fetch_nix, create_users_and_group, create_nix_tree, move_unpacked_nix })
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
|
||||
pub struct ProvisionNixReceipt {
|
||||
fetch_nix: FetchNixReceipt,
|
||||
create_users_and_group: CreateUsersAndGroupReceipt,
|
||||
create_nix_tree: CreateNixTreeReceipt,
|
||||
move_unpacked_nix: MoveUnpackedNixReceipt,
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl<'a> Revertable<'a> for ProvisionNixReceipt {
|
||||
fn description(&self) -> Vec<ActionDescription> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn revert(self) -> Result<(), HarmonicError> {
|
||||
todo!();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
use crate::{settings, HarmonicError, InstallSettings};
|
||||
use crate::{HarmonicError, InstallSettings};
|
||||
|
||||
use super::{ActionDescription, ActionReceipt, Actionable, Revertable};
|
||||
use crate::actions::{ActionDescription, ActionReceipt, Actionable, Revertable};
|
||||
|
||||
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
|
||||
pub struct StartNixDaemon {}
|
||||
|
@ -13,6 +13,7 @@ impl StartNixDaemon {
|
|||
|
||||
#[async_trait::async_trait]
|
||||
impl<'a> Actionable<'a> for StartNixDaemon {
|
||||
type Receipt = StartNixDaemonReceipt;
|
||||
fn description(&self) -> Vec<ActionDescription> {
|
||||
vec![
|
||||
ActionDescription::new(
|
||||
|
@ -24,7 +25,7 @@ impl<'a> Actionable<'a> for StartNixDaemon {
|
|||
]
|
||||
}
|
||||
|
||||
async fn execute(self) -> Result<ActionReceipt, HarmonicError> {
|
||||
async fn execute(self) -> Result<Self::Receipt, HarmonicError> {
|
||||
todo!()
|
||||
}
|
||||
}
|
|
@ -1,43 +1,37 @@
|
|||
mod configure_nix;
|
||||
mod configure_nix_daemon_service;
|
||||
mod configure_shell_profile;
|
||||
mod create_directory;
|
||||
mod create_group;
|
||||
mod create_nix_tree;
|
||||
mod create_nix_tree_dirs;
|
||||
mod create_user;
|
||||
mod create_users;
|
||||
mod place_channel_configuration;
|
||||
mod place_nix_configuration;
|
||||
mod setup_default_profile;
|
||||
mod start_nix_daemon;
|
||||
mod start_systemd_service;
|
||||
pub mod base;
|
||||
pub mod meta;
|
||||
|
||||
pub use configure_nix::{ConfigureNix, ConfigureNixReceipt};
|
||||
pub use configure_nix_daemon_service::{
|
||||
use base::{
|
||||
ConfigureNixDaemonService, ConfigureNixDaemonServiceReceipt,
|
||||
};
|
||||
pub use configure_shell_profile::{ConfigureShellProfile, ConfigureShellProfileReceipt};
|
||||
pub use create_directory::{CreateDirectory, CreateDirectoryReceipt};
|
||||
pub use create_group::{CreateGroup, CreateGroupReceipt};
|
||||
pub use create_nix_tree::{CreateNixTree, CreateNixTreeReceipt};
|
||||
pub use create_nix_tree_dirs::{CreateNixTreeDirs, CreateNixTreeDirsReceipt};
|
||||
pub use create_user::{CreateUser, CreateUserReceipt};
|
||||
pub use create_users::{CreateUsers, CreateUsersReceipt};
|
||||
pub use place_channel_configuration::{
|
||||
ConfigureShellProfile, ConfigureShellProfileReceipt,
|
||||
CreateDirectory, CreateDirectoryReceipt,
|
||||
CreateGroup, CreateGroupReceipt,
|
||||
CreateUser, CreateUserReceipt,
|
||||
FetchNix, FetchNixReceipt,
|
||||
MoveUnpackedNix, MoveUnpackedNixReceipt,
|
||||
PlaceChannelConfiguration, PlaceChannelConfigurationReceipt,
|
||||
PlaceNixConfiguration, PlaceNixConfigurationReceipt,
|
||||
SetupDefaultProfile, SetupDefaultProfileReceipt,
|
||||
StartSystemdService, StartSystemdServiceReceipt,
|
||||
};
|
||||
pub use place_nix_configuration::{PlaceNixConfiguration, PlaceNixConfigurationReceipt};
|
||||
pub use setup_default_profile::{SetupDefaultProfile, SetupDefaultProfileReceipt};
|
||||
pub use start_nix_daemon::{StartNixDaemon, StartNixDaemonReceipt};
|
||||
pub use start_systemd_service::{StartSystemdService, StartSystemdServiceReceipt};
|
||||
use meta::{
|
||||
ConfigureNix, ConfigureNixReceipt,
|
||||
CreateNixTree, CreateNixTreeReceipt,
|
||||
CreateNixTreeDirs, CreateNixTreeDirsReceipt,
|
||||
CreateUsersAndGroup, CreateUsersAndGroupReceipt,
|
||||
StartNixDaemon, StartNixDaemonReceipt,
|
||||
};
|
||||
|
||||
|
||||
use crate::HarmonicError;
|
||||
|
||||
use self::meta::{ProvisionNix, ProvisionNixReceipt};
|
||||
|
||||
#[async_trait::async_trait]
|
||||
pub trait Actionable<'a>: serde::de::Deserialize<'a> + serde::Serialize {
|
||||
type Receipt;
|
||||
fn description(&self) -> Vec<ActionDescription>;
|
||||
async fn execute(self) -> Result<ActionReceipt, HarmonicError>;
|
||||
async fn execute(self) -> Result<Self::Receipt, HarmonicError>;
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
|
@ -67,17 +61,20 @@ pub enum Action {
|
|||
ConfigureNixDaemonService(ConfigureNixDaemonService),
|
||||
ConfigureNix(ConfigureNix),
|
||||
ConfigureShellProfile(ConfigureShellProfile),
|
||||
CreateDirectory(CreateUser),
|
||||
CreateDirectory(CreateDirectory),
|
||||
CreateGroup(CreateGroup),
|
||||
CreateNixTreeDirs(CreateNixTreeDirs),
|
||||
CreateNixTree(CreateNixTree),
|
||||
CreateUser(CreateUser),
|
||||
CreateUsers(CreateUsers),
|
||||
CreateUsersAndGroup(CreateUsersAndGroup),
|
||||
FetchNix(FetchNix),
|
||||
MoveUnpackedNix(MoveUnpackedNix),
|
||||
PlaceChannelConfiguration(PlaceChannelConfiguration),
|
||||
PlaceNixConfiguration(PlaceNixConfiguration),
|
||||
SetupDefaultProfile(SetupDefaultProfile),
|
||||
StartNixDaemon(StartNixDaemon),
|
||||
StartSystemdService(StartNixDaemon),
|
||||
StartSystemdService(StartSystemdService),
|
||||
ProvisionNix(ProvisionNix),
|
||||
}
|
||||
|
||||
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
|
||||
|
@ -90,16 +87,20 @@ pub enum ActionReceipt {
|
|||
CreateNixTreeDirs(CreateNixTreeDirsReceipt),
|
||||
CreateNixTree(CreateNixTreeReceipt),
|
||||
CreateUser(CreateUserReceipt),
|
||||
CreateUsers(CreateUsersReceipt),
|
||||
CreateUsersAndGroup(CreateUsersAndGroupReceipt),
|
||||
FetchNix(FetchNixReceipt),
|
||||
MoveUnpackedNix(MoveUnpackedNixReceipt),
|
||||
PlaceChannelConfiguration(PlaceChannelConfigurationReceipt),
|
||||
PlaceNixConfiguration(PlaceNixConfigurationReceipt),
|
||||
SetupDefaultProfile(SetupDefaultProfileReceipt),
|
||||
StartNixDaemon(StartNixDaemonReceipt),
|
||||
StartSystemdService(StartNixDaemonReceipt),
|
||||
StartSystemdService(StartSystemdServiceReceipt),
|
||||
ProvisionNix(ProvisionNixReceipt),
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl<'a> Actionable<'a> for Action {
|
||||
type Receipt = ActionReceipt;
|
||||
fn description(&self) -> Vec<ActionDescription> {
|
||||
match self {
|
||||
Action::ConfigureNixDaemonService(i) => i.description(),
|
||||
|
@ -110,31 +111,37 @@ impl<'a> Actionable<'a> for Action {
|
|||
Action::CreateNixTreeDirs(i) => i.description(),
|
||||
Action::CreateNixTree(i) => i.description(),
|
||||
Action::CreateUser(i) => i.description(),
|
||||
Action::CreateUsers(i) => i.description(),
|
||||
Action::CreateUsersAndGroup(i) => i.description(),
|
||||
Action::FetchNix(i) => i.description(),
|
||||
Action::MoveUnpackedNix(i) => i.description(),
|
||||
Action::PlaceChannelConfiguration(i) => i.description(),
|
||||
Action::PlaceNixConfiguration(i) => i.description(),
|
||||
Action::SetupDefaultProfile(i) => i.description(),
|
||||
Action::StartNixDaemon(i) => i.description(),
|
||||
Action::StartSystemdService(i) => i.description(),
|
||||
Action::ProvisionNix(i) => i.description(),
|
||||
}
|
||||
}
|
||||
|
||||
async fn execute(self) -> Result<ActionReceipt, HarmonicError> {
|
||||
async fn execute(self) -> Result<Self::Receipt, HarmonicError> {
|
||||
match self {
|
||||
Action::ConfigureNixDaemonService(i) => i.execute().await,
|
||||
Action::ConfigureNix(i) => i.execute().await,
|
||||
Action::ConfigureShellProfile(i) => i.execute().await,
|
||||
Action::CreateDirectory(i) => i.execute().await,
|
||||
Action::CreateGroup(i) => i.execute().await,
|
||||
Action::CreateNixTreeDirs(i) => i.execute().await,
|
||||
Action::CreateNixTree(i) => i.execute().await,
|
||||
Action::CreateUser(i) => i.execute().await,
|
||||
Action::CreateUsers(i) => i.execute().await,
|
||||
Action::PlaceChannelConfiguration(i) => i.execute().await,
|
||||
Action::PlaceNixConfiguration(i) => i.execute().await,
|
||||
Action::SetupDefaultProfile(i) => i.execute().await,
|
||||
Action::StartNixDaemon(i) => i.execute().await,
|
||||
Action::StartSystemdService(i) => i.execute().await,
|
||||
Action::ConfigureNixDaemonService(i) => i.execute().await.map(ActionReceipt::ConfigureNixDaemonService),
|
||||
Action::ConfigureNix(i) => i.execute().await.map(ActionReceipt::ConfigureNix),
|
||||
Action::ConfigureShellProfile(i) => i.execute().await.map(ActionReceipt::ConfigureShellProfile),
|
||||
Action::CreateDirectory(i) => i.execute().await.map(ActionReceipt::CreateDirectory),
|
||||
Action::CreateGroup(i) => i.execute().await.map(ActionReceipt::CreateGroup),
|
||||
Action::CreateNixTreeDirs(i) => i.execute().await.map(ActionReceipt::CreateNixTreeDirs),
|
||||
Action::CreateNixTree(i) => i.execute().await.map(ActionReceipt::CreateNixTree),
|
||||
Action::CreateUser(i) => i.execute().await.map(ActionReceipt::CreateUser),
|
||||
Action::CreateUsersAndGroup(i) => i.execute().await.map(ActionReceipt::CreateUsersAndGroup),
|
||||
Action::FetchNix(i) => i.execute().await.map(ActionReceipt::FetchNix),
|
||||
Action::MoveUnpackedNix(i) => i.execute().await.map(ActionReceipt::MoveUnpackedNix),
|
||||
Action::PlaceChannelConfiguration(i) => i.execute().await.map(ActionReceipt::PlaceChannelConfiguration),
|
||||
Action::PlaceNixConfiguration(i) => i.execute().await.map(ActionReceipt::PlaceNixConfiguration),
|
||||
Action::SetupDefaultProfile(i) => i.execute().await.map(ActionReceipt::SetupDefaultProfile),
|
||||
Action::StartNixDaemon(i) => i.execute().await.map(ActionReceipt::StartNixDaemon),
|
||||
Action::StartSystemdService(i) => i.execute().await.map(ActionReceipt::StartSystemdService),
|
||||
Action::ProvisionNix(i) => i.execute().await.map(ActionReceipt::ProvisionNix),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -151,12 +158,15 @@ impl<'a> Revertable<'a> for ActionReceipt {
|
|||
ActionReceipt::CreateNixTreeDirs(i) => i.description(),
|
||||
ActionReceipt::CreateNixTree(i) => i.description(),
|
||||
ActionReceipt::CreateUser(i) => i.description(),
|
||||
ActionReceipt::CreateUsers(i) => i.description(),
|
||||
ActionReceipt::CreateUsersAndGroup(i) => i.description(),
|
||||
ActionReceipt::FetchNix(i) => i.description(),
|
||||
ActionReceipt::MoveUnpackedNix(i) => i.description(),
|
||||
ActionReceipt::PlaceChannelConfiguration(i) => i.description(),
|
||||
ActionReceipt::PlaceNixConfiguration(i) => i.description(),
|
||||
ActionReceipt::SetupDefaultProfile(i) => i.description(),
|
||||
ActionReceipt::StartNixDaemon(i) => i.description(),
|
||||
ActionReceipt::StartSystemdService(i) => i.description(),
|
||||
ActionReceipt::ProvisionNix(i) => i.description(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -170,12 +180,15 @@ impl<'a> Revertable<'a> for ActionReceipt {
|
|||
ActionReceipt::CreateNixTreeDirs(i) => i.revert().await,
|
||||
ActionReceipt::CreateNixTree(i) => i.revert().await,
|
||||
ActionReceipt::CreateUser(i) => i.revert().await,
|
||||
ActionReceipt::CreateUsers(i) => i.revert().await,
|
||||
ActionReceipt::CreateUsersAndGroup(i) => i.revert().await,
|
||||
ActionReceipt::FetchNix(i) => i.revert().await,
|
||||
ActionReceipt::MoveUnpackedNix(i) => i.revert().await,
|
||||
ActionReceipt::PlaceChannelConfiguration(i) => i.revert().await,
|
||||
ActionReceipt::PlaceNixConfiguration(i) => i.revert().await,
|
||||
ActionReceipt::SetupDefaultProfile(i) => i.revert().await,
|
||||
ActionReceipt::StartNixDaemon(i) => i.revert().await,
|
||||
ActionReceipt::StartSystemdService(i) => i.revert().await,
|
||||
ActionReceipt::ProvisionNix(i) => i.revert().await,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
10
src/plan.rs
10
src/plan.rs
|
@ -2,8 +2,12 @@ use serde::{Deserialize, Serialize};
|
|||
|
||||
use crate::{
|
||||
actions::{
|
||||
Action, ActionDescription, ActionReceipt, Actionable, ConfigureNix, CreateNixTree,
|
||||
Revertable, StartNixDaemon,
|
||||
Action, ActionDescription, ActionReceipt, Actionable, Revertable,
|
||||
meta::{
|
||||
ConfigureNix,
|
||||
ProvisionNix,
|
||||
StartNixDaemon,
|
||||
},
|
||||
},
|
||||
settings::InstallSettings,
|
||||
HarmonicError,
|
||||
|
@ -79,7 +83,7 @@ impl InstallPlan {
|
|||
}
|
||||
pub async fn new(settings: InstallSettings) -> Result<Self, HarmonicError> {
|
||||
let actions = vec![
|
||||
Action::CreateNixTree(CreateNixTree::plan(settings.clone())),
|
||||
Action::ProvisionNix(ProvisionNix::plan(settings.clone())?),
|
||||
Action::ConfigureNix(ConfigureNix::plan(settings.clone())),
|
||||
Action::StartNixDaemon(StartNixDaemon::plan(settings.clone())),
|
||||
];
|
||||
|
|
|
@ -10,6 +10,7 @@ pub struct InstallSettings {
|
|||
pub(crate) nix_build_group_id: usize,
|
||||
pub(crate) nix_build_user_prefix: String,
|
||||
pub(crate) nix_build_user_id_base: usize,
|
||||
pub(crate) nix_package_url: Url,
|
||||
}
|
||||
|
||||
impl Default for InstallSettings {
|
||||
|
@ -23,6 +24,7 @@ impl Default for InstallSettings {
|
|||
nix_build_group_id: 3000,
|
||||
nix_build_user_prefix: String::from("nixbld"),
|
||||
nix_build_user_id_base: 3001,
|
||||
nix_package_url: "https://releases.nixos.org/nix/nix-2.11.0/nix-2.11.0-x86_64-linux.tar.xz".parse().expect("Could not parse default Nix archive url, please report this issue")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -67,4 +69,8 @@ impl InstallSettings {
|
|||
self.nix_build_user_id_base = count;
|
||||
self
|
||||
}
|
||||
pub fn nix_package_url(&mut self, url: Url) -> &mut Self {
|
||||
self.nix_package_url = url;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue