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 crate::HarmonicError;
|
||||||
|
|
||||||
use super::{ActionDescription, ActionReceipt, Actionable, Revertable};
|
use crate::actions::{ActionDescription, ActionReceipt, Actionable, Revertable};
|
||||||
|
|
||||||
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
|
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
|
||||||
pub struct ConfigureNixDaemonService {}
|
pub struct ConfigureNixDaemonService {}
|
||||||
|
@ -13,6 +13,7 @@ impl ConfigureNixDaemonService {
|
||||||
|
|
||||||
#[async_trait::async_trait]
|
#[async_trait::async_trait]
|
||||||
impl<'a> Actionable<'a> for ConfigureNixDaemonService {
|
impl<'a> Actionable<'a> for ConfigureNixDaemonService {
|
||||||
|
type Receipt = ConfigureNixDaemonServiceReceipt;
|
||||||
fn description(&self) -> Vec<ActionDescription> {
|
fn description(&self) -> Vec<ActionDescription> {
|
||||||
vec![
|
vec![
|
||||||
ActionDescription::new(
|
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!()
|
todo!()
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::HarmonicError;
|
use crate::HarmonicError;
|
||||||
|
|
||||||
use super::{ActionDescription, ActionReceipt, Actionable, Revertable};
|
use crate::actions::{ActionDescription, ActionReceipt, Actionable, Revertable};
|
||||||
|
|
||||||
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
|
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
|
||||||
pub struct ConfigureShellProfile {}
|
pub struct ConfigureShellProfile {}
|
||||||
|
@ -13,6 +13,7 @@ impl ConfigureShellProfile {
|
||||||
|
|
||||||
#[async_trait::async_trait]
|
#[async_trait::async_trait]
|
||||||
impl<'a> Actionable<'a> for ConfigureShellProfile {
|
impl<'a> Actionable<'a> for ConfigureShellProfile {
|
||||||
|
type Receipt = ConfigureShellProfileReceipt;
|
||||||
fn description(&self) -> Vec<ActionDescription> {
|
fn description(&self) -> Vec<ActionDescription> {
|
||||||
vec![
|
vec![
|
||||||
ActionDescription::new(
|
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!()
|
todo!()
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -5,7 +5,7 @@ use std::{
|
||||||
|
|
||||||
use crate::HarmonicError;
|
use crate::HarmonicError;
|
||||||
|
|
||||||
use super::{ActionDescription, ActionReceipt, Actionable, Revertable};
|
use crate::actions::{ActionDescription, ActionReceipt, Actionable, Revertable};
|
||||||
|
|
||||||
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
|
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
|
||||||
pub struct CreateDirectory {
|
pub struct CreateDirectory {
|
||||||
|
@ -29,6 +29,7 @@ impl CreateDirectory {
|
||||||
|
|
||||||
#[async_trait::async_trait]
|
#[async_trait::async_trait]
|
||||||
impl<'a> Actionable<'a> for CreateDirectory {
|
impl<'a> Actionable<'a> for CreateDirectory {
|
||||||
|
type Receipt = CreateDirectoryReceipt;
|
||||||
fn description(&self) -> Vec<ActionDescription> {
|
fn description(&self) -> Vec<ActionDescription> {
|
||||||
vec![ActionDescription::new(
|
vec![ActionDescription::new(
|
||||||
format!("Create the directory `/nix`"),
|
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 {
|
let Self {
|
||||||
path,
|
path,
|
||||||
user,
|
user,
|
||||||
|
@ -46,12 +47,12 @@ impl<'a> Actionable<'a> for CreateDirectory {
|
||||||
mode,
|
mode,
|
||||||
} = self;
|
} = self;
|
||||||
todo!();
|
todo!();
|
||||||
Ok(ActionReceipt::CreateDirectory(CreateDirectoryReceipt {
|
Ok(CreateDirectoryReceipt {
|
||||||
path,
|
path,
|
||||||
user,
|
user,
|
||||||
group,
|
group,
|
||||||
mode,
|
mode,
|
||||||
}))
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::HarmonicError;
|
use crate::HarmonicError;
|
||||||
|
|
||||||
use super::{ActionDescription, ActionReceipt, Actionable, Revertable};
|
use crate::actions::{ActionDescription, ActionReceipt, Actionable, Revertable};
|
||||||
|
|
||||||
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
|
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
|
||||||
pub struct CreateGroup {
|
pub struct CreateGroup {
|
||||||
|
@ -16,6 +16,7 @@ impl CreateGroup {
|
||||||
|
|
||||||
#[async_trait::async_trait]
|
#[async_trait::async_trait]
|
||||||
impl<'a> Actionable<'a> for CreateGroup {
|
impl<'a> Actionable<'a> for CreateGroup {
|
||||||
|
type Receipt = CreateGroupReceipt;
|
||||||
fn description(&self) -> Vec<ActionDescription> {
|
fn description(&self) -> Vec<ActionDescription> {
|
||||||
let name = &self.name;
|
let name = &self.name;
|
||||||
let uid = &self.uid;
|
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;
|
let Self { name, uid } = self;
|
||||||
Ok(ActionReceipt::CreateGroup(CreateGroupReceipt { name, uid }))
|
Ok(CreateGroupReceipt { name, uid })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::HarmonicError;
|
use crate::HarmonicError;
|
||||||
|
|
||||||
use super::{ActionDescription, ActionReceipt, Actionable, Revertable};
|
use crate::actions::{ActionDescription, ActionReceipt, Actionable, Revertable};
|
||||||
|
|
||||||
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
|
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
|
||||||
pub struct CreateUser {
|
pub struct CreateUser {
|
||||||
|
@ -16,6 +16,7 @@ impl CreateUser {
|
||||||
|
|
||||||
#[async_trait::async_trait]
|
#[async_trait::async_trait]
|
||||||
impl<'a> Actionable<'a> for CreateUser {
|
impl<'a> Actionable<'a> for CreateUser {
|
||||||
|
type Receipt = CreateUserReceipt;
|
||||||
fn description(&self) -> Vec<ActionDescription> {
|
fn description(&self) -> Vec<ActionDescription> {
|
||||||
let name = &self.name;
|
let name = &self.name;
|
||||||
let uid = &self.uid;
|
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;
|
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 crate::HarmonicError;
|
||||||
|
|
||||||
use super::{ActionDescription, ActionReceipt, Actionable, Revertable};
|
use crate::actions::{ActionDescription, ActionReceipt, Actionable, Revertable};
|
||||||
|
|
||||||
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
|
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
|
||||||
pub struct PlaceChannelConfiguration {}
|
pub struct PlaceChannelConfiguration {}
|
||||||
|
@ -13,6 +13,7 @@ impl PlaceChannelConfiguration {
|
||||||
|
|
||||||
#[async_trait::async_trait]
|
#[async_trait::async_trait]
|
||||||
impl<'a> Actionable<'a> for PlaceChannelConfiguration {
|
impl<'a> Actionable<'a> for PlaceChannelConfiguration {
|
||||||
|
type Receipt = PlaceChannelConfigurationReceipt;
|
||||||
fn description(&self) -> Vec<ActionDescription> {
|
fn description(&self) -> Vec<ActionDescription> {
|
||||||
vec![
|
vec![
|
||||||
ActionDescription::new(
|
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!()
|
todo!()
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::HarmonicError;
|
use crate::HarmonicError;
|
||||||
|
|
||||||
use super::{ActionDescription, ActionReceipt, Actionable, Revertable};
|
use crate::actions::{ActionDescription, ActionReceipt, Actionable, Revertable};
|
||||||
|
|
||||||
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
|
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
|
||||||
pub struct PlaceNixConfiguration {}
|
pub struct PlaceNixConfiguration {}
|
||||||
|
@ -13,6 +13,7 @@ impl PlaceNixConfiguration {
|
||||||
|
|
||||||
#[async_trait::async_trait]
|
#[async_trait::async_trait]
|
||||||
impl<'a> Actionable<'a> for PlaceNixConfiguration {
|
impl<'a> Actionable<'a> for PlaceNixConfiguration {
|
||||||
|
type Receipt = PlaceNixConfigurationReceipt;
|
||||||
fn description(&self) -> Vec<ActionDescription> {
|
fn description(&self) -> Vec<ActionDescription> {
|
||||||
vec![
|
vec![
|
||||||
ActionDescription::new(
|
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!()
|
todo!()
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::HarmonicError;
|
use crate::HarmonicError;
|
||||||
|
|
||||||
use super::{ActionDescription, ActionReceipt, Actionable, Revertable};
|
use crate::actions::{ActionDescription, ActionReceipt, Actionable, Revertable};
|
||||||
|
|
||||||
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
|
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
|
||||||
pub struct SetupDefaultProfile {}
|
pub struct SetupDefaultProfile {}
|
||||||
|
@ -13,6 +13,7 @@ impl SetupDefaultProfile {
|
||||||
|
|
||||||
#[async_trait::async_trait]
|
#[async_trait::async_trait]
|
||||||
impl<'a> Actionable<'a> for SetupDefaultProfile {
|
impl<'a> Actionable<'a> for SetupDefaultProfile {
|
||||||
|
type Receipt = SetupDefaultProfileReceipt;
|
||||||
fn description(&self) -> Vec<ActionDescription> {
|
fn description(&self) -> Vec<ActionDescription> {
|
||||||
vec![
|
vec![
|
||||||
ActionDescription::new(
|
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!()
|
todo!()
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::HarmonicError;
|
use crate::HarmonicError;
|
||||||
|
|
||||||
use super::{ActionDescription, ActionReceipt, Actionable, Revertable};
|
use crate::actions::{ActionDescription, ActionReceipt, Actionable, Revertable};
|
||||||
|
|
||||||
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
|
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
|
||||||
pub struct StartSystemdService {}
|
pub struct StartSystemdService {}
|
||||||
|
@ -13,6 +13,7 @@ impl StartSystemdService {
|
||||||
|
|
||||||
#[async_trait::async_trait]
|
#[async_trait::async_trait]
|
||||||
impl<'a> Actionable<'a> for StartSystemdService {
|
impl<'a> Actionable<'a> for StartSystemdService {
|
||||||
|
type Receipt = StartSystemdServiceReceipt;
|
||||||
fn description(&self) -> Vec<ActionDescription> {
|
fn description(&self) -> Vec<ActionDescription> {
|
||||||
vec![
|
vec![
|
||||||
ActionDescription::new(
|
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!()
|
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 crate::{HarmonicError, InstallSettings};
|
||||||
|
|
||||||
use super::{ActionDescription, ActionReceipt, Actionable, Revertable};
|
use crate::actions::{ActionDescription, ActionReceipt, Actionable, Revertable};
|
||||||
|
|
||||||
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
|
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
|
||||||
pub struct ConfigureNix {}
|
pub struct ConfigureNix {}
|
||||||
|
@ -13,18 +13,19 @@ impl ConfigureNix {
|
||||||
|
|
||||||
#[async_trait::async_trait]
|
#[async_trait::async_trait]
|
||||||
impl<'a> Actionable<'a> for ConfigureNix {
|
impl<'a> Actionable<'a> for ConfigureNix {
|
||||||
|
type Receipt = ConfigureNixReceipt;
|
||||||
fn description(&self) -> Vec<ActionDescription> {
|
fn description(&self) -> Vec<ActionDescription> {
|
||||||
vec![
|
vec![
|
||||||
ActionDescription::new(
|
ActionDescription::new(
|
||||||
"Start the systemd Nix daemon".to_string(),
|
"Configure the Nix daemon".to_string(),
|
||||||
vec![
|
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!()
|
todo!()
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::{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)]
|
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
|
||||||
pub struct CreateNixTree {
|
pub struct CreateNixTree {
|
||||||
|
@ -15,6 +15,7 @@ impl CreateNixTree {
|
||||||
|
|
||||||
#[async_trait::async_trait]
|
#[async_trait::async_trait]
|
||||||
impl<'a> Actionable<'a> for CreateNixTree {
|
impl<'a> Actionable<'a> for CreateNixTree {
|
||||||
|
type Receipt = CreateNixTreeReceipt;
|
||||||
fn description(&self) -> Vec<ActionDescription> {
|
fn description(&self) -> Vec<ActionDescription> {
|
||||||
vec![ActionDescription::new(
|
vec![ActionDescription::new(
|
||||||
format!("Create a directory tree in `/nix`"),
|
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;
|
let Self { settings: _ } = self;
|
||||||
Ok(ActionReceipt::CreateNixTree(CreateNixTreeReceipt {}))
|
Ok(CreateNixTreeReceipt {})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::HarmonicError;
|
use crate::HarmonicError;
|
||||||
|
|
||||||
use super::{ActionDescription, ActionReceipt, Actionable, Revertable};
|
use crate::actions::{ActionDescription, ActionReceipt, Actionable, Revertable};
|
||||||
|
|
||||||
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
|
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
|
||||||
pub struct CreateNixTreeDirs {}
|
pub struct CreateNixTreeDirs {}
|
||||||
|
@ -13,6 +13,7 @@ impl CreateNixTreeDirs {
|
||||||
|
|
||||||
#[async_trait::async_trait]
|
#[async_trait::async_trait]
|
||||||
impl<'a> Actionable<'a> for CreateNixTreeDirs {
|
impl<'a> Actionable<'a> for CreateNixTreeDirs {
|
||||||
|
type Receipt = CreateNixTreeDirsReceipt;
|
||||||
fn description(&self) -> Vec<ActionDescription> {
|
fn description(&self) -> Vec<ActionDescription> {
|
||||||
vec![ActionDescription::new(
|
vec![ActionDescription::new(
|
||||||
format!("Create a directory tree in `/nix`"),
|
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;
|
let Self {} = self;
|
||||||
Ok(ActionReceipt::CreateNixTreeDirs(
|
Ok(CreateNixTreeDirsReceipt {})
|
||||||
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)]
|
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
|
||||||
pub struct StartNixDaemon {}
|
pub struct StartNixDaemon {}
|
||||||
|
@ -13,6 +13,7 @@ impl StartNixDaemon {
|
||||||
|
|
||||||
#[async_trait::async_trait]
|
#[async_trait::async_trait]
|
||||||
impl<'a> Actionable<'a> for StartNixDaemon {
|
impl<'a> Actionable<'a> for StartNixDaemon {
|
||||||
|
type Receipt = StartNixDaemonReceipt;
|
||||||
fn description(&self) -> Vec<ActionDescription> {
|
fn description(&self) -> Vec<ActionDescription> {
|
||||||
vec![
|
vec![
|
||||||
ActionDescription::new(
|
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!()
|
todo!()
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,43 +1,37 @@
|
||||||
mod configure_nix;
|
pub mod base;
|
||||||
mod configure_nix_daemon_service;
|
pub mod meta;
|
||||||
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 use configure_nix::{ConfigureNix, ConfigureNixReceipt};
|
use base::{
|
||||||
pub use configure_nix_daemon_service::{
|
|
||||||
ConfigureNixDaemonService, ConfigureNixDaemonServiceReceipt,
|
ConfigureNixDaemonService, ConfigureNixDaemonServiceReceipt,
|
||||||
};
|
ConfigureShellProfile, ConfigureShellProfileReceipt,
|
||||||
pub use configure_shell_profile::{ConfigureShellProfile, ConfigureShellProfileReceipt};
|
CreateDirectory, CreateDirectoryReceipt,
|
||||||
pub use create_directory::{CreateDirectory, CreateDirectoryReceipt};
|
CreateGroup, CreateGroupReceipt,
|
||||||
pub use create_group::{CreateGroup, CreateGroupReceipt};
|
CreateUser, CreateUserReceipt,
|
||||||
pub use create_nix_tree::{CreateNixTree, CreateNixTreeReceipt};
|
FetchNix, FetchNixReceipt,
|
||||||
pub use create_nix_tree_dirs::{CreateNixTreeDirs, CreateNixTreeDirsReceipt};
|
MoveUnpackedNix, MoveUnpackedNixReceipt,
|
||||||
pub use create_user::{CreateUser, CreateUserReceipt};
|
|
||||||
pub use create_users::{CreateUsers, CreateUsersReceipt};
|
|
||||||
pub use place_channel_configuration::{
|
|
||||||
PlaceChannelConfiguration, PlaceChannelConfigurationReceipt,
|
PlaceChannelConfiguration, PlaceChannelConfigurationReceipt,
|
||||||
|
PlaceNixConfiguration, PlaceNixConfigurationReceipt,
|
||||||
|
SetupDefaultProfile, SetupDefaultProfileReceipt,
|
||||||
|
StartSystemdService, StartSystemdServiceReceipt,
|
||||||
};
|
};
|
||||||
pub use place_nix_configuration::{PlaceNixConfiguration, PlaceNixConfigurationReceipt};
|
use meta::{
|
||||||
pub use setup_default_profile::{SetupDefaultProfile, SetupDefaultProfileReceipt};
|
ConfigureNix, ConfigureNixReceipt,
|
||||||
pub use start_nix_daemon::{StartNixDaemon, StartNixDaemonReceipt};
|
CreateNixTree, CreateNixTreeReceipt,
|
||||||
pub use start_systemd_service::{StartSystemdService, StartSystemdServiceReceipt};
|
CreateNixTreeDirs, CreateNixTreeDirsReceipt,
|
||||||
|
CreateUsersAndGroup, CreateUsersAndGroupReceipt,
|
||||||
|
StartNixDaemon, StartNixDaemonReceipt,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
use crate::HarmonicError;
|
use crate::HarmonicError;
|
||||||
|
|
||||||
|
use self::meta::{ProvisionNix, ProvisionNixReceipt};
|
||||||
|
|
||||||
#[async_trait::async_trait]
|
#[async_trait::async_trait]
|
||||||
pub trait Actionable<'a>: serde::de::Deserialize<'a> + serde::Serialize {
|
pub trait Actionable<'a>: serde::de::Deserialize<'a> + serde::Serialize {
|
||||||
|
type Receipt;
|
||||||
fn description(&self) -> Vec<ActionDescription>;
|
fn description(&self) -> Vec<ActionDescription>;
|
||||||
async fn execute(self) -> Result<ActionReceipt, HarmonicError>;
|
async fn execute(self) -> Result<Self::Receipt, HarmonicError>;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait::async_trait]
|
#[async_trait::async_trait]
|
||||||
|
@ -67,17 +61,20 @@ pub enum Action {
|
||||||
ConfigureNixDaemonService(ConfigureNixDaemonService),
|
ConfigureNixDaemonService(ConfigureNixDaemonService),
|
||||||
ConfigureNix(ConfigureNix),
|
ConfigureNix(ConfigureNix),
|
||||||
ConfigureShellProfile(ConfigureShellProfile),
|
ConfigureShellProfile(ConfigureShellProfile),
|
||||||
CreateDirectory(CreateUser),
|
CreateDirectory(CreateDirectory),
|
||||||
CreateGroup(CreateGroup),
|
CreateGroup(CreateGroup),
|
||||||
CreateNixTreeDirs(CreateNixTreeDirs),
|
CreateNixTreeDirs(CreateNixTreeDirs),
|
||||||
CreateNixTree(CreateNixTree),
|
CreateNixTree(CreateNixTree),
|
||||||
CreateUser(CreateUser),
|
CreateUser(CreateUser),
|
||||||
CreateUsers(CreateUsers),
|
CreateUsersAndGroup(CreateUsersAndGroup),
|
||||||
|
FetchNix(FetchNix),
|
||||||
|
MoveUnpackedNix(MoveUnpackedNix),
|
||||||
PlaceChannelConfiguration(PlaceChannelConfiguration),
|
PlaceChannelConfiguration(PlaceChannelConfiguration),
|
||||||
PlaceNixConfiguration(PlaceNixConfiguration),
|
PlaceNixConfiguration(PlaceNixConfiguration),
|
||||||
SetupDefaultProfile(SetupDefaultProfile),
|
SetupDefaultProfile(SetupDefaultProfile),
|
||||||
StartNixDaemon(StartNixDaemon),
|
StartNixDaemon(StartNixDaemon),
|
||||||
StartSystemdService(StartNixDaemon),
|
StartSystemdService(StartSystemdService),
|
||||||
|
ProvisionNix(ProvisionNix),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
|
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
|
||||||
|
@ -90,16 +87,20 @@ pub enum ActionReceipt {
|
||||||
CreateNixTreeDirs(CreateNixTreeDirsReceipt),
|
CreateNixTreeDirs(CreateNixTreeDirsReceipt),
|
||||||
CreateNixTree(CreateNixTreeReceipt),
|
CreateNixTree(CreateNixTreeReceipt),
|
||||||
CreateUser(CreateUserReceipt),
|
CreateUser(CreateUserReceipt),
|
||||||
CreateUsers(CreateUsersReceipt),
|
CreateUsersAndGroup(CreateUsersAndGroupReceipt),
|
||||||
|
FetchNix(FetchNixReceipt),
|
||||||
|
MoveUnpackedNix(MoveUnpackedNixReceipt),
|
||||||
PlaceChannelConfiguration(PlaceChannelConfigurationReceipt),
|
PlaceChannelConfiguration(PlaceChannelConfigurationReceipt),
|
||||||
PlaceNixConfiguration(PlaceNixConfigurationReceipt),
|
PlaceNixConfiguration(PlaceNixConfigurationReceipt),
|
||||||
SetupDefaultProfile(SetupDefaultProfileReceipt),
|
SetupDefaultProfile(SetupDefaultProfileReceipt),
|
||||||
StartNixDaemon(StartNixDaemonReceipt),
|
StartNixDaemon(StartNixDaemonReceipt),
|
||||||
StartSystemdService(StartNixDaemonReceipt),
|
StartSystemdService(StartSystemdServiceReceipt),
|
||||||
|
ProvisionNix(ProvisionNixReceipt),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait::async_trait]
|
#[async_trait::async_trait]
|
||||||
impl<'a> Actionable<'a> for Action {
|
impl<'a> Actionable<'a> for Action {
|
||||||
|
type Receipt = ActionReceipt;
|
||||||
fn description(&self) -> Vec<ActionDescription> {
|
fn description(&self) -> Vec<ActionDescription> {
|
||||||
match self {
|
match self {
|
||||||
Action::ConfigureNixDaemonService(i) => i.description(),
|
Action::ConfigureNixDaemonService(i) => i.description(),
|
||||||
|
@ -110,31 +111,37 @@ impl<'a> Actionable<'a> for Action {
|
||||||
Action::CreateNixTreeDirs(i) => i.description(),
|
Action::CreateNixTreeDirs(i) => i.description(),
|
||||||
Action::CreateNixTree(i) => i.description(),
|
Action::CreateNixTree(i) => i.description(),
|
||||||
Action::CreateUser(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::PlaceChannelConfiguration(i) => i.description(),
|
||||||
Action::PlaceNixConfiguration(i) => i.description(),
|
Action::PlaceNixConfiguration(i) => i.description(),
|
||||||
Action::SetupDefaultProfile(i) => i.description(),
|
Action::SetupDefaultProfile(i) => i.description(),
|
||||||
Action::StartNixDaemon(i) => i.description(),
|
Action::StartNixDaemon(i) => i.description(),
|
||||||
Action::StartSystemdService(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 {
|
match self {
|
||||||
Action::ConfigureNixDaemonService(i) => i.execute().await,
|
Action::ConfigureNixDaemonService(i) => i.execute().await.map(ActionReceipt::ConfigureNixDaemonService),
|
||||||
Action::ConfigureNix(i) => i.execute().await,
|
Action::ConfigureNix(i) => i.execute().await.map(ActionReceipt::ConfigureNix),
|
||||||
Action::ConfigureShellProfile(i) => i.execute().await,
|
Action::ConfigureShellProfile(i) => i.execute().await.map(ActionReceipt::ConfigureShellProfile),
|
||||||
Action::CreateDirectory(i) => i.execute().await,
|
Action::CreateDirectory(i) => i.execute().await.map(ActionReceipt::CreateDirectory),
|
||||||
Action::CreateGroup(i) => i.execute().await,
|
Action::CreateGroup(i) => i.execute().await.map(ActionReceipt::CreateGroup),
|
||||||
Action::CreateNixTreeDirs(i) => i.execute().await,
|
Action::CreateNixTreeDirs(i) => i.execute().await.map(ActionReceipt::CreateNixTreeDirs),
|
||||||
Action::CreateNixTree(i) => i.execute().await,
|
Action::CreateNixTree(i) => i.execute().await.map(ActionReceipt::CreateNixTree),
|
||||||
Action::CreateUser(i) => i.execute().await,
|
Action::CreateUser(i) => i.execute().await.map(ActionReceipt::CreateUser),
|
||||||
Action::CreateUsers(i) => i.execute().await,
|
Action::CreateUsersAndGroup(i) => i.execute().await.map(ActionReceipt::CreateUsersAndGroup),
|
||||||
Action::PlaceChannelConfiguration(i) => i.execute().await,
|
Action::FetchNix(i) => i.execute().await.map(ActionReceipt::FetchNix),
|
||||||
Action::PlaceNixConfiguration(i) => i.execute().await,
|
Action::MoveUnpackedNix(i) => i.execute().await.map(ActionReceipt::MoveUnpackedNix),
|
||||||
Action::SetupDefaultProfile(i) => i.execute().await,
|
Action::PlaceChannelConfiguration(i) => i.execute().await.map(ActionReceipt::PlaceChannelConfiguration),
|
||||||
Action::StartNixDaemon(i) => i.execute().await,
|
Action::PlaceNixConfiguration(i) => i.execute().await.map(ActionReceipt::PlaceNixConfiguration),
|
||||||
Action::StartSystemdService(i) => i.execute().await,
|
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::CreateNixTreeDirs(i) => i.description(),
|
||||||
ActionReceipt::CreateNixTree(i) => i.description(),
|
ActionReceipt::CreateNixTree(i) => i.description(),
|
||||||
ActionReceipt::CreateUser(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::PlaceChannelConfiguration(i) => i.description(),
|
||||||
ActionReceipt::PlaceNixConfiguration(i) => i.description(),
|
ActionReceipt::PlaceNixConfiguration(i) => i.description(),
|
||||||
ActionReceipt::SetupDefaultProfile(i) => i.description(),
|
ActionReceipt::SetupDefaultProfile(i) => i.description(),
|
||||||
ActionReceipt::StartNixDaemon(i) => i.description(),
|
ActionReceipt::StartNixDaemon(i) => i.description(),
|
||||||
ActionReceipt::StartSystemdService(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::CreateNixTreeDirs(i) => i.revert().await,
|
||||||
ActionReceipt::CreateNixTree(i) => i.revert().await,
|
ActionReceipt::CreateNixTree(i) => i.revert().await,
|
||||||
ActionReceipt::CreateUser(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::PlaceChannelConfiguration(i) => i.revert().await,
|
||||||
ActionReceipt::PlaceNixConfiguration(i) => i.revert().await,
|
ActionReceipt::PlaceNixConfiguration(i) => i.revert().await,
|
||||||
ActionReceipt::SetupDefaultProfile(i) => i.revert().await,
|
ActionReceipt::SetupDefaultProfile(i) => i.revert().await,
|
||||||
ActionReceipt::StartNixDaemon(i) => i.revert().await,
|
ActionReceipt::StartNixDaemon(i) => i.revert().await,
|
||||||
ActionReceipt::StartSystemdService(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::{
|
use crate::{
|
||||||
actions::{
|
actions::{
|
||||||
Action, ActionDescription, ActionReceipt, Actionable, ConfigureNix, CreateNixTree,
|
Action, ActionDescription, ActionReceipt, Actionable, Revertable,
|
||||||
Revertable, StartNixDaemon,
|
meta::{
|
||||||
|
ConfigureNix,
|
||||||
|
ProvisionNix,
|
||||||
|
StartNixDaemon,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
settings::InstallSettings,
|
settings::InstallSettings,
|
||||||
HarmonicError,
|
HarmonicError,
|
||||||
|
@ -79,7 +83,7 @@ impl InstallPlan {
|
||||||
}
|
}
|
||||||
pub async fn new(settings: InstallSettings) -> Result<Self, HarmonicError> {
|
pub async fn new(settings: InstallSettings) -> Result<Self, HarmonicError> {
|
||||||
let actions = vec![
|
let actions = vec![
|
||||||
Action::CreateNixTree(CreateNixTree::plan(settings.clone())),
|
Action::ProvisionNix(ProvisionNix::plan(settings.clone())?),
|
||||||
Action::ConfigureNix(ConfigureNix::plan(settings.clone())),
|
Action::ConfigureNix(ConfigureNix::plan(settings.clone())),
|
||||||
Action::StartNixDaemon(StartNixDaemon::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_group_id: usize,
|
||||||
pub(crate) nix_build_user_prefix: String,
|
pub(crate) nix_build_user_prefix: String,
|
||||||
pub(crate) nix_build_user_id_base: usize,
|
pub(crate) nix_build_user_id_base: usize,
|
||||||
|
pub(crate) nix_package_url: Url,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for InstallSettings {
|
impl Default for InstallSettings {
|
||||||
|
@ -23,6 +24,7 @@ impl Default for InstallSettings {
|
||||||
nix_build_group_id: 3000,
|
nix_build_group_id: 3000,
|
||||||
nix_build_user_prefix: String::from("nixbld"),
|
nix_build_user_prefix: String::from("nixbld"),
|
||||||
nix_build_user_id_base: 3001,
|
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.nix_build_user_id_base = count;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
pub fn nix_package_url(&mut self, url: Url) -> &mut Self {
|
||||||
|
self.nix_package_url = url;
|
||||||
|
self
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue