forked from lix-project/lix-installer
Rework planners to support custom args
This commit is contained in:
parent
b920b384d3
commit
16acc1fe6c
|
@ -69,13 +69,13 @@ impl Actionable for CreateDirectory {
|
|||
fn describe_execute(&self) -> Vec<ActionDescription> {
|
||||
let Self {
|
||||
path,
|
||||
user,
|
||||
group,
|
||||
mode,
|
||||
user: _,
|
||||
group: _,
|
||||
mode: _,
|
||||
force_prune_on_revert: _,
|
||||
action_state: _,
|
||||
action_state,
|
||||
} = &self;
|
||||
if self.action_state == ActionState::Completed {
|
||||
if *action_state == ActionState::Completed {
|
||||
vec![]
|
||||
} else {
|
||||
vec![ActionDescription::new(
|
||||
|
|
|
@ -56,10 +56,10 @@ impl Actionable for CreateFile {
|
|||
fn describe_execute(&self) -> Vec<ActionDescription> {
|
||||
let Self {
|
||||
path,
|
||||
user,
|
||||
group,
|
||||
mode,
|
||||
buf,
|
||||
user: _,
|
||||
group: _,
|
||||
mode: _,
|
||||
buf: _,
|
||||
force: _,
|
||||
action_state: _,
|
||||
} = &self;
|
||||
|
|
|
@ -53,10 +53,10 @@ impl Actionable for CreateOrAppendFile {
|
|||
fn describe_execute(&self) -> Vec<ActionDescription> {
|
||||
let Self {
|
||||
path,
|
||||
user,
|
||||
group,
|
||||
mode,
|
||||
buf,
|
||||
user: _,
|
||||
group: _,
|
||||
mode: _,
|
||||
buf: _,
|
||||
action_state: _,
|
||||
} = &self;
|
||||
if self.action_state == ActionState::Completed {
|
||||
|
|
|
@ -110,7 +110,7 @@ impl Actionable for CreateVolume {
|
|||
))]
|
||||
async fn revert(&mut self) -> Result<(), Self::Error> {
|
||||
let Self {
|
||||
disk,
|
||||
disk: _,
|
||||
name,
|
||||
case_sensitive: _,
|
||||
action_state,
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
use serde::Serialize;
|
||||
use std::path::{Path, PathBuf};
|
||||
use tokio::process::Command;
|
||||
|
||||
use crate::execute_command;
|
||||
|
||||
use crate::actions::{Action, ActionDescription, ActionState, Actionable};
|
||||
|
||||
|
@ -47,8 +44,8 @@ impl Actionable for EncryptVolume {
|
|||
))]
|
||||
async fn execute(&mut self) -> Result<(), Self::Error> {
|
||||
let Self {
|
||||
disk,
|
||||
password,
|
||||
disk: _,
|
||||
password: _,
|
||||
action_state,
|
||||
} = self;
|
||||
if *action_state == ActionState::Completed {
|
||||
|
@ -77,8 +74,8 @@ impl Actionable for EncryptVolume {
|
|||
))]
|
||||
async fn revert(&mut self) -> Result<(), Self::Error> {
|
||||
let Self {
|
||||
disk,
|
||||
password,
|
||||
disk: _,
|
||||
password: _,
|
||||
action_state,
|
||||
} = self;
|
||||
if *action_state == ActionState::Uncompleted {
|
||||
|
|
|
@ -49,7 +49,7 @@ impl Actionable for UnmountVolume {
|
|||
))]
|
||||
async fn execute(&mut self) -> Result<(), Self::Error> {
|
||||
let Self {
|
||||
disk,
|
||||
disk: _,
|
||||
name,
|
||||
action_state,
|
||||
} = self;
|
||||
|
@ -91,7 +91,7 @@ impl Actionable for UnmountVolume {
|
|||
))]
|
||||
async fn revert(&mut self) -> Result<(), Self::Error> {
|
||||
let Self {
|
||||
disk,
|
||||
disk: _,
|
||||
name,
|
||||
action_state,
|
||||
} = self;
|
||||
|
|
|
@ -1,17 +1,21 @@
|
|||
use reqwest::Url;
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::actions::{
|
||||
base::{
|
||||
ConfigureNixDaemonService, ConfigureNixDaemonServiceError, SetupDefaultProfile,
|
||||
SetupDefaultProfileError,
|
||||
},
|
||||
meta::{
|
||||
ConfigureShellProfile, ConfigureShellProfileError, PlaceChannelConfiguration,
|
||||
PlaceChannelConfigurationError, PlaceNixConfiguration, PlaceNixConfigurationError,
|
||||
},
|
||||
Action, ActionState,
|
||||
};
|
||||
use crate::InstallSettings;
|
||||
use crate::{
|
||||
actions::{
|
||||
base::{
|
||||
ConfigureNixDaemonService, ConfigureNixDaemonServiceError, SetupDefaultProfile,
|
||||
SetupDefaultProfileError,
|
||||
},
|
||||
meta::{
|
||||
ConfigureShellProfile, ConfigureShellProfileError, PlaceChannelConfiguration,
|
||||
PlaceChannelConfigurationError, PlaceNixConfiguration, PlaceNixConfigurationError,
|
||||
},
|
||||
Action, ActionState,
|
||||
},
|
||||
cli::arg::ChannelValue,
|
||||
};
|
||||
|
||||
use crate::actions::{ActionDescription, Actionable};
|
||||
|
||||
|
@ -28,13 +32,14 @@ pub struct ConfigureNix {
|
|||
impl ConfigureNix {
|
||||
#[tracing::instrument(skip_all)]
|
||||
pub async fn plan(settings: InstallSettings) -> Result<Self, ConfigureNixError> {
|
||||
let channels = settings
|
||||
let channels: Vec<(String, Url)> = settings
|
||||
.channels
|
||||
.iter()
|
||||
.map(|(channel, _)| channel.to_string())
|
||||
.map(|ChannelValue(channel, url)| (channel.to_string(), url.clone()))
|
||||
.collect();
|
||||
|
||||
let setup_default_profile = SetupDefaultProfile::plan(channels).await?;
|
||||
let setup_default_profile =
|
||||
SetupDefaultProfile::plan(channels.iter().map(|(v, _k)| v.clone()).collect()).await?;
|
||||
|
||||
let configure_shell_profile = if settings.modify_profile {
|
||||
Some(ConfigureShellProfile::plan().await?)
|
||||
|
@ -42,7 +47,7 @@ impl ConfigureNix {
|
|||
None
|
||||
};
|
||||
let place_channel_configuration =
|
||||
PlaceChannelConfiguration::plan(settings.channels, settings.force).await?;
|
||||
PlaceChannelConfiguration::plan(channels, settings.force).await?;
|
||||
let place_nix_configuration = PlaceNixConfiguration::plan(
|
||||
settings.nix_build_group_name,
|
||||
settings.extra_conf,
|
||||
|
|
|
@ -5,19 +5,15 @@ use std::{
|
|||
};
|
||||
use tokio::process::Command;
|
||||
|
||||
use crate::actions::{base::darwin, Action, ActionDescription, ActionState, Actionable};
|
||||
use crate::{
|
||||
actions::base::{
|
||||
darwin::{
|
||||
BootstrapVolume, BootstrapVolumeError, CreateSyntheticObjects,
|
||||
CreateSyntheticObjectsError, CreateVolume, CreateVolumeError, EnableOwnership,
|
||||
EnableOwnershipError, EncryptVolume, EncryptVolumeError, UnmountVolume,
|
||||
UnmountVolumeError,
|
||||
},
|
||||
CreateFile, CreateFileError, CreateOrAppendFile, CreateOrAppendFileError,
|
||||
use crate::actions::base::{
|
||||
darwin::{
|
||||
BootstrapVolume, BootstrapVolumeError, CreateSyntheticObjects, CreateSyntheticObjectsError,
|
||||
CreateVolume, CreateVolumeError, EnableOwnership, EnableOwnershipError, EncryptVolume,
|
||||
EncryptVolumeError, UnmountVolume, UnmountVolumeError,
|
||||
},
|
||||
execute_command,
|
||||
CreateFile, CreateFileError, CreateOrAppendFile, CreateOrAppendFileError,
|
||||
};
|
||||
use crate::actions::{Action, ActionDescription, ActionState, Actionable};
|
||||
|
||||
const NIX_VOLUME_MOUNTD_DEST: &str = "/Library/LaunchDaemons/org.nixos.darwin-store.plist";
|
||||
|
||||
|
|
|
@ -4,8 +4,7 @@ use serde::Serialize;
|
|||
use tokio::task::JoinError;
|
||||
|
||||
use crate::actions::base::{
|
||||
CreateDirectory, CreateDirectoryError, FetchNix, FetchNixError, MoveUnpackedNix,
|
||||
MoveUnpackedNixError,
|
||||
CreateDirectoryError, FetchNix, FetchNixError, MoveUnpackedNix, MoveUnpackedNixError,
|
||||
};
|
||||
use crate::InstallSettings;
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use reqwest::Url;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct ChannelValue(pub String, pub Url);
|
||||
|
||||
impl clap::builder::ValueParserFactory for ChannelValue {
|
||||
|
@ -10,6 +11,12 @@ impl clap::builder::ValueParserFactory for ChannelValue {
|
|||
}
|
||||
}
|
||||
|
||||
impl From<(String, Url)> for ChannelValue {
|
||||
fn from((string, url): (String, Url)) -> Self {
|
||||
Self(string, url)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct ChannelValueParser;
|
||||
impl clap::builder::TypedValueParser for ChannelValueParser {
|
||||
|
|
|
@ -9,11 +9,11 @@ use valuable::Valuable;
|
|||
pub struct Instrumentation {
|
||||
/// Enable debug logs, -vv for trace
|
||||
#[clap(short = 'v', long, action = clap::ArgAction::Count, global = true)]
|
||||
pub(crate) verbose: u8,
|
||||
pub verbose: u8,
|
||||
}
|
||||
|
||||
impl<'a> Instrumentation {
|
||||
pub(crate) fn log_level(&self) -> String {
|
||||
pub fn log_level(&self) -> String {
|
||||
match self.verbose {
|
||||
0 => "info",
|
||||
1 => "debug",
|
||||
|
@ -22,7 +22,7 @@ impl<'a> Instrumentation {
|
|||
.to_string()
|
||||
}
|
||||
|
||||
pub(crate) fn setup<'b: 'a>(&'b self) -> eyre::Result<()> {
|
||||
pub fn setup<'b: 'a>(&'b self) -> eyre::Result<()> {
|
||||
let fmt_layer = self.fmt_layer();
|
||||
let filter_layer = self.filter_layer()?;
|
||||
|
||||
|
@ -35,7 +35,7 @@ impl<'a> Instrumentation {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn fmt_layer<S>(&self) -> impl tracing_subscriber::layer::Layer<S>
|
||||
pub fn fmt_layer<S>(&self) -> impl tracing_subscriber::layer::Layer<S>
|
||||
where
|
||||
S: tracing::Subscriber + for<'span> tracing_subscriber::registry::LookupSpan<'span>,
|
||||
{
|
||||
|
@ -45,7 +45,7 @@ impl<'a> Instrumentation {
|
|||
.pretty()
|
||||
}
|
||||
|
||||
pub(crate) fn filter_layer(&self) -> eyre::Result<EnvFilter> {
|
||||
pub fn filter_layer(&self) -> eyre::Result<EnvFilter> {
|
||||
let filter_layer = match EnvFilter::try_from_default_env() {
|
||||
Ok(layer) => layer,
|
||||
Err(e) => {
|
||||
|
|
|
@ -2,5 +2,3 @@ mod instrumentation;
|
|||
pub(crate) use instrumentation::Instrumentation;
|
||||
mod channel_value;
|
||||
pub(crate) use channel_value::ChannelValue;
|
||||
mod plan_options;
|
||||
pub(crate) use plan_options::PlanOptions;
|
||||
|
|
|
@ -1,45 +0,0 @@
|
|||
use clap::{ArgAction, Parser};
|
||||
use harmonic::Planner;
|
||||
|
||||
/// Plan an install that can be repeated on an identical host later
|
||||
#[derive(Debug, Parser)]
|
||||
pub(crate) struct PlanOptions {
|
||||
/// Channel(s) to add by default, pass multiple times for multiple channels
|
||||
#[clap(
|
||||
long,
|
||||
value_parser,
|
||||
action = clap::ArgAction::Append,
|
||||
env = "HARMONIC_CHANNEL",
|
||||
default_value = "nixpkgs=https://nixos.org/channels/nixpkgs-unstable",
|
||||
group = "plan_options"
|
||||
)]
|
||||
pub(crate) channel: Vec<crate::cli::arg::ChannelValue>,
|
||||
/// Don't modify the user profile to automatically load nix
|
||||
#[clap(
|
||||
long,
|
||||
action(ArgAction::SetTrue),
|
||||
default_value = "false",
|
||||
global = true,
|
||||
group = "plan_options"
|
||||
)]
|
||||
pub(crate) no_modify_profile: bool,
|
||||
/// Number of build users to create
|
||||
#[clap(
|
||||
long,
|
||||
default_value = "32",
|
||||
env = "HARMONIC_NIX_DAEMON_USER_COUNT",
|
||||
group = "plan_options"
|
||||
)]
|
||||
pub(crate) daemon_user_count: usize,
|
||||
#[clap(
|
||||
long,
|
||||
action(ArgAction::SetTrue),
|
||||
default_value = "false",
|
||||
global = true,
|
||||
group = "plan_options"
|
||||
)]
|
||||
pub(crate) force: bool,
|
||||
// Override the default planner for this OS/Architecture
|
||||
#[clap(long, global = true, group = "plan_options", value_parser = clap::builder::EnumValueParser::<Planner>::new())]
|
||||
pub(crate) planner: Option<Planner>,
|
||||
}
|
|
@ -7,7 +7,7 @@ use std::process::ExitCode;
|
|||
use self::subcommand::HarmonicSubcommand;
|
||||
|
||||
#[async_trait::async_trait]
|
||||
pub(crate) trait CommandExecute {
|
||||
pub trait CommandExecute {
|
||||
async fn execute(self) -> eyre::Result<ExitCode>;
|
||||
}
|
||||
|
||||
|
@ -16,12 +16,12 @@ pub(crate) trait CommandExecute {
|
|||
/// Plans a Nix install, prompts for confirmation, then executes it
|
||||
#[derive(Debug, Parser)]
|
||||
#[clap(version)]
|
||||
pub(crate) struct HarmonicCli {
|
||||
pub struct HarmonicCli {
|
||||
#[clap(flatten)]
|
||||
pub(crate) instrumentation: arg::Instrumentation,
|
||||
pub instrumentation: arg::Instrumentation,
|
||||
|
||||
#[clap(subcommand)]
|
||||
subcommand: HarmonicSubcommand,
|
||||
pub subcommand: HarmonicSubcommand,
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
|
|
|
@ -1,41 +1,35 @@
|
|||
use std::{path::PathBuf, process::ExitCode};
|
||||
|
||||
use crate::BuiltinPlanner;
|
||||
use clap::{ArgAction, Parser};
|
||||
use eyre::{eyre, WrapErr};
|
||||
use harmonic::{InstallPlan, InstallSettings, Planner};
|
||||
|
||||
use crate::{
|
||||
cli::{
|
||||
arg::{ChannelValue, PlanOptions},
|
||||
CommandExecute,
|
||||
},
|
||||
interaction,
|
||||
};
|
||||
use crate::{cli::CommandExecute, interaction};
|
||||
|
||||
/// Execute an install (possibly using an existing plan)
|
||||
#[derive(Debug, Parser)]
|
||||
pub(crate) struct Install {
|
||||
#[command(args_conflicts_with_subcommands = true)]
|
||||
pub struct Install {
|
||||
#[clap(
|
||||
long,
|
||||
action(ArgAction::SetTrue),
|
||||
default_value = "false",
|
||||
global = true
|
||||
)]
|
||||
no_confirm: bool,
|
||||
#[clap(flatten)]
|
||||
plan_options: PlanOptions,
|
||||
pub no_confirm: bool,
|
||||
|
||||
#[clap(
|
||||
long,
|
||||
action(ArgAction::SetTrue),
|
||||
default_value = "false",
|
||||
global = true
|
||||
)]
|
||||
pub(crate) explain: bool,
|
||||
#[clap(
|
||||
conflicts_with_all = [ "plan_options" ],
|
||||
env = "HARMONIC_PLAN",
|
||||
)]
|
||||
plan: Option<PathBuf>,
|
||||
pub explain: bool,
|
||||
#[clap(env = "HARMONIC_PLAN")]
|
||||
pub plan: Option<PathBuf>,
|
||||
|
||||
#[clap(subcommand)]
|
||||
pub planner: BuiltinPlanner,
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
|
@ -45,7 +39,7 @@ impl CommandExecute for Install {
|
|||
let Self {
|
||||
no_confirm,
|
||||
plan,
|
||||
plan_options,
|
||||
planner,
|
||||
explain,
|
||||
} = self;
|
||||
|
||||
|
@ -56,26 +50,7 @@ impl CommandExecute for Install {
|
|||
.wrap_err("Reading plan")?;
|
||||
serde_json::from_str(&install_plan_string)?
|
||||
},
|
||||
None => {
|
||||
let mut settings = InstallSettings::default()?;
|
||||
|
||||
settings.force(plan_options.force);
|
||||
settings.daemon_user_count(plan_options.daemon_user_count);
|
||||
settings.channels(
|
||||
plan_options
|
||||
.channel
|
||||
.into_iter()
|
||||
.map(|ChannelValue(name, url)| (name, url)),
|
||||
);
|
||||
settings.modify_profile(!plan_options.no_modify_profile);
|
||||
|
||||
let planner = match plan_options.planner {
|
||||
Some(planner) => planner,
|
||||
None => Planner::default()?,
|
||||
};
|
||||
|
||||
InstallPlan::new(planner, settings).await?
|
||||
},
|
||||
None => planner.plan().await?,
|
||||
};
|
||||
|
||||
if !no_confirm {
|
||||
|
|
|
@ -6,7 +6,7 @@ mod uninstall;
|
|||
use uninstall::Uninstall;
|
||||
|
||||
#[derive(Debug, clap::Subcommand)]
|
||||
pub(crate) enum HarmonicSubcommand {
|
||||
pub enum HarmonicSubcommand {
|
||||
Plan(Plan),
|
||||
Install(Install),
|
||||
Uninstall(Uninstall),
|
||||
|
|
|
@ -1,61 +1,34 @@
|
|||
use std::{path::PathBuf, process::ExitCode};
|
||||
|
||||
use crate::BuiltinPlanner;
|
||||
use clap::Parser;
|
||||
use harmonic::{InstallPlan, InstallSettings, Planner};
|
||||
|
||||
use eyre::WrapErr;
|
||||
|
||||
use crate::cli::{
|
||||
arg::{ChannelValue, PlanOptions},
|
||||
CommandExecute,
|
||||
};
|
||||
use crate::cli::CommandExecute;
|
||||
|
||||
/// Plan an install that can be repeated on an identical host later
|
||||
#[derive(Debug, Parser)]
|
||||
pub(crate) struct Plan {
|
||||
#[clap(flatten)]
|
||||
plan_options: PlanOptions,
|
||||
#[clap(default_value = "/dev/stdout")]
|
||||
pub(crate) plan: PathBuf,
|
||||
#[command(multicall = true)]
|
||||
pub struct Plan {
|
||||
#[clap(subcommand)]
|
||||
pub planner: Option<BuiltinPlanner>,
|
||||
#[clap(env = "HARMONIC_PLAN")]
|
||||
pub plan: PathBuf,
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl CommandExecute for Plan {
|
||||
#[tracing::instrument(skip_all, fields(
|
||||
channels = %self.plan_options.channel.iter().map(|ChannelValue(name, url)| format!("{name} {url}")).collect::<Vec<_>>().join(", "),
|
||||
daemon_user_count = %self.plan_options.daemon_user_count,
|
||||
no_modify_profile = %self.plan_options.no_modify_profile,
|
||||
))]
|
||||
#[tracing::instrument(skip_all, fields())]
|
||||
async fn execute(self) -> eyre::Result<ExitCode> {
|
||||
let Self {
|
||||
plan_options:
|
||||
PlanOptions {
|
||||
channel,
|
||||
no_modify_profile,
|
||||
daemon_user_count,
|
||||
force,
|
||||
planner,
|
||||
},
|
||||
plan,
|
||||
} = self;
|
||||
|
||||
let mut settings = InstallSettings::default()?;
|
||||
|
||||
settings.force(force);
|
||||
settings.daemon_user_count(daemon_user_count);
|
||||
settings.channels(
|
||||
channel
|
||||
.into_iter()
|
||||
.map(|ChannelValue(name, url)| (name, url)),
|
||||
);
|
||||
settings.modify_profile(!no_modify_profile);
|
||||
let Self { planner, plan } = self;
|
||||
|
||||
let planner = match planner {
|
||||
Some(planner) => planner,
|
||||
None => Planner::default()?,
|
||||
None => BuiltinPlanner::default()?,
|
||||
};
|
||||
|
||||
let install_plan = InstallPlan::new(planner, settings).await?;
|
||||
let install_plan = planner.plan().await?;
|
||||
|
||||
let json = serde_json::to_string_pretty(&install_plan)?;
|
||||
tokio::fs::write(plan, json)
|
||||
|
|
|
@ -1,30 +1,30 @@
|
|||
use std::{path::PathBuf, process::ExitCode};
|
||||
|
||||
use crate::InstallPlan;
|
||||
use clap::{ArgAction, Parser};
|
||||
use eyre::WrapErr;
|
||||
use harmonic::InstallPlan;
|
||||
|
||||
use crate::{cli::CommandExecute, interaction};
|
||||
|
||||
/// Uninstall a previously installed Nix (only Harmonic done installs supported)
|
||||
#[derive(Debug, Parser)]
|
||||
pub(crate) struct Uninstall {
|
||||
pub struct Uninstall {
|
||||
#[clap(
|
||||
long,
|
||||
action(ArgAction::SetTrue),
|
||||
default_value = "false",
|
||||
global = true
|
||||
)]
|
||||
no_confirm: bool,
|
||||
pub no_confirm: bool,
|
||||
#[clap(
|
||||
long,
|
||||
action(ArgAction::SetTrue),
|
||||
default_value = "false",
|
||||
global = true
|
||||
)]
|
||||
explain: bool,
|
||||
pub explain: bool,
|
||||
#[clap(default_value = "/nix/receipt.json")]
|
||||
receipt: PathBuf,
|
||||
pub receipt: PathBuf,
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
|
|
10
src/lib.rs
10
src/lib.rs
|
@ -1,19 +1,17 @@
|
|||
mod actions;
|
||||
pub mod cli;
|
||||
mod error;
|
||||
mod interaction;
|
||||
mod os;
|
||||
mod plan;
|
||||
mod planner;
|
||||
mod settings;
|
||||
|
||||
use std::{
|
||||
ffi::OsStr,
|
||||
fmt::Display,
|
||||
process::{ExitStatus, Output},
|
||||
};
|
||||
use std::{ffi::OsStr, fmt::Display, process::Output};
|
||||
|
||||
pub use error::HarmonicError;
|
||||
pub use plan::InstallPlan;
|
||||
pub use planner::Planner;
|
||||
pub use planner::BuiltinPlanner;
|
||||
use serde::Serializer;
|
||||
pub use settings::InstallSettings;
|
||||
|
||||
|
|
|
@ -1,11 +1,7 @@
|
|||
pub(crate) mod cli;
|
||||
|
||||
use std::process::ExitCode;
|
||||
|
||||
pub mod interaction;
|
||||
|
||||
use clap::Parser;
|
||||
use cli::CommandExecute;
|
||||
use harmonic::cli::CommandExecute;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> color_eyre::Result<ExitCode> {
|
||||
|
@ -17,7 +13,7 @@ async fn main() -> color_eyre::Result<ExitCode> {
|
|||
})
|
||||
.install()?;
|
||||
|
||||
let cli = cli::HarmonicCli::parse();
|
||||
let cli = harmonic::cli::HarmonicCli::parse();
|
||||
|
||||
cli.instrumentation.setup()?;
|
||||
|
||||
|
|
40
src/plan.rs
40
src/plan.rs
|
@ -2,32 +2,20 @@ use std::path::PathBuf;
|
|||
|
||||
use crate::{
|
||||
actions::{Action, ActionDescription, ActionError, Actionable},
|
||||
planner::PlannerError,
|
||||
settings::InstallSettings,
|
||||
HarmonicError, Planner,
|
||||
BuiltinPlanner, HarmonicError,
|
||||
};
|
||||
|
||||
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
|
||||
pub struct InstallPlan {
|
||||
pub(crate) settings: InstallSettings,
|
||||
|
||||
pub(crate) actions: Vec<Action>,
|
||||
|
||||
pub(crate) planner: Planner,
|
||||
pub(crate) planner: BuiltinPlanner,
|
||||
}
|
||||
|
||||
impl InstallPlan {
|
||||
pub async fn new(planner: Planner, settings: InstallSettings) -> Result<Self, PlannerError> {
|
||||
planner.plan(settings).await
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip_all)]
|
||||
pub fn describe_execute(&self, explain: bool) -> String {
|
||||
let Self {
|
||||
planner,
|
||||
settings,
|
||||
actions,
|
||||
} = self;
|
||||
let Self { planner, actions } = self;
|
||||
format!(
|
||||
"\
|
||||
This Nix install is for:\n\
|
||||
|
@ -42,12 +30,7 @@ impl InstallPlan {
|
|||
",
|
||||
os_type = "Linux",
|
||||
init_type = "systemd",
|
||||
nix_channels = settings
|
||||
.channels
|
||||
.iter()
|
||||
.map(|(name, url)| format!("{name}={url}"))
|
||||
.collect::<Vec<_>>()
|
||||
.join(","),
|
||||
nix_channels = "todo",
|
||||
actions = actions
|
||||
.iter()
|
||||
.map(|v| v.describe_execute())
|
||||
|
@ -76,7 +59,6 @@ impl InstallPlan {
|
|||
pub async fn install(&mut self) -> Result<(), HarmonicError> {
|
||||
let Self {
|
||||
actions,
|
||||
settings: _,
|
||||
planner: _,
|
||||
} = self;
|
||||
|
||||
|
@ -97,11 +79,7 @@ impl InstallPlan {
|
|||
|
||||
#[tracing::instrument(skip_all)]
|
||||
pub fn describe_revert(&self, explain: bool) -> String {
|
||||
let Self {
|
||||
planner,
|
||||
settings,
|
||||
actions,
|
||||
} = self;
|
||||
let Self { planner, actions } = self;
|
||||
format!(
|
||||
"\
|
||||
This Nix uninstall is for:\n\
|
||||
|
@ -116,12 +94,7 @@ impl InstallPlan {
|
|||
",
|
||||
os_type = "Linux",
|
||||
init_type = "systemd",
|
||||
nix_channels = settings
|
||||
.channels
|
||||
.iter()
|
||||
.map(|(name, url)| format!("{name}={url}"))
|
||||
.collect::<Vec<_>>()
|
||||
.join(","),
|
||||
nix_channels = "todo",
|
||||
actions = actions
|
||||
.iter()
|
||||
.map(|v| v.describe_revert())
|
||||
|
@ -150,7 +123,6 @@ impl InstallPlan {
|
|||
pub async fn revert(&mut self) -> Result<(), HarmonicError> {
|
||||
let Self {
|
||||
actions,
|
||||
settings: _,
|
||||
planner: _,
|
||||
} = self;
|
||||
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
mod multi_user;
|
||||
mod multi;
|
||||
|
||||
pub use multi_user::DarwinMultiUser;
|
||||
pub use multi::DarwinMulti;
|
||||
|
|
|
@ -11,20 +11,27 @@ use crate::{
|
|||
execute_command,
|
||||
os::darwin::DiskUtilOutput,
|
||||
planner::{Plannable, PlannerError},
|
||||
InstallPlan, Planner,
|
||||
BuiltinPlanner, InstallPlan, InstallSettings,
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, Default)]
|
||||
pub struct DarwinMultiUser;
|
||||
#[derive(Debug, Clone, clap::Parser, serde::Serialize, serde::Deserialize)]
|
||||
pub struct DarwinMulti {
|
||||
#[clap(flatten)]
|
||||
settings: InstallSettings,
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl Plannable for DarwinMultiUser {
|
||||
impl Plannable for DarwinMulti {
|
||||
const DISPLAY_STRING: &'static str = "Darwin Multi-User";
|
||||
const SLUG: &'static str = "darwin-multi";
|
||||
|
||||
async fn plan(
|
||||
settings: crate::InstallSettings,
|
||||
) -> Result<crate::InstallPlan, crate::planner::PlannerError> {
|
||||
fn default() -> Result<Self, PlannerError> {
|
||||
Ok(Self {
|
||||
settings: InstallSettings::default()?,
|
||||
})
|
||||
}
|
||||
|
||||
async fn plan(self) -> Result<crate::InstallPlan, crate::planner::PlannerError> {
|
||||
let root_disk = {
|
||||
let buf =
|
||||
execute_command(Command::new("/usr/sbin/diskutil").args(["info", "-plist", "/"]))
|
||||
|
@ -39,8 +46,7 @@ impl Plannable for DarwinMultiUser {
|
|||
let volume_label = "Nix Store".into();
|
||||
|
||||
Ok(InstallPlan {
|
||||
planner: Self.into(),
|
||||
settings: settings.clone(),
|
||||
planner: self.clone().into(),
|
||||
actions: vec![
|
||||
// Create Volume step:
|
||||
//
|
||||
|
@ -50,11 +56,11 @@ impl Plannable for DarwinMultiUser {
|
|||
.await
|
||||
.map(Action::from)
|
||||
.map_err(ActionError::from)?,
|
||||
ProvisionNix::plan(settings.clone())
|
||||
ProvisionNix::plan(self.settings.clone())
|
||||
.await
|
||||
.map(Action::from)
|
||||
.map_err(ActionError::from)?,
|
||||
ConfigureNix::plan(settings)
|
||||
ConfigureNix::plan(self.settings)
|
||||
.await
|
||||
.map(Action::from)
|
||||
.map_err(ActionError::from)?,
|
||||
|
@ -67,8 +73,8 @@ impl Plannable for DarwinMultiUser {
|
|||
}
|
||||
}
|
||||
|
||||
impl Into<Planner> for DarwinMultiUser {
|
||||
fn into(self) -> Planner {
|
||||
Planner::DarwinMultiUser
|
||||
impl Into<BuiltinPlanner> for DarwinMulti {
|
||||
fn into(self) -> BuiltinPlanner {
|
||||
BuiltinPlanner::DarwinMulti(self)
|
||||
}
|
||||
}
|
|
@ -1,3 +1,3 @@
|
|||
mod multi_user;
|
||||
mod multi;
|
||||
|
||||
pub use multi_user::LinuxMultiUser;
|
||||
pub use multi::LinuxMulti;
|
||||
|
|
|
@ -5,31 +5,39 @@ use crate::{
|
|||
Action, ActionError,
|
||||
},
|
||||
planner::{Plannable, PlannerError},
|
||||
InstallPlan, InstallSettings, Planner,
|
||||
BuiltinPlanner, InstallPlan, InstallSettings,
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, Default)]
|
||||
pub struct LinuxMultiUser;
|
||||
#[derive(Debug, Clone, clap::Parser, serde::Serialize, serde::Deserialize)]
|
||||
pub struct LinuxMulti {
|
||||
#[clap(flatten)]
|
||||
settings: InstallSettings,
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl Plannable for LinuxMultiUser {
|
||||
impl Plannable for LinuxMulti {
|
||||
const DISPLAY_STRING: &'static str = "Linux Multi-User";
|
||||
const SLUG: &'static str = "linux-multi";
|
||||
|
||||
async fn plan(settings: InstallSettings) -> Result<InstallPlan, PlannerError> {
|
||||
fn default() -> Result<Self, PlannerError> {
|
||||
Ok(Self {
|
||||
settings: InstallSettings::default()?,
|
||||
})
|
||||
}
|
||||
|
||||
async fn plan(self) -> Result<InstallPlan, PlannerError> {
|
||||
Ok(InstallPlan {
|
||||
planner: Self.into(),
|
||||
settings: settings.clone(),
|
||||
planner: self.clone().into(),
|
||||
actions: vec![
|
||||
CreateDirectory::plan("/nix", None, None, 0o0755, true)
|
||||
.await
|
||||
.map(Action::from)
|
||||
.map_err(ActionError::from)?,
|
||||
ProvisionNix::plan(settings.clone())
|
||||
ProvisionNix::plan(self.settings.clone())
|
||||
.await
|
||||
.map(Action::from)
|
||||
.map_err(ActionError::from)?,
|
||||
ConfigureNix::plan(settings)
|
||||
ConfigureNix::plan(self.settings)
|
||||
.await
|
||||
.map(Action::from)
|
||||
.map_err(ActionError::from)?,
|
||||
|
@ -42,8 +50,8 @@ impl Plannable for LinuxMultiUser {
|
|||
}
|
||||
}
|
||||
|
||||
impl Into<Planner> for LinuxMultiUser {
|
||||
fn into(self) -> Planner {
|
||||
Planner::LinuxMultiUser
|
||||
impl Into<BuiltinPlanner> for LinuxMulti {
|
||||
fn into(self) -> BuiltinPlanner {
|
||||
BuiltinPlanner::LinuxMulti(self)
|
||||
}
|
||||
}
|
|
@ -1,51 +1,57 @@
|
|||
mod darwin;
|
||||
mod linux;
|
||||
mod specific;
|
||||
pub mod darwin;
|
||||
pub mod linux;
|
||||
pub mod specific;
|
||||
|
||||
use crate::{actions::ActionError, InstallPlan, InstallSettings};
|
||||
use crate::{actions::ActionError, settings::InstallSettingsError, InstallPlan};
|
||||
|
||||
#[derive(Debug, Clone, clap::ValueEnum, serde::Serialize, serde::Deserialize)]
|
||||
pub enum Planner {
|
||||
LinuxMultiUser,
|
||||
DarwinMultiUser,
|
||||
SteamDeck,
|
||||
#[derive(Debug, Clone, clap::Subcommand, serde::Serialize, serde::Deserialize)]
|
||||
pub enum BuiltinPlanner {
|
||||
LinuxMulti(linux::LinuxMulti),
|
||||
DarwinMulti(darwin::DarwinMulti),
|
||||
SteamDeck(specific::SteamDeck),
|
||||
}
|
||||
|
||||
impl Planner {
|
||||
pub fn possible_values() -> &'static [Planner] {
|
||||
&[Self::LinuxMultiUser, Self::DarwinMultiUser, Self::SteamDeck]
|
||||
}
|
||||
impl BuiltinPlanner {
|
||||
pub fn default() -> Result<Self, PlannerError> {
|
||||
use target_lexicon::{Architecture, OperatingSystem};
|
||||
match (Architecture::host(), OperatingSystem::host()) {
|
||||
(Architecture::X86_64, OperatingSystem::Linux) => Ok(Self::LinuxMultiUser),
|
||||
(Architecture::Aarch64(_), OperatingSystem::Linux) => Ok(Self::LinuxMultiUser),
|
||||
(Architecture::X86_64, OperatingSystem::Linux) => {
|
||||
Ok(Self::LinuxMulti(linux::LinuxMulti::default()?))
|
||||
},
|
||||
(Architecture::Aarch64(_), OperatingSystem::Linux) => {
|
||||
Ok(Self::LinuxMulti(linux::LinuxMulti::default()?))
|
||||
},
|
||||
(Architecture::X86_64, OperatingSystem::MacOSX { .. })
|
||||
| (Architecture::X86_64, OperatingSystem::Darwin) => Ok(Self::DarwinMultiUser),
|
||||
| (Architecture::X86_64, OperatingSystem::Darwin) => {
|
||||
Ok(Self::DarwinMulti(darwin::DarwinMulti::default()?))
|
||||
},
|
||||
(Architecture::Aarch64(_), OperatingSystem::MacOSX { .. })
|
||||
| (Architecture::Aarch64(_), OperatingSystem::Darwin) => Ok(Self::DarwinMultiUser),
|
||||
| (Architecture::Aarch64(_), OperatingSystem::Darwin) => {
|
||||
Ok(Self::DarwinMulti(darwin::DarwinMulti::default()?))
|
||||
},
|
||||
_ => Err(PlannerError::UnsupportedArchitecture(target_lexicon::HOST)),
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn plan(self, settings: InstallSettings) -> Result<InstallPlan, PlannerError> {
|
||||
pub async fn plan(self) -> Result<InstallPlan, PlannerError> {
|
||||
match self {
|
||||
Planner::LinuxMultiUser => linux::LinuxMultiUser::plan(settings).await,
|
||||
Planner::DarwinMultiUser => darwin::DarwinMultiUser::plan(settings).await,
|
||||
Planner::SteamDeck => specific::SteamDeck::plan(settings).await,
|
||||
BuiltinPlanner::LinuxMulti(planner) => planner.plan().await,
|
||||
BuiltinPlanner::DarwinMulti(planner) => planner.plan().await,
|
||||
BuiltinPlanner::SteamDeck(planner) => planner.plan().await,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
trait Plannable: Into<Planner>
|
||||
trait Plannable: Into<BuiltinPlanner>
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
const DISPLAY_STRING: &'static str;
|
||||
const SLUG: &'static str;
|
||||
|
||||
async fn plan(settings: InstallSettings) -> Result<InstallPlan, PlannerError>;
|
||||
fn default() -> Result<Self, PlannerError>;
|
||||
async fn plan(self) -> Result<InstallPlan, PlannerError>;
|
||||
}
|
||||
|
||||
#[derive(thiserror::Error, Debug)]
|
||||
|
@ -58,4 +64,6 @@ pub enum PlannerError {
|
|||
#[from]
|
||||
ActionError,
|
||||
),
|
||||
#[error(transparent)]
|
||||
InstallSettings(#[from] InstallSettingsError),
|
||||
}
|
||||
|
|
|
@ -4,24 +4,30 @@ use crate::{
|
|||
meta::{CreateSystemdSysext, ProvisionNix},
|
||||
Action, ActionError,
|
||||
},
|
||||
planner::Plannable,
|
||||
InstallPlan, Planner,
|
||||
planner::{Plannable, PlannerError},
|
||||
BuiltinPlanner, InstallPlan, InstallSettings,
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, Default)]
|
||||
pub struct SteamDeck;
|
||||
#[derive(Debug, Clone, clap::Parser, serde::Serialize, serde::Deserialize)]
|
||||
pub struct SteamDeck {
|
||||
#[clap(flatten)]
|
||||
settings: InstallSettings,
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl Plannable for SteamDeck {
|
||||
const DISPLAY_STRING: &'static str = "Steam Deck (x86_64 Linux Multi-User)";
|
||||
const SLUG: &'static str = "steam-deck";
|
||||
|
||||
async fn plan(
|
||||
settings: crate::InstallSettings,
|
||||
) -> Result<crate::InstallPlan, crate::planner::PlannerError> {
|
||||
fn default() -> Result<Self, PlannerError> {
|
||||
Ok(Self {
|
||||
settings: InstallSettings::default()?,
|
||||
})
|
||||
}
|
||||
|
||||
async fn plan(self) -> Result<crate::InstallPlan, PlannerError> {
|
||||
Ok(InstallPlan {
|
||||
planner: Self.into(),
|
||||
settings: settings.clone(),
|
||||
planner: self.clone().into(),
|
||||
actions: vec![
|
||||
CreateSystemdSysext::plan("/var/lib/extensions")
|
||||
.await
|
||||
|
@ -31,7 +37,7 @@ impl Plannable for SteamDeck {
|
|||
.await
|
||||
.map(Action::from)
|
||||
.map_err(ActionError::from)?,
|
||||
ProvisionNix::plan(settings.clone())
|
||||
ProvisionNix::plan(self.settings.clone())
|
||||
.await
|
||||
.map(Action::from)
|
||||
.map_err(ActionError::from)?,
|
||||
|
@ -44,8 +50,8 @@ impl Plannable for SteamDeck {
|
|||
}
|
||||
}
|
||||
|
||||
impl Into<Planner> for SteamDeck {
|
||||
fn into(self) -> Planner {
|
||||
Planner::SteamDeck
|
||||
impl Into<BuiltinPlanner> for SteamDeck {
|
||||
fn into(self) -> BuiltinPlanner {
|
||||
BuiltinPlanner::SteamDeck(self)
|
||||
}
|
||||
}
|
||||
|
|
107
src/settings.rs
107
src/settings.rs
|
@ -1,22 +1,90 @@
|
|||
use crate::planner;
|
||||
use target_lexicon::Triple;
|
||||
use clap::ArgAction;
|
||||
use derivative::Derivative;
|
||||
use url::Url;
|
||||
|
||||
pub const NIX_X64_64_LINUX_URL: &str =
|
||||
"https://releases.nixos.org/nix/nix-2.11.0/nix-2.11.0-x86_64-linux.tar.xz";
|
||||
pub const NIX_AARCH64_LINUX_URL: &str =
|
||||
"https://releases.nixos.org/nix/nix-2.11.0/nix-2.11.0-aarch64-linux.tar.xz";
|
||||
pub const NIX_X64_64_DARWIN_URL: &str =
|
||||
"https://releases.nixos.org/nix/nix-2.11.0/nix-2.11.0-x86_64-darwin.tar.xz";
|
||||
pub const NIX_AARCH64_DARWIN_URL: &str =
|
||||
"https://releases.nixos.org/nix/nix-2.11.0/nix-2.11.0-aarch64-darwin.tar.xz";
|
||||
|
||||
#[serde_with::serde_as]
|
||||
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
|
||||
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone, clap::Parser)]
|
||||
pub struct InstallSettings {
|
||||
pub(crate) daemon_user_count: usize,
|
||||
pub(crate) channels: Vec<(String, Url)>,
|
||||
/// Channel(s) to add by default, pass multiple times for multiple channels
|
||||
#[clap(
|
||||
long,
|
||||
value_parser,
|
||||
name = "channel",
|
||||
action = clap::ArgAction::Append,
|
||||
env = "HARMONIC_CHANNEL",
|
||||
default_value = "nixpkgs=https://nixos.org/channels/nixpkgs-unstable",
|
||||
)]
|
||||
pub(crate) channels: Vec<crate::cli::arg::ChannelValue>,
|
||||
/// Modify the user profile to automatically load nix
|
||||
#[clap(
|
||||
long,
|
||||
action(ArgAction::SetFalse),
|
||||
default_value = "true",
|
||||
global = true,
|
||||
env = "HARMONIC_NO_MODIFY_PROFILE",
|
||||
name = "no-modify-profile"
|
||||
)]
|
||||
pub(crate) modify_profile: bool,
|
||||
/// Number of build users to create
|
||||
#[clap(long, default_value = "32", env = "HARMONIC_DAEMON_USER_COUNT")]
|
||||
pub(crate) daemon_user_count: usize,
|
||||
#[clap(long, default_value = "nixbld", env = "HARMONIC_NIX_BUILD_GROUP_NAME")]
|
||||
pub(crate) nix_build_group_name: String,
|
||||
#[clap(long, default_value_t = 3000, env = "HARMONIC_NIX_BUILD_GROUP_ID")]
|
||||
pub(crate) nix_build_group_id: usize,
|
||||
#[clap(long, env = "HARMONIC_NIX_BUILD_USER_PREFIX")]
|
||||
#[cfg_attr(target_os = "macos", clap(default_value = "_nixbld"))]
|
||||
#[cfg_attr(target_os = "linux", clap(default_value = "nixbld"))]
|
||||
pub(crate) nix_build_user_prefix: String,
|
||||
#[clap(long, env = "HARMONIC_NIX_BUILD_USER_ID_BASE")]
|
||||
#[cfg_attr(target_os = "macos", clap(default_value_t = 300))]
|
||||
#[cfg_attr(target_os = "linux", clap(default_value_t = 3000))]
|
||||
pub(crate) nix_build_user_id_base: usize,
|
||||
#[clap(long, env = "HARMONIC_NIX_PACKAGE_URL")]
|
||||
#[cfg_attr(
|
||||
all(target_os = "macos", target_arch = "x86_64"),
|
||||
clap(
|
||||
default_value = NIX_X64_64_DARWIN_URL,
|
||||
)
|
||||
)]
|
||||
#[cfg_attr(
|
||||
all(target_os = "macos", target_arch = "aarch64"),
|
||||
clap(
|
||||
default_value = NIX_AARCH64_DARWIN_URL,
|
||||
)
|
||||
)]
|
||||
#[cfg_attr(
|
||||
all(target_os = "linux", target_arch = "x86_64"),
|
||||
clap(
|
||||
default_value = NIX_X64_64_LINUX_URL,
|
||||
)
|
||||
)]
|
||||
#[cfg_attr(
|
||||
all(target_os = "linux", target_arch = "aarch64"),
|
||||
clap(
|
||||
default_value = NIX_AARCH64_LINUX_URL,
|
||||
)
|
||||
)]
|
||||
pub(crate) nix_package_url: Url,
|
||||
#[clap(long, env = "HARMONIC_EXTRA_CONF")]
|
||||
pub(crate) extra_conf: Option<String>,
|
||||
#[clap(
|
||||
long,
|
||||
action(ArgAction::SetTrue),
|
||||
default_value = "false",
|
||||
global = true,
|
||||
env = "HARMONIC_FORCE"
|
||||
)]
|
||||
pub(crate) force: bool,
|
||||
#[serde_as(as = "serde_with::DisplayFromStr")]
|
||||
pub(crate) triple: Triple,
|
||||
}
|
||||
|
||||
impl InstallSettings {
|
||||
|
@ -28,24 +96,24 @@ impl InstallSettings {
|
|||
use target_lexicon::{Architecture, OperatingSystem};
|
||||
match (Architecture::host(), OperatingSystem::host()) {
|
||||
(Architecture::X86_64, OperatingSystem::Linux) => {
|
||||
url = "https://releases.nixos.org/nix/nix-2.11.0/nix-2.11.0-x86_64-linux.tar.xz";
|
||||
url = NIX_X64_64_LINUX_URL;
|
||||
nix_build_user_prefix = "nixbld";
|
||||
nix_build_user_id_base = 3000;
|
||||
},
|
||||
(Architecture::Aarch64(_), OperatingSystem::Linux) => {
|
||||
url = "https://releases.nixos.org/nix/nix-2.11.0/nix-2.11.0-aarch64-linux.tar.xz";
|
||||
url = NIX_AARCH64_LINUX_URL;
|
||||
nix_build_user_prefix = "nixbld";
|
||||
nix_build_user_id_base = 3000;
|
||||
},
|
||||
(Architecture::X86_64, OperatingSystem::MacOSX { .. })
|
||||
| (Architecture::X86_64, OperatingSystem::Darwin) => {
|
||||
url = "https://releases.nixos.org/nix/nix-2.11.0/nix-2.11.0-x86_64-darwin.tar.xz";
|
||||
url = NIX_X64_64_DARWIN_URL;
|
||||
nix_build_user_prefix = "_nixbld";
|
||||
nix_build_user_id_base = 300;
|
||||
},
|
||||
(Architecture::Aarch64(_), OperatingSystem::MacOSX { .. })
|
||||
| (Architecture::Aarch64(_), OperatingSystem::Darwin) => {
|
||||
url = "https://releases.nixos.org/nix/nix-2.11.0/nix-2.11.0-aarch64-darwin.tar.xz";
|
||||
url = NIX_AARCH64_DARWIN_URL;
|
||||
nix_build_user_prefix = "_nixbld";
|
||||
nix_build_user_id_base = 300;
|
||||
},
|
||||
|
@ -57,17 +125,14 @@ impl InstallSettings {
|
|||
};
|
||||
|
||||
Ok(Self {
|
||||
triple: target_lexicon::HOST,
|
||||
daemon_user_count: Default::default(),
|
||||
channels: Default::default(),
|
||||
modify_profile: Default::default(),
|
||||
channels: Vec::default(),
|
||||
modify_profile: true,
|
||||
nix_build_group_name: String::from("nixbld"),
|
||||
nix_build_group_id: 3000,
|
||||
nix_build_user_prefix: nix_build_user_prefix.to_string(),
|
||||
nix_build_user_id_base,
|
||||
nix_package_url: url
|
||||
.parse()
|
||||
.expect("Could not parse default Nix archive url, please report this issue"),
|
||||
nix_package_url: url.parse()?,
|
||||
extra_conf: Default::default(),
|
||||
force: false,
|
||||
})
|
||||
|
@ -82,7 +147,7 @@ impl InstallSettings {
|
|||
}
|
||||
|
||||
pub fn channels(&mut self, channels: impl IntoIterator<Item = (String, Url)>) -> &mut Self {
|
||||
self.channels = channels.into_iter().collect();
|
||||
self.channels = channels.into_iter().map(Into::into).collect();
|
||||
self
|
||||
}
|
||||
|
||||
|
@ -128,10 +193,10 @@ impl InstallSettings {
|
|||
pub enum InstallSettingsError {
|
||||
#[error("Harmonic does not support the `{0}` architecture right now")]
|
||||
UnsupportedArchitecture(target_lexicon::Triple),
|
||||
#[error("Planner error")]
|
||||
Planner(
|
||||
#[error("Parsing URL")]
|
||||
Parse(
|
||||
#[source]
|
||||
#[from]
|
||||
planner::PlannerError,
|
||||
url::ParseError,
|
||||
),
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue