diff --git a/Cargo.lock b/Cargo.lock index 9c7e2bc..3ab5f96 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -628,6 +628,7 @@ name = "installer" version = "0.1.0" dependencies = [ "system", + "thiserror", ] [[package]] @@ -676,6 +677,7 @@ dependencies = [ "dialoguer", "futures", "indicatif", + "installer", "system", "tokio", ] diff --git a/crates/installer/Cargo.toml b/crates/installer/Cargo.toml index 22af29f..7ec7cd7 100644 --- a/crates/installer/Cargo.toml +++ b/crates/installer/Cargo.toml @@ -5,3 +5,4 @@ edition = "2021" [dependencies] system = { path = "../system" } +thiserror.workspace = true diff --git a/crates/installer/src/account.rs b/crates/installer/src/account.rs new file mode 100644 index 0000000..4a93dd5 --- /dev/null +++ b/crates/installer/src/account.rs @@ -0,0 +1,97 @@ +// SPDX-FileCopyrightText: Copyright © 2024 Serpent OS Developers +// +// SPDX-License-Identifier: MPL-2.0 + +/// Identifies an account +#[derive(Debug, Clone)] +pub struct Account { + /// User ID + uid: u16, + + /// Group ID + gid: u16, + + /// Account name + username: String, + + /// Human username string + gecos: Option, + + /// Home directory + homedir: String, + + /// Which shell to use + shell: String, + + /// New password + password: Option, + + /// Builtin user? (root) + builtin: bool, +} + +impl Default for Account { + fn default() -> Self { + Self { + uid: 1000, + gid: 1000, + username: "user".into(), + gecos: None, + homedir: "/home/user".into(), + shell: "/bin/bash".into(), + password: None, + builtin: false, + } + } +} + +impl Account { + /// Return an account definition for the root account + pub fn root() -> Self { + Self { + uid: 0, + gid: 0, + username: "root".to_string(), + homedir: "/root".to_string(), + builtin: true, + ..Default::default() + } + } + + /// New account with the given username + pub fn new>(username: S) -> Self { + Self { + username: username.as_ref().to_string(), + ..Default::default() + } + } + + /// Update the IDs + pub fn with_id(self, uid: u16, gid: u16) -> Self { + Self { uid, gid, ..self } + } + + /// Update the gecos + pub fn with_gecos>(self, gecos: S) -> Self { + Self { + gecos: Some(gecos.as_ref().to_string()), + ..self + } + } + + /// Update the shell + pub fn with_shell>(self, shell: S) -> Self { + Self { + shell: shell.as_ref().to_string(), + ..self + } + } + + /// Update the password + pub fn with_password>(self, p: P) -> Self { + Self { + password: Some(p.as_ref().to_string()), + ..self + } + } +} diff --git a/crates/installer/src/engine.rs b/crates/installer/src/engine.rs new file mode 100644 index 0000000..9f7c6fc --- /dev/null +++ b/crates/installer/src/engine.rs @@ -0,0 +1,53 @@ +// SPDX-FileCopyrightText: Copyright © 2024 Serpent OS Developers +// +// SPDX-License-Identifier: MPL-2.0 + +//! Concrete implementation of the isntaller + +use system::{ + disk::{self, Disk}, + locale::{self, Locale}, +}; +use thiserror::Error; + +use crate::Model; + +#[derive(Debug, Error)] +pub enum Error { + #[error("disk: {0}")] + Disk(#[from] disk::Error), + + #[error("locale: {0}")] + Locale(#[from] locale::Error), +} + +/// The installer does some initial probing and is used with a Model +/// to build an execution routine +pub struct Installer<'a> { + /// Complete locale registry + locale_registry: locale::Registry, + + /// Available / loaded locales + locales: Vec>, + + /// All known/useful disks + disks: Vec, +} + +impl<'a> Installer<'a> { + /// Return a newly initialised installer + pub fn new() -> Result { + let locale_registry = locale::Registry::new()?; + let disks = Disk::discover()?; + Ok(Self { + locale_registry, + locales: Vec::new(), + disks, + }) + } + + /// build the model into a set of install steps + pub fn compile_to_steps(&self, _model: &Model) -> Result<(), Error> { + todo!("dont know how") + } +} diff --git a/crates/installer/src/lib.rs b/crates/installer/src/lib.rs index 8969fcf..6181c2c 100644 --- a/crates/installer/src/lib.rs +++ b/crates/installer/src/lib.rs @@ -3,3 +3,13 @@ // SPDX-License-Identifier: MPL-2.0 //! Lichen installer APIs + +mod model; + +pub use model::Model; + +mod account; +pub use account::Account; + +mod engine; +pub use engine::Installer; diff --git a/crates/installer/src/model.rs b/crates/installer/src/model.rs new file mode 100644 index 0000000..2dca9c9 --- /dev/null +++ b/crates/installer/src/model.rs @@ -0,0 +1,14 @@ +// SPDX-FileCopyrightText: Copyright © 2024 Serpent OS Developers +// +// SPDX-License-Identifier: MPL-2.0 + +use std::collections::BTreeSet; + +use crate::Account; + +/// Core model for the installation target +#[derive(Debug, Default)] +pub struct Model { + /// All accounts in the system. + pub accounts: BTreeSet, +} diff --git a/lichen_cli/Cargo.toml b/lichen_cli/Cargo.toml index 7b2d418..7098f79 100644 --- a/lichen_cli/Cargo.toml +++ b/lichen_cli/Cargo.toml @@ -10,5 +10,6 @@ dialoguer = { version = "0.11.0", features = ["completion", "fuzzy-matcher", "fu indicatif = "0.17.8" futures.workspace = true tokio.workspace = true +installer = { path = "../crates/installer" } system = { path = "../crates/system" } console = "0.15.8"