Tidy up some planner api

Signed-off-by: Ana Hobden <operator@hoverbear.org>
This commit is contained in:
Ana Hobden 2022-10-26 09:27:50 -07:00
parent 16acc1fe6c
commit 706af47714
10 changed files with 65 additions and 30 deletions

View file

@ -1,7 +1,7 @@
use reqwest::Url; use reqwest::Url;
use serde::Serialize; use serde::Serialize;
use crate::InstallSettings; use crate::CommonSettings;
use crate::{ use crate::{
actions::{ actions::{
base::{ base::{
@ -31,7 +31,7 @@ pub struct ConfigureNix {
impl ConfigureNix { impl ConfigureNix {
#[tracing::instrument(skip_all)] #[tracing::instrument(skip_all)]
pub async fn plan(settings: InstallSettings) -> Result<Self, ConfigureNixError> { pub async fn plan(settings: CommonSettings) -> Result<Self, ConfigureNixError> {
let channels: Vec<(String, Url)> = settings let channels: Vec<(String, Url)> = settings
.channels .channels
.iter() .iter()

View file

@ -1,7 +1,7 @@
use serde::Serialize; use serde::Serialize;
use tokio::task::{JoinError, JoinSet}; use tokio::task::{JoinError, JoinSet};
use crate::InstallSettings; use crate::CommonSettings;
use crate::actions::base::{CreateGroup, CreateGroupError, CreateUserError}; use crate::actions::base::{CreateGroup, CreateGroupError, CreateUserError};
use crate::actions::{Action, ActionDescription, ActionState, Actionable, CreateUser}; use crate::actions::{Action, ActionDescription, ActionState, Actionable, CreateUser};
@ -20,7 +20,7 @@ pub struct CreateUsersAndGroup {
impl CreateUsersAndGroup { impl CreateUsersAndGroup {
#[tracing::instrument(skip_all)] #[tracing::instrument(skip_all)]
pub async fn plan(settings: InstallSettings) -> Result<Self, CreateUsersAndGroupError> { pub async fn plan(settings: CommonSettings) -> Result<Self, CreateUsersAndGroupError> {
// TODO(@hoverbear): CHeck if it exist, error if so // TODO(@hoverbear): CHeck if it exist, error if so
let create_group = CreateGroup::plan( let create_group = CreateGroup::plan(
settings.nix_build_group_name.clone(), settings.nix_build_group_name.clone(),

View file

@ -6,7 +6,7 @@ use tokio::task::JoinError;
use crate::actions::base::{ use crate::actions::base::{
CreateDirectoryError, FetchNix, FetchNixError, MoveUnpackedNix, MoveUnpackedNixError, CreateDirectoryError, FetchNix, FetchNixError, MoveUnpackedNix, MoveUnpackedNixError,
}; };
use crate::InstallSettings; use crate::CommonSettings;
use crate::actions::{Action, ActionDescription, ActionState, Actionable}; use crate::actions::{Action, ActionDescription, ActionState, Actionable};
@ -23,7 +23,7 @@ pub struct ProvisionNix {
impl ProvisionNix { impl ProvisionNix {
#[tracing::instrument(skip_all)] #[tracing::instrument(skip_all)]
pub async fn plan(settings: InstallSettings) -> Result<Self, ProvisionNixError> { pub async fn plan(settings: CommonSettings) -> Result<Self, ProvisionNixError> {
let fetch_nix = FetchNix::plan( let fetch_nix = FetchNix::plan(
settings.nix_package_url.clone(), settings.nix_package_url.clone(),
PathBuf::from("/nix/temp-install-dir"), PathBuf::from("/nix/temp-install-dir"),

View file

@ -25,7 +25,7 @@ impl CommandExecute for Plan {
let planner = match planner { let planner = match planner {
Some(planner) => planner, Some(planner) => planner,
None => BuiltinPlanner::default()?, None => BuiltinPlanner::default().await?,
}; };
let install_plan = planner.plan().await?; let install_plan = planner.plan().await?;

View file

@ -13,7 +13,7 @@ pub use error::HarmonicError;
pub use plan::InstallPlan; pub use plan::InstallPlan;
pub use planner::BuiltinPlanner; pub use planner::BuiltinPlanner;
use serde::Serializer; use serde::Serializer;
pub use settings::InstallSettings; pub use settings::CommonSettings;
use tokio::process::Command; use tokio::process::Command;

View file

@ -1,5 +1,6 @@
use std::io::Cursor; use std::io::Cursor;
use clap::ArgAction;
use tokio::process::Command; use tokio::process::Command;
use crate::{ use crate::{
@ -11,13 +12,34 @@ use crate::{
execute_command, execute_command,
os::darwin::DiskUtilOutput, os::darwin::DiskUtilOutput,
planner::{Plannable, PlannerError}, planner::{Plannable, PlannerError},
BuiltinPlanner, InstallPlan, InstallSettings, BuiltinPlanner, CommonSettings, InstallPlan,
}; };
#[derive(Debug, Clone, clap::Parser, serde::Serialize, serde::Deserialize)] #[derive(Debug, Clone, clap::Parser, serde::Serialize, serde::Deserialize)]
pub struct DarwinMulti { pub struct DarwinMulti {
#[clap(flatten)] #[clap(flatten)]
settings: InstallSettings, settings: CommonSettings,
#[clap(
long,
action(ArgAction::SetTrue),
default_value = "false",
env = "HARMONIC_VOLUME_ENCRYPT"
)]
volume_encrypt: bool,
#[clap(long, default_value = "Nix Store", env = "HARMONIC_VOLUME_LABEL")]
volume_label: String,
#[clap(long, env = "HARMONIC_ROOT_DISK")]
root_disk: Option<String>,
}
async fn default_root_disk() -> Result<String, PlannerError> {
let buf = execute_command(Command::new("/usr/sbin/diskutil").args(["info", "-plist", "/"]))
.await
.unwrap()
.stdout;
let the_plist: DiskUtilOutput = plist::from_reader(Cursor::new(buf))?;
Ok(the_plist.parent_whole_disk)
} }
#[async_trait::async_trait] #[async_trait::async_trait]
@ -25,9 +47,12 @@ impl Plannable for DarwinMulti {
const DISPLAY_STRING: &'static str = "Darwin Multi-User"; const DISPLAY_STRING: &'static str = "Darwin Multi-User";
const SLUG: &'static str = "darwin-multi"; const SLUG: &'static str = "darwin-multi";
fn default() -> Result<Self, PlannerError> { async fn default() -> Result<Self, PlannerError> {
Ok(Self { Ok(Self {
settings: InstallSettings::default()?, settings: CommonSettings::default()?,
root_disk: Some(default_root_disk().await?),
volume_encrypt: false,
volume_label: "Nix Store".into(),
}) })
} }

View file

@ -5,13 +5,13 @@ use crate::{
Action, ActionError, Action, ActionError,
}, },
planner::{Plannable, PlannerError}, planner::{Plannable, PlannerError},
BuiltinPlanner, InstallPlan, InstallSettings, BuiltinPlanner, CommonSettings, InstallPlan,
}; };
#[derive(Debug, Clone, clap::Parser, serde::Serialize, serde::Deserialize)] #[derive(Debug, Clone, clap::Parser, serde::Serialize, serde::Deserialize)]
pub struct LinuxMulti { pub struct LinuxMulti {
#[clap(flatten)] #[clap(flatten)]
settings: InstallSettings, settings: CommonSettings,
} }
#[async_trait::async_trait] #[async_trait::async_trait]
@ -19,9 +19,9 @@ impl Plannable for LinuxMulti {
const DISPLAY_STRING: &'static str = "Linux Multi-User"; const DISPLAY_STRING: &'static str = "Linux Multi-User";
const SLUG: &'static str = "linux-multi"; const SLUG: &'static str = "linux-multi";
fn default() -> Result<Self, PlannerError> { async fn default() -> Result<Self, PlannerError> {
Ok(Self { Ok(Self {
settings: InstallSettings::default()?, settings: CommonSettings::default()?,
}) })
} }

View file

@ -12,22 +12,22 @@ pub enum BuiltinPlanner {
} }
impl BuiltinPlanner { impl BuiltinPlanner {
pub fn default() -> Result<Self, PlannerError> { pub async fn default() -> Result<Self, PlannerError> {
use target_lexicon::{Architecture, OperatingSystem}; use target_lexicon::{Architecture, OperatingSystem};
match (Architecture::host(), OperatingSystem::host()) { match (Architecture::host(), OperatingSystem::host()) {
(Architecture::X86_64, OperatingSystem::Linux) => { (Architecture::X86_64, OperatingSystem::Linux) => {
Ok(Self::LinuxMulti(linux::LinuxMulti::default()?)) Ok(Self::LinuxMulti(linux::LinuxMulti::default().await?))
}, },
(Architecture::Aarch64(_), OperatingSystem::Linux) => { (Architecture::Aarch64(_), OperatingSystem::Linux) => {
Ok(Self::LinuxMulti(linux::LinuxMulti::default()?)) Ok(Self::LinuxMulti(linux::LinuxMulti::default().await?))
}, },
(Architecture::X86_64, OperatingSystem::MacOSX { .. }) (Architecture::X86_64, OperatingSystem::MacOSX { .. })
| (Architecture::X86_64, OperatingSystem::Darwin) => { | (Architecture::X86_64, OperatingSystem::Darwin) => {
Ok(Self::DarwinMulti(darwin::DarwinMulti::default()?)) Ok(Self::DarwinMulti(darwin::DarwinMulti::default().await?))
}, },
(Architecture::Aarch64(_), OperatingSystem::MacOSX { .. }) (Architecture::Aarch64(_), OperatingSystem::MacOSX { .. })
| (Architecture::Aarch64(_), OperatingSystem::Darwin) => { | (Architecture::Aarch64(_), OperatingSystem::Darwin) => {
Ok(Self::DarwinMulti(darwin::DarwinMulti::default()?)) Ok(Self::DarwinMulti(darwin::DarwinMulti::default().await?))
}, },
_ => Err(PlannerError::UnsupportedArchitecture(target_lexicon::HOST)), _ => Err(PlannerError::UnsupportedArchitecture(target_lexicon::HOST)),
} }
@ -50,7 +50,7 @@ where
const DISPLAY_STRING: &'static str; const DISPLAY_STRING: &'static str;
const SLUG: &'static str; const SLUG: &'static str;
fn default() -> Result<Self, PlannerError>; async fn default() -> Result<Self, PlannerError>;
async fn plan(self) -> Result<InstallPlan, PlannerError>; async fn plan(self) -> Result<InstallPlan, PlannerError>;
} }
@ -66,4 +66,6 @@ pub enum PlannerError {
), ),
#[error(transparent)] #[error(transparent)]
InstallSettings(#[from] InstallSettingsError), InstallSettings(#[from] InstallSettingsError),
#[error(transparent)]
Plist(#[from] plist::Error),
} }

View file

@ -5,13 +5,13 @@ use crate::{
Action, ActionError, Action, ActionError,
}, },
planner::{Plannable, PlannerError}, planner::{Plannable, PlannerError},
BuiltinPlanner, InstallPlan, InstallSettings, BuiltinPlanner, CommonSettings, InstallPlan,
}; };
#[derive(Debug, Clone, clap::Parser, serde::Serialize, serde::Deserialize)] #[derive(Debug, Clone, clap::Parser, serde::Serialize, serde::Deserialize)]
pub struct SteamDeck { pub struct SteamDeck {
#[clap(flatten)] #[clap(flatten)]
settings: InstallSettings, settings: CommonSettings,
} }
#[async_trait::async_trait] #[async_trait::async_trait]
@ -19,9 +19,9 @@ impl Plannable for SteamDeck {
const DISPLAY_STRING: &'static str = "Steam Deck (x86_64 Linux Multi-User)"; const DISPLAY_STRING: &'static str = "Steam Deck (x86_64 Linux Multi-User)";
const SLUG: &'static str = "steam-deck"; const SLUG: &'static str = "steam-deck";
fn default() -> Result<Self, PlannerError> { async fn default() -> Result<Self, PlannerError> {
Ok(Self { Ok(Self {
settings: InstallSettings::default()?, settings: CommonSettings::default()?,
}) })
} }

View file

@ -1,5 +1,4 @@
use clap::ArgAction; use clap::ArgAction;
use derivative::Derivative;
use url::Url; use url::Url;
pub const NIX_X64_64_LINUX_URL: &str = pub const NIX_X64_64_LINUX_URL: &str =
@ -13,7 +12,7 @@ pub const NIX_AARCH64_DARWIN_URL: &str =
#[serde_with::serde_as] #[serde_with::serde_as]
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone, clap::Parser)] #[derive(Debug, serde::Deserialize, serde::Serialize, Clone, clap::Parser)]
pub struct InstallSettings { pub struct CommonSettings {
/// Channel(s) to add by default, pass multiple times for multiple channels /// Channel(s) to add by default, pass multiple times for multiple channels
#[clap( #[clap(
long, long,
@ -24,6 +23,7 @@ pub struct InstallSettings {
default_value = "nixpkgs=https://nixos.org/channels/nixpkgs-unstable", default_value = "nixpkgs=https://nixos.org/channels/nixpkgs-unstable",
)] )]
pub(crate) channels: Vec<crate::cli::arg::ChannelValue>, pub(crate) channels: Vec<crate::cli::arg::ChannelValue>,
/// Modify the user profile to automatically load nix /// Modify the user profile to automatically load nix
#[clap( #[clap(
long, long,
@ -34,21 +34,27 @@ pub struct InstallSettings {
name = "no-modify-profile" name = "no-modify-profile"
)] )]
pub(crate) modify_profile: bool, pub(crate) modify_profile: bool,
/// Number of build users to create /// Number of build users to create
#[clap(long, default_value = "32", env = "HARMONIC_DAEMON_USER_COUNT")] #[clap(long, default_value = "32", env = "HARMONIC_DAEMON_USER_COUNT")]
pub(crate) daemon_user_count: usize, pub(crate) daemon_user_count: usize,
#[clap(long, default_value = "nixbld", env = "HARMONIC_NIX_BUILD_GROUP_NAME")] #[clap(long, default_value = "nixbld", env = "HARMONIC_NIX_BUILD_GROUP_NAME")]
pub(crate) nix_build_group_name: String, pub(crate) nix_build_group_name: String,
#[clap(long, default_value_t = 3000, env = "HARMONIC_NIX_BUILD_GROUP_ID")] #[clap(long, default_value_t = 3000, env = "HARMONIC_NIX_BUILD_GROUP_ID")]
pub(crate) nix_build_group_id: usize, pub(crate) nix_build_group_id: usize,
#[clap(long, env = "HARMONIC_NIX_BUILD_USER_PREFIX")] #[clap(long, env = "HARMONIC_NIX_BUILD_USER_PREFIX")]
#[cfg_attr(target_os = "macos", clap(default_value = "_nixbld"))] #[cfg_attr(target_os = "macos", clap(default_value = "_nixbld"))]
#[cfg_attr(target_os = "linux", clap(default_value = "nixbld"))] #[cfg_attr(target_os = "linux", clap(default_value = "nixbld"))]
pub(crate) nix_build_user_prefix: String, pub(crate) nix_build_user_prefix: String,
#[clap(long, env = "HARMONIC_NIX_BUILD_USER_ID_BASE")] #[clap(long, env = "HARMONIC_NIX_BUILD_USER_ID_BASE")]
#[cfg_attr(target_os = "macos", clap(default_value_t = 300))] #[cfg_attr(target_os = "macos", clap(default_value_t = 300))]
#[cfg_attr(target_os = "linux", clap(default_value_t = 3000))] #[cfg_attr(target_os = "linux", clap(default_value_t = 3000))]
pub(crate) nix_build_user_id_base: usize, pub(crate) nix_build_user_id_base: usize,
#[clap(long, env = "HARMONIC_NIX_PACKAGE_URL")] #[clap(long, env = "HARMONIC_NIX_PACKAGE_URL")]
#[cfg_attr( #[cfg_attr(
all(target_os = "macos", target_arch = "x86_64"), all(target_os = "macos", target_arch = "x86_64"),
@ -75,8 +81,10 @@ pub struct InstallSettings {
) )
)] )]
pub(crate) nix_package_url: Url, pub(crate) nix_package_url: Url,
#[clap(long, env = "HARMONIC_EXTRA_CONF")] #[clap(long, env = "HARMONIC_EXTRA_CONF")]
pub(crate) extra_conf: Option<String>, pub(crate) extra_conf: Option<String>,
#[clap( #[clap(
long, long,
action(ArgAction::SetTrue), action(ArgAction::SetTrue),
@ -87,7 +95,7 @@ pub struct InstallSettings {
pub(crate) force: bool, pub(crate) force: bool,
} }
impl InstallSettings { impl CommonSettings {
pub fn default() -> Result<Self, InstallSettingsError> { pub fn default() -> Result<Self, InstallSettingsError> {
let url; let url;
let nix_build_user_prefix; let nix_build_user_prefix;
@ -140,7 +148,7 @@ impl InstallSettings {
} }
// Builder Pattern // Builder Pattern
impl InstallSettings { impl CommonSettings {
pub fn daemon_user_count(&mut self, count: usize) -> &mut Self { pub fn daemon_user_count(&mut self, count: usize) -> &mut Self {
self.daemon_user_count = count; self.daemon_user_count = count;
self self