Skip to content

Commit

Permalink
wip: use enum dispatch in image mold
Browse files Browse the repository at this point in the history
  • Loading branch information
cilki committed Nov 25, 2023
1 parent fbc190a commit 82b5abf
Show file tree
Hide file tree
Showing 29 changed files with 173 additions and 196 deletions.
14 changes: 14 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions goldboot-macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,5 @@ fn impl_prompt(ast: &syn::DeriveInput) -> TokenStream {
};
gen.into()
}

// TODO probably need a macro for ImageMold and Fabricator
1 change: 1 addition & 0 deletions goldboot-registry/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,4 @@ rustls = "0.21.8"
rustls-pemfile = "1.0.3"
simple-error = "0.3.0"
tokio = { version = "1.34.0", features = ["full"] }
goldboot = { path="../goldboot", version = "0.0.1" }
1 change: 1 addition & 0 deletions goldboot/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ validator = { version = "0.16.1", features = ["derive"] }
vnc = "0.4.0"
whoami = "1.4.1"
zstd = "0.13.0"
enum_dispatch = "0.3.12"

[dev-dependencies]
test-env-log = "0"
Expand Down
20 changes: 7 additions & 13 deletions goldboot/src/cli/cmd/init.rs
Original file line number Diff line number Diff line change
@@ -1,31 +1,25 @@
use crate::{
build::BuildConfig,
cmd::Commands,
templates::{Template, TemplateMetadata},
Architecture,
};
use console::Style;
use dialoguer::{theme::ColorfulTheme, Confirm, Input, Select};
use goldboot_image::ImageArch;
use simple_error::bail;
use std::{error::Error, path::Path};
use strum::IntoEnumIterator;

#[rustfmt::skip]
fn print_banner() {
if console::colors_enabled() {
let style = Style::new().yellow();

println!("{}", "");
for line in fossable::goldboot_word() {
println!(" {}", style.apply_to(line));
}
println!(" {}", style.apply_to(line));
}
println!("{}", "");
}
}

