Skip to content

Commit 82b5abf

Browse files
committed
wip: use enum dispatch in image mold
1 parent fbc190a commit 82b5abf

File tree

29 files changed

+173
-196
lines changed

29 files changed

+173
-196
lines changed

Cargo.lock

Lines changed: 14 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

goldboot-macros/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,5 @@ fn impl_prompt(ast: &syn::DeriveInput) -> TokenStream {
3636
};
3737
gen.into()
3838
}
39+
40+
// TODO probably need a macro for ImageMold and Fabricator

goldboot-registry/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,4 @@ rustls = "0.21.8"
1818
rustls-pemfile = "1.0.3"
1919
simple-error = "0.3.0"
2020
tokio = { version = "1.34.0", features = ["full"] }
21+
goldboot = { path="../goldboot", version = "0.0.1" }

goldboot/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ validator = { version = "0.16.1", features = ["derive"] }
4444
vnc = "0.4.0"
4545
whoami = "1.4.1"
4646
zstd = "0.13.0"
47+
enum_dispatch = "0.3.12"
4748

4849
[dev-dependencies]
4950
test-env-log = "0"

goldboot/src/cli/cmd/init.rs

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,25 @@
1-
use crate::{
2-
build::BuildConfig,
3-
cmd::Commands,
4-
templates::{Template, TemplateMetadata},
5-
Architecture,
6-
};
71
use console::Style;
82
use dialoguer::{theme::ColorfulTheme, Confirm, Input, Select};
3+
use goldboot_image::ImageArch;
94
use simple_error::bail;
105
use std::{error::Error, path::Path};
116
use strum::IntoEnumIterator;
127

13-
#[rustfmt::skip]
148
fn print_banner() {
159
if console::colors_enabled() {
1610
let style = Style::new().yellow();
1711

1812
println!("{}", "");
1913
for line in fossable::goldboot_word() {
20-
println!(" {}", style.apply_to(line));
21-
}
14+
println!(" {}", style.apply_to(line));
15+
}
2216
println!("{}", "");
2317
}
2418
}
2519

26-
pub fn run(cmd: crate::cmd::Commands) -> Result<(), Box<dyn Error>> {
20+
pub fn run(cmd: super::Commands) -> Result<(), Box<dyn Error>> {
2721
match cmd {
28-
Commands::Init {
22+
super::Commands::Init {
2923
name,
3024
template,
3125
mimic_hardware,
@@ -91,7 +85,7 @@ pub fn run(cmd: crate::cmd::Commands) -> Result<(), Box<dyn Error>> {
9185

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

130124
// Finally write out the config
131-
std::fs::write(config_path, serde_yaml::to_string(&config)?)?;
125+
std::fs::write(config_path, ron::to_string(&config)?)?;
132126
Ok(())
133127
}
134128
_ => panic!(),

goldboot/src/cli/cmd/registry.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,17 @@
1-
use std::error::Error;
2-
3-
use crate::cmd::Commands;
41
use console::Style;
52
use dialoguer::{theme::ColorfulTheme, Confirm, Input, Select};
3+
use std::error::Error;
64

75
use super::RegistryCommands;
86

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

1513
match cmd {
16-
Commands::Registry { command } => match &command {
14+
super::Commands::Registry { command } => match &command {
1715
RegistryCommands::Push { url } => todo!(),
1816
RegistryCommands::Pull { url } => todo!(),
1917
RegistryCommands::Login {} => {

goldboot/src/cli/cmd/write.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
1-
use crate::{cmd::Commands, library::ImageLibrary};
21
use console::Style;
32
use dialoguer::{theme::ColorfulTheme, Confirm, Input, Select};
43
use std::{error::Error, path::Path};
54

6-
pub fn run(cmd: crate::cmd::Commands) -> Result<(), Box<dyn Error>> {
5+
pub fn run(cmd: super::Commands) -> Result<(), Box<dyn Error>> {
76
match cmd {
8-
Commands::Write {
7+
super::Commands::Write {
98
image,
109
output,
1110
confirm,

goldboot/src/cli/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
pub mod cmd;
22
pub mod progress;
3+
pub mod prompt;

goldboot/src/cli/prompt.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
use std::error::Error;
2+
3+
pub trait Prompt {
4+
fn prompt(
5+
&mut self,
6+
config: &BuildConfig,
7+
theme: Box<dyn dialoguer::theme::Theme>,
8+
) -> Result<(), Box<dyn Error>>;
9+
}
10+
11+
pub trait PromptNew {
12+
fn prompt(
13+
config: &BuildConfig,
14+
theme: Box<dyn dialoguer::theme::Theme>,
15+
) -> Result<Self, Box<dyn Error>>
16+
where
17+
Self: Sized;
18+
}

goldboot/src/foundry/fabricators/ansible.rs

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,10 @@
1-
use std::{error::Error, path::Path, process::Command};
2-
3-
use dialoguer::theme::ColorfulTheme;
1+
use crate::{cli::prompt::Prompt, foundry::ssh::SshConnection};
42
use log::info;
53
use serde::{Deserialize, Serialize};
64
use simple_error::bail;
5+
use std::{error::Error, path::Path, process::Command};
76
use validator::Validate;
87

9-
use crate::{foundry::ssh::SshConnection, PromptMut};
10-
118
/// Runs an Ansible playbook on the image remotely.
129
#[derive(Clone, Serialize, Deserialize, Validate, Debug)]
1310
pub struct AnsibleFabricator {
@@ -47,18 +44,18 @@ impl AnsibleFabricator {
4744
}
4845
}
4946

50-
impl PromptMut for AnsibleFabricator {
47+
impl Prompt for AnsibleFabricator {
5148
fn prompt(
5249
&mut self,
5350
config: &BuildConfig,
54-
theme: &ColorfulTheme,
51+
theme: Box<dyn dialoguer::theme::Theme>,
5552
) -> Result<(), Box<dyn Error>> {
56-
self.playbook = dialoguer::Input::with_theme(theme)
53+
self.playbook = dialoguer::Input::with_theme(&theme)
5754
.with_prompt("Enter the playbook path relative to the current directory")
5855
.interact()?;
5956

6057
if !Path::new(&self.playbook).exists() {
61-
if !dialoguer::Confirm::with_theme(theme)
58+
if !dialoguer::Confirm::with_theme(&theme)
6259
.with_prompt("The path does not exist. Add anyway?")
6360
.interact()?
6461
{

goldboot/src/foundry/fabricators/exe.rs

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,8 @@
11
use std::{error::Error, path::Path};
2-
3-
use dialoguer::theme::ColorfulTheme;
42
use log::info;
53
use serde::{Deserialize, Serialize};
64
use simple_error::bail;
75
use validator::Validate;
8-
9-
use crate::{build::BuildConfig, ssh::SshConnection, PromptMut};
10-
116
use super::Fabricator;
127

138
/// Runs an executable file.
@@ -28,18 +23,18 @@ impl ExecutableFabricator {
2823
}
2924
}
3025

31-
impl PromptMut for ExecutableFabricator {
26+
impl Prompt for ExecutableFabricator {
3227
fn prompt(
3328
&mut self,
3429
config: &BuildConfig,
35-
theme: &ColorfulTheme,
30+
theme: Box<dyn dialoguer::theme::Theme>,
3631
) -> Result<(), Box<dyn Error>> {
37-
self.path = dialoguer::Input::with_theme(theme)
32+
self.path = dialoguer::Input::with_theme(&theme)
3833
.with_prompt("Enter the script path relative to the current directory")
3934
.interact()?;
4035

4136
if !Path::new(&self.path).exists() {
42-
if !dialoguer::Confirm::with_theme(theme)
37+
if !dialoguer::Confirm::with_theme(&theme)
4338
.with_prompt("The path does not exist. Add anyway?")
4439
.interact()?
4540
{

goldboot/src/foundry/fabricators/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//! image templates. Templates may also specify their own specialized
33
//! provisioners for specific tasks.
44
5-
use crate::ssh::SshConnection;
5+
use crate::foundry::ssh::SshConnection;
66
use std::error::Error;
77

88
pub mod ansible;

goldboot/src/foundry/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ use simple_error::bail;
77
use std::{error::Error, fmt::Display, thread, time::SystemTime};
88
use validator::Validate;
99

10+
use self::sources::Source;
11+
1012
pub mod fabricators;
1113
pub mod mold;
1214
pub mod ovmf;

goldboot/src/foundry/mold/builtins/alpine_linux/mod.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -111,16 +111,16 @@ iface eth0 inet dhcp
111111
}
112112
}
113113

114-
impl PromptMut for AlpineTemplate {
114+
impl Prompt for AlpineLinux {
115115
fn prompt(
116116
&mut self,
117117
config: &BuildConfig,
118-
theme: &dialoguer::theme::ColorfulTheme,
118+
theme: Box<dyn dialoguer::theme::Theme>,
119119
) -> Result<(), Box<dyn Error>> {
120120
// Prompt edition
121121
{
122122
let editions: Vec<AlpineEdition> = AlpineEdition::iter().collect();
123-
let edition_index = dialoguer::Select::with_theme(theme)
123+
let edition_index = dialoguer::Select::with_theme(&theme)
124124
.with_prompt("Choose an edition")
125125
.default(0)
126126
.items(&editions)

goldboot/src/foundry/mold/builtins/arch_linux/mod.rs

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,21 @@ use std::{
88
};
99
use validator::Validate;
1010

11-
use crate::foundry::{sources::Source, FoundryWorker};
11+
use crate::wait;
12+
use crate::{
13+
enter,
14+
foundry::{sources::Source, FoundryWorker},
15+
wait_screen_rect,
16+
};
1217

13-
use super::{ImageMold, ImageMoldInfo};
18+
use super::{CastImage, ImageMold, ImageMoldInfo};
1419

1520
/// This `Mold` produces an [Arch Linux](https://archlinux.org) image.
1621
#[derive(Clone, Serialize, Deserialize, Validate, Debug)]
1722
pub struct ArchLinux {
18-
pub root_password: Option<String>,
19-
pub packages: Option<Vec<String>>,
20-
pub mirrorlist: Option<Vec<String>>,
23+
pub root_password: Option<RootPassword>,
24+
pub packages: Option<Packages>,
25+
pub mirrorlist: Option<Mirrorlist>,
2126
pub hostname: Option<Hostname>,
2227
}
2328

@@ -30,7 +35,7 @@ impl Default for ArchLinux {
3035
}
3136
}
3237

33-
impl ImageMold for ArchLinux {
38+
impl CastImage for ArchLinux {
3439
fn info() -> ImageMoldInfo {
3540
ImageMoldInfo {
3641
name: String::from("Arch Linux"),
@@ -93,12 +98,6 @@ pub mod options {
9398
use serde::{Deserialize, Serialize};
9499
use validator::Validate;
95100

96-
use crate::{
97-
build::BuildConfig,
98-
provisioners::{ansible::AnsibleProvisioner, hostname::HostnameProvisioner},
99-
PromptMut,
100-
};
101-
102101
#[derive(Clone, Serialize, Deserialize, Debug)]
103102
#[serde(tag = "type", rename_all = "snake_case")]
104103
pub enum ArchProvisioner {
@@ -125,15 +124,15 @@ pub mod options {
125124
}
126125
}
127126

128-
impl PromptMut for ArchMirrorlistProvisioner {
127+
impl Prompt for ArchMirrorlist {
129128
fn prompt(
130129
&mut self,
131130
config: &BuildConfig,
132-
theme: &dialoguer::theme::ColorfulTheme,
131+
theme: Box<dyn dialoguer::theme::Theme>,
133132
) -> Result<(), Box<dyn Error>> {
134133
// Prompt mirror list
135134
{
136-
let mirror_index = dialoguer::Select::with_theme(theme)
135+
let mirror_index = dialoguer::Select::with_theme(&theme)
137136
.with_prompt("Choose a mirror site")
138137
.default(0)
139138
.items(&MIRRORLIST)

0 commit comments

Comments
 (0)