pub fn run(cmd: crate::cmd::Commands) -> Result<(), Box<dyn Error>> {
pub fn run(cmd: super::Commands) -> Result<(), Box<dyn Error>> {
match cmd {
Commands::Init {
super::Commands::Init {
name,
template,
mimic_hardware,
Expand Down Expand Up @@ -91,7 +85,7 @@ pub fn run(cmd: crate::cmd::Commands) -> Result<(), Box<dyn Error>> {

// Prompt image architecture
{
let architectures: Vec<Architecture> = Architecture::iter().collect();
let architectures: Vec<ImageArch> = ImageArch::iter().collect();
let arch_index = Select::with_theme(&theme)
.with_prompt("Choose image architecture")
.default(0)
Expand Down Expand Up @@ -128,7 +122,7 @@ pub fn run(cmd: crate::cmd::Commands) -> Result<(), Box<dyn Error>> {
}

// Finally write out the config
std::fs::write(config_path, serde_yaml::to_string(&config)?)?;
std::fs::write(config_path, ron::to_string(&config)?)?;
Ok(())
}
_ => panic!(),
Expand Down
8 changes: 3 additions & 5 deletions goldboot/src/cli/cmd/registry.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,17 @@
use std::error::Error;

use crate::cmd::Commands;
use console::Style;
use dialoguer::{theme::ColorfulTheme, Confirm, Input, Select};
use std::error::Error;

use super::RegistryCommands;

pub fn run(cmd: crate::cmd::Commands) -> Result<(), Box<dyn Error>> {
pub fn run(cmd: super::Commands) -> Result<(), Box<dyn Error>> {
let theme = ColorfulTheme {
values_style: Style::new().yellow().dim(),
..ColorfulTheme::default()
};

match cmd {
Commands::Registry { command } => match &command {
super::Commands::Registry { command } => match &command {
RegistryCommands::Push { url } => todo!(),
RegistryCommands::Pull { url } => todo!(),
RegistryCommands::Login {} => {
Expand Down
5 changes: 2 additions & 3 deletions goldboot/src/cli/cmd/write.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
use crate::{cmd::Commands, library::ImageLibrary};
use console::Style;
use dialoguer::{theme::ColorfulTheme, Confirm, Input, Select};
use std::{error::Error, path::Path};

pub fn run(cmd: crate::cmd::Commands) -> Result<(), Box<dyn Error>> {
pub fn run(cmd: super::Commands) -> Result<(), Box<dyn Error>> {
match cmd {
Commands::Write {
super::Commands::Write {
image,
output,
confirm,
Expand Down
1 change: 1 addition & 0 deletions goldboot/src/cli/mod.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
pub mod cmd;
pub mod progress;
pub mod prompt;
18 changes: 18 additions & 0 deletions goldboot/src/cli/prompt.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
use std::error::Error;

pub trait Prompt {
fn prompt(
&mut self,
config: &BuildConfig,
theme: Box<dyn dialoguer::theme::Theme>,
) -> Result<(), Box<dyn Error>>;
}

pub trait PromptNew {
fn prompt(
config: &BuildConfig,
theme: Box<dyn dialoguer::theme::Theme>,
) -> Result<Self, Box<dyn Error>>
where
Self: Sized;
}
15 changes: 6 additions & 9 deletions goldboot/src/foundry/fabricators/ansible.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
use std::{error::Error, path::Path, process::Command};

use dialoguer::theme::ColorfulTheme;
use crate::{cli::prompt::Prompt, foundry::ssh::SshConnection};
use log::info;
use serde::{Deserialize, Serialize};
use simple_error::bail;
use std::{error::Error, path::Path, process::Command};
use validator::Validate;

use crate::{foundry::ssh::SshConnection, PromptMut};

/// Runs an Ansible playbook on the image remotely.
#[derive(Clone, Serialize, Deserialize, Validate, Debug)]
pub struct AnsibleFabricator {
Expand Down Expand Up @@ -47,18 +44,18 @@ impl AnsibleFabricator {
}
}

impl PromptMut for AnsibleFabricator {
impl Prompt for AnsibleFabricator {
fn prompt(
&mut self,
config: &BuildConfig,
theme: &ColorfulTheme,
theme: Box<dyn dialoguer::theme::Theme>,
) -> Result<(), Box<dyn Error>> {
self.playbook = dialoguer::Input::with_theme(theme)
self.playbook = dialoguer::Input::with_theme(&theme)
.with_prompt("Enter the playbook path relative to the current directory")
.interact()?;

if !Path::new(&self.playbook).exists() {
if !dialoguer::Confirm::with_theme(theme)
if !dialoguer::Confirm::with_theme(&theme)
.with_prompt("The path does not exist. Add anyway?")
.interact()?
{
Expand Down
13 changes: 4 additions & 9 deletions goldboot/src/foundry/fabricators/exe.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,8 @@
use std::{error::Error, path::Path};

use dialoguer::theme::ColorfulTheme;
use log::info;
use serde::{Deserialize, Serialize};
use simple_error::bail;
use validator::Validate;

use crate::{build::BuildConfig, ssh::SshConnection, PromptMut};

use super::Fabricator;

/// Runs an executable file.
Expand All @@ -28,18 +23,18 @@ impl ExecutableFabricator {
}
}

impl PromptMut for ExecutableFabricator {
impl Prompt for ExecutableFabricator {
fn prompt(
&mut self,
config: &BuildConfig,
theme: &ColorfulTheme,
theme: Box<dyn dialoguer::theme::Theme>,
) -> Result<(), Box<dyn Error>> {
self.path = dialoguer::Input::with_theme(theme)
self.path = dialoguer::Input::with_theme(&theme)
.with_prompt("Enter the script path relative to the current directory")
.interact()?;

if !Path::new(&self.path).exists() {
if !dialoguer::Confirm::with_theme(theme)
if !dialoguer::Confirm::with_theme(&theme)
.with_prompt("The path does not exist. Add anyway?")
.interact()?
{
Expand Down
2 changes: 1 addition & 1 deletion goldboot/src/foundry/fabricators/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//! image templates. Templates may also specify their own specialized
//! provisioners for specific tasks.
use crate::ssh::SshConnection;
use crate::foundry::ssh::SshConnection;
use std::error::Error;

pub mod ansible;
Expand Down
2 changes: 2 additions & 0 deletions goldboot/src/foundry/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ use simple_error::bail;
use std::{error::Error, fmt::Display, thread, time::SystemTime};
use validator::Validate;

use self::sources::Source;

pub mod fabricators;
pub mod mold;
pub mod ovmf;
Expand Down
6 changes: 3 additions & 3 deletions goldboot/src/foundry/mold/builtins/alpine_linux/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,16 +111,16 @@ iface eth0 inet dhcp
}
}

impl PromptMut for AlpineTemplate {
impl Prompt for AlpineLinux {
fn prompt(
&mut self,
config: &BuildConfig,
theme: &dialoguer::theme::ColorfulTheme,
theme: Box<dyn dialoguer::theme::Theme>,
) -> Result<(), Box<dyn Error>> {
// Prompt edition
{
let editions: Vec<AlpineEdition> = AlpineEdition::iter().collect();
let edition_index = dialoguer::Select::with_theme(theme)
let edition_index = dialoguer::Select::with_theme(&theme)
.with_prompt("Choose an edition")
.default(0)
.items(&editions)
Expand Down
29 changes: 14 additions & 15 deletions goldboot/src/foundry/mold/builtins/arch_linux/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,21 @@ use std::{
};
use validator::Validate;

use crate::foundry::{sources::Source, FoundryWorker};
use crate::wait;
use crate::{
enter,
foundry::{sources::Source, FoundryWorker},
wait_screen_rect,
};

use super::{ImageMold, ImageMoldInfo};
use super::{CastImage, ImageMold, ImageMoldInfo};

/// This `Mold` produces an [Arch Linux](https://archlinux.org) image.
#[derive(Clone, Serialize, Deserialize, Validate, Debug)]
pub struct ArchLinux {
pub root_password: Option<String>,
pub packages: Option<Vec<String>>,
pub mirrorlist: Option<Vec<String>>,
pub root_password: Option<RootPassword>,
pub packages: Option<Packages>,
pub mirrorlist: Option<Mirrorlist>,
pub hostname: Option<Hostname>,
}

Expand All @@ -30,7 +35,7 @@ impl Default for ArchLinux {
}
}

impl ImageMold for ArchLinux {
impl CastImage for ArchLinux {
fn info() -> ImageMoldInfo {

Check failure on line 39 in goldboot/src/foundry/mold/builtins/arch_linux/mod.rs

View workflow job for this annotation

GitHub Actions / Build Linux

method `info` is not a member of trait `CastImage`

Check failure on line 39 in goldboot/src/foundry/mold/builtins/arch_linux/mod.rs

View workflow job for this annotation

GitHub Actions / Build Windows

method `info` is not a member of trait `CastImage`

Check failure on line 39 in goldboot/src/foundry/mold/builtins/arch_linux/mod.rs

View workflow job for this annotation

GitHub Actions / Build macOS

method `info` is not a member of trait `CastImage`
ImageMoldInfo {
name: String::from("Arch Linux"),
Expand Down Expand Up @@ -93,12 +98,6 @@ pub mod options {
use serde::{Deserialize, Serialize};
use validator::Validate;

use crate::{
build::BuildConfig,
provisioners::{ansible::AnsibleProvisioner, hostname::HostnameProvisioner},
PromptMut,
};

#[derive(Clone, Serialize, Deserialize, Debug)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum ArchProvisioner {
Expand All @@ -125,15 +124,15 @@ pub mod options {
}
}

impl PromptMut for ArchMirrorlistProvisioner {
impl Prompt for ArchMirrorlist {
fn prompt(
&mut self,
config: &BuildConfig,
theme: &dialoguer::theme::ColorfulTheme,
theme: Box<dyn dialoguer::theme::Theme>,
) -> Result<(), Box<dyn Error>> {
// Prompt mirror list
{
let mirror_index = dialoguer::Select::with_theme(theme)
let mirror_index = dialoguer::Select::with_theme(&theme)
.with_prompt("Choose a mirror site")
.default(0)
.items(&MIRRORLIST)
Expand Down
Loading

0 comments on commit 82b5abf

Please sign in to comment.