[PATCH installer v3 31/38] tree-wide: switch to filesystem types from proxmox-installer-types

Christoph Heiss
2026-04-03T16:57:04Z

No functional changes.

Signed-off-by: Christoph Heiss <c.heiss@proxmox.com>
---
Changes v2 -> v3:
* new patch

Cargo.toml | 2 +
proxmox-auto-installer/Cargo.toml | 1 +
proxmox-auto-installer/src/answer.rs | 26 ++-
proxmox-auto-installer/src/utils.rs | 16 +-
proxmox-chroot/Cargo.toml | 1 +
proxmox-chroot/src/main.rs | 60 ++----
proxmox-installer-common/Cargo.toml | 1 +
proxmox-installer-common/src/options.rs | 197 ++++----------------
proxmox-installer-common/src/setup.rs | 5 +-
proxmox-post-hook/Cargo.toml | 1 +
proxmox-post-hook/src/main.rs | 37 ++--
proxmox-tui-installer/Cargo.toml | 1 +
proxmox-tui-installer/src/options.rs | 21 +--
proxmox-tui-installer/src/views/bootdisk.rs | 30 +--
14 files changed, 132 insertions(+), 267 deletions(-)

diff --git a/Cargo.toml b/Cargo.toml
index 379ee6b..9d95796 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -28,8 +28,10 @@ toml = "0.8"
proxmox-auto-installer.path = "./proxmox-auto-installer"
proxmox-installer-common.path = "./proxmox-installer-common"
proxmox-network-types = "1.0"
+proxmox-installer-types = "0.1"

# Local path overrides
# NOTE: You must run `cargo update` after changing this for it to take effect!
[patch.crates-io]
# proxmox-network-types.path = "../proxmox/proxmox-network-types"
+# proxmox-installer-types.path = "../proxmox/proxmox-installer-types"
diff --git a/proxmox-auto-installer/Cargo.toml b/proxmox-auto-installer/Cargo.toml
index 0086e5d..5ef2f4f 100644
--- a/proxmox-auto-installer/Cargo.toml
+++ b/proxmox-auto-installer/Cargo.toml
@@ -15,6 +15,7 @@ anyhow.workspace = true
log.workspace = true
proxmox-installer-common = { workspace = true, features = ["http"] }
proxmox-network-types.workspace = true
+proxmox-installer-types.workspace = true
serde = { workspace = true, features = ["derive"] }
serde_json.workspace = true
serde_plain.workspace = true
diff --git a/proxmox-auto-installer/src/answer.rs b/proxmox-auto-installer/src/answer.rs
index acb0d5b..eec5b58 100644
--- a/proxmox-auto-installer/src/answer.rs
+++ b/proxmox-auto-installer/src/answer.rs
@@ -7,9 +7,9 @@ use std::{
};

use proxmox_installer_common::options::{
- BtrfsCompressOption, BtrfsRaidLevel, FsType, NetworkInterfacePinningOptions, ZfsChecksumOption,
- ZfsCompressOption, ZfsRaidLevel,
+ BtrfsCompressOption, NetworkInterfacePinningOptions, ZfsChecksumOption, ZfsCompressOption,
};
+use proxmox_installer_types::answer::{BtrfsRaidLevel, FilesystemType, ZfsRaidLevel};
use proxmox_network_types::{Cidr, fqdn::Fqdn};

// NOTE New answer file properties must use kebab-case, but should allow snake_case for backwards
@@ -314,7 +314,7 @@ pub struct DiskSetup {
#[derive(Clone, Debug, Deserialize)]
#[serde(try_from = "DiskSetup", deny_unknown_fields)]
pub struct Disks {
- pub fs_type: FsType,
+ pub fs_type: FilesystemType,
pub disk_selection: DiskSelection,
pub filter_match: Option<FilterMatch>,
pub fs_options: FsOptions,
@@ -351,11 +351,17 @@ impl TryFrom<DiskSetup> for Disks {
let (fs, fs_options) = match source.filesystem {
Filesystem::Xfs => {
lvm_checks(&source)?;
- (FsType::Xfs, FsOptions::LVM(source.lvm.unwrap_or_default()))
+ (
+ FilesystemType::Xfs,
+ FsOptions::LVM(source.lvm.unwrap_or_default()),
+ )
}
Filesystem::Ext4 => {
lvm_checks(&source)?;
- (FsType::Ext4, FsOptions::LVM(source.lvm.unwrap_or_default()))
+ (
+ FilesystemType::Ext4,
+ FsOptions::LVM(source.lvm.unwrap_or_default()),
+ )
}
Filesystem::Zfs => {
if source.lvm.is_some() || source.btrfs.is_some() {
@@ -365,7 +371,10 @@ impl TryFrom<DiskSetup> for Disks {
None | Some(ZfsOptions { raid: None, .. }) => {
return Err("ZFS raid level 'zfs.raid' must be set");
}
- Some(opts) => (FsType::Zfs(opts.raid.unwrap()), FsOptions::ZFS(opts)),
+ Some(opts) => (
+ FilesystemType::Zfs(opts.raid.unwrap()),
+ FsOptions::ZFS(opts),
+ ),
}
}
Filesystem::Btrfs => {
@@ -376,7 +385,10 @@ impl TryFrom<DiskSetup> for Disks {
None | Some(BtrfsOptions { raid: None, .. }) => {
return Err("BTRFS raid level 'btrfs.raid' must be set");
}
- Some(opts) => (FsType::Btrfs(opts.raid.unwrap()), FsOptions::BTRFS(opts)),
+ Some(opts) => (
+ FilesystemType::Btrfs(opts.raid.unwrap()),
+ FsOptions::BTRFS(opts),
+ ),
}
}
};
diff --git a/proxmox-auto-installer/src/utils.rs b/proxmox-auto-installer/src/utils.rs
index f9cfcdd..83be913 100644
--- a/proxmox-auto-installer/src/utils.rs
+++ b/proxmox-auto-installer/src/utils.rs
@@ -16,12 +16,13 @@ use crate::{
use proxmox_installer_common::{
ROOT_PASSWORD_MIN_LENGTH,
disk_checks::check_swapsize,
- options::{FsType, NetworkOptions, ZfsChecksumOption, ZfsCompressOption, email_validate},
+ options::{NetworkOptions, RaidLevel, ZfsChecksumOption, ZfsCompressOption, email_validate},
setup::{
InstallBtrfsOption, InstallConfig, InstallFirstBootSetup, InstallRootPassword,
InstallZfsOption, LocaleInfo, RuntimeInfo, SetupInfo,
},
};
+use proxmox_installer_types::answer::FilesystemType;
use serde::{Deserialize, Serialize};

fn get_network_settings(
@@ -211,8 +212,10 @@ fn set_disks(
config: &mut InstallConfig,
) -> Result<()> {
match config.filesys {
- FsType::Ext4 | FsType::Xfs => set_single_disk(answer, udev_info, runtime_info, config),
- FsType::Zfs(_) | FsType::Btrfs(_) => {
+ FilesystemType::Ext4 | FilesystemType::Xfs => {
+ set_single_disk(answer, udev_info, runtime_info, config)
+ }
+ FilesystemType::Zfs(_) | FilesystemType::Btrfs(_) => {
set_selected_disks(answer, udev_info, runtime_info, config)
}
}
@@ -410,7 +413,12 @@ pub fn verify_email_and_root_password_settings(answer: &Answer) -> Result<()> {

pub fn verify_disks_settings(answer: &Answer) -> Result<()> {
if let DiskSelection::Selection(selection) = &answer.disks.disk_selection {
- let min_disks = answer.disks.fs_type.get_min_disks();
+ let min_disks = match answer.disks.fs_type {
+ FilesystemType::Ext4 | FilesystemType::Xfs => 1,
+ FilesystemType::Zfs(level) => level.get_min_disks(),
+ FilesystemType::Btrfs(level) => level.get_min_disks(),
+ };
+
if selection.len() < min_disks {
bail!(
"{}: need at least {} disks",
diff --git a/proxmox-chroot/Cargo.toml b/proxmox-chroot/Cargo.toml
index a6a705d..e1e0e4c 100644
--- a/proxmox-chroot/Cargo.toml
+++ b/proxmox-chroot/Cargo.toml
@@ -10,5 +10,6 @@ homepage = "https://www.proxmox.com"
[dependencies]
anyhow.workspace = true
proxmox-installer-common = { workspace = true, features = [ "cli" ] }
+proxmox-installer-types.workspace = true
serde = { workspace = true, features = [ "derive" ] }
serde_json.workspace = true
diff --git a/proxmox-chroot/src/main.rs b/proxmox-chroot/src/main.rs
index 2cff630..5f087bb 100644
--- a/proxmox-chroot/src/main.rs
+++ b/proxmox-chroot/src/main.rs
@@ -5,20 +5,19 @@

#![forbid(unsafe_code)]

+use anyhow::{Result, bail};
+use serde::Deserialize;
use std::{
env, fs, io,
path::{self, Path, PathBuf},
process::{self, Command},
- str::FromStr,
};

-use anyhow::{Result, bail};
use proxmox_installer_common::{
RUNTIME_DIR, cli,
- options::FsType,
setup::{InstallConfig, SetupInfo},
};
-use serde::Deserialize;
+use proxmox_installer_types::answer::Filesystem;

const ANSWER_MP: &str = "answer";
static BINDMOUNTS: [&str; 4] = ["dev", "proc", "run", "sys"];
@@ -29,7 +28,7 @@ const ZPOOL_NAME: &str = "rpool";
struct CommandPrepareArgs {
/// Filesystem used for the installation. Will try to automatically detect it after a
/// successful installation.
- filesystem: Option<Filesystems>,
+ filesystem: Option<Filesystem>,

/// Numerical ID of the `rpool` ZFS pool to import. Needed if multiple pools of name `rpool`
/// are present.
@@ -74,7 +73,7 @@ OPTIONS:
/// Arguments for the `cleanup` command.
struct CommandCleanupArgs {
/// Filesystem used for the installation. Will try to automatically detect it by default.
- filesystem: Option<Filesystems>,
+ filesystem: Option<Filesystem>,
}

impl cli::Subcommand for CommandCleanupArgs {
@@ -105,39 +104,6 @@ OPTIONS:
}
}

-#[derive(Copy, Clone, Debug)]
-enum Filesystems {
- Zfs,
- Ext4,
- Xfs,
- Btrfs,
-}
-
-impl From<FsType> for Filesystems {
- fn from(fs: FsType) -> Self {
- match fs {
- FsType::Xfs => Self::Xfs,
- FsType::Ext4 => Self::Ext4,
- FsType::Zfs(_) => Self::Zfs,
- FsType::Btrfs(_) => Self::Btrfs,
- }
- }
-}
-
-impl FromStr for Filesystems {
- type Err = anyhow::Error;
-
- fn from_str(s: &str) -> Result<Self> {
- match s {
- "ext4" => Ok(Filesystems::Ext4),
- "xfs" => Ok(Filesystems::Xfs),
- _ if s.starts_with("zfs") => Ok(Filesystems::Zfs),
- _ if s.starts_with("btrfs") => Ok(Filesystems::Btrfs),
- _ => bail!("unknown filesystem"),
- }
- }
-}
-
fn main() -> process::ExitCode {
cli::run(cli::AppInfo {
global_help: &format!(
@@ -171,10 +137,10 @@ fn prepare(args: &CommandPrepareArgs) -> Result<()> {
fs::create_dir_all(TARGET_DIR)?;

match fs {
- Filesystems::Zfs => mount_zpool(args.rpool_id)?,
- Filesystems::Xfs => mount_fs()?,
- Filesystems::Ext4 => mount_fs()?,
- Filesystems::Btrfs => mount_btrfs(args.btrfs_uuid.clone())?,
+ Filesystem::Zfs => mount_zpool(args.rpool_id)?,
+ Filesystem::Xfs => mount_fs()?,
+ Filesystem::Ext4 => mount_fs()?,
+ Filesystem::Btrfs => mount_btrfs(args.btrfs_uuid.clone())?,
}

if let Err(e) = bindmount() {
@@ -193,15 +159,15 @@ fn cleanup(args: &CommandCleanupArgs) -> Result<()> {
}

match fs {
- Filesystems::Zfs => umount_zpool(),
- Filesystems::Btrfs | Filesystems::Xfs | Filesystems::Ext4 => umount(Path::new(TARGET_DIR))?,
+ Filesystem::Zfs => umount_zpool(),
+ Filesystem::Btrfs | Filesystem::Xfs | Filesystem::Ext4 => umount(Path::new(TARGET_DIR))?,
}

println!("Chroot cleanup done. You can now reboot or leave the shell.");
Ok(())
}

-fn get_fs(filesystem: Option<Filesystems>) -> Result<Filesystems> {
+fn get_fs(filesystem: Option<Filesystem>) -> Result<Filesystem> {
let fs = match filesystem {
None => {
let low_level_config = match get_low_level_config() {
@@ -210,7 +176,7 @@ fn get_fs(filesystem: Option<Filesystems>) -> Result<Filesystems> {
"Could not fetch config from previous installation. Please specify file system with -f."
),
};
- Filesystems::from(low_level_config.filesys)
+ low_level_config.filesys.into()
}
Some(fs) => fs,
};
diff --git a/proxmox-installer-common/Cargo.toml b/proxmox-installer-common/Cargo.toml
index 7469627..7682680 100644
--- a/proxmox-installer-common/Cargo.toml
+++ b/proxmox-installer-common/Cargo.toml
@@ -14,6 +14,7 @@ serde = { workspace = true, features = [ "derive" ] }
serde_json.workspace = true
serde_plain.workspace = true
proxmox-network-types.workspace = true
+proxmox-installer-types.workspace = true

# `http` feature
hex = { version = "0.4", optional = true }
diff --git a/proxmox-installer-common/src/options.rs b/proxmox-installer-common/src/options.rs
index f903f7e..8e19663 100644
--- a/proxmox-installer-common/src/options.rs
+++ b/proxmox-installer-common/src/options.rs
@@ -1,36 +1,23 @@
use anyhow::{Result, bail};
use regex::{Regex, RegexBuilder};
use serde::{Deserialize, Serialize};
-use std::collections::HashMap;
-use std::net::{IpAddr, Ipv4Addr};
-use std::str::FromStr;
-use std::sync::OnceLock;
-use std::{cmp, fmt};
+use std::{
+ cmp,
+ collections::HashMap,
+ fmt,
+ net::{IpAddr, Ipv4Addr},
+ sync::OnceLock,
+};

use crate::disk_checks::check_raid_min_disks;
use crate::net::{MAX_IFNAME_LEN, MIN_IFNAME_LEN};
use crate::setup::{LocaleInfo, NetworkInfo, RuntimeInfo, SetupInfo};
+use proxmox_installer_types::answer::{BtrfsRaidLevel, FilesystemType, ZfsRaidLevel};
use proxmox_network_types::{fqdn::Fqdn, ip_address::Cidr};

-#[derive(Copy, Clone, Debug, Deserialize, Serialize, Eq, PartialEq)]
-#[serde(rename_all(deserialize = "lowercase", serialize = "UPPERCASE"))]
-pub enum BtrfsRaidLevel {
- #[serde(alias = "RAID0")]
- Raid0,
- #[serde(alias = "RAID1")]
- Raid1,
- #[serde(alias = "RAID10")]
- Raid10,
-}
-
-impl BtrfsRaidLevel {
- pub fn get_min_disks(&self) -> usize {
- match self {
- BtrfsRaidLevel::Raid0 => 1,
- BtrfsRaidLevel::Raid1 => 2,
- BtrfsRaidLevel::Raid10 => 4,
- }
- }
+pub trait RaidLevel {
+ /// Returns the minimum number of disks needed for this RAID level.
+ fn get_min_disks(&self) -> usize;

/// Checks whether a user-supplied Btrfs RAID setup is valid or not, such as minimum
/// number of disks.
@@ -38,42 +25,31 @@ impl BtrfsRaidLevel {
/// # Arguments
///
/// * `disks` - List of disks designated as RAID targets.
- pub fn check_raid_disks_setup(&self, disks: &[Disk]) -> Result<(), String> {
+ fn check_raid_disks_setup(&self, disks: &[Disk]) -> Result<(), String>;
+
+ /// Checks whether the given disk sizes are compatible for the RAID level, if it is a mirror.
+ fn check_mirror_size(&self, _disk1: &Disk, _disk2: &Disk) -> Result<(), String> {
+ Ok(())
+ }
+}
+
+impl RaidLevel for BtrfsRaidLevel {
+ fn get_min_disks(&self) -> usize {
+ match self {
+ Self::Raid0 => 1,
+ Self::Raid1 => 2,
+ Self::Raid10 => 4,
+ }
+ }
+
+ fn check_raid_disks_setup(&self, disks: &[Disk]) -> Result<(), String> {
check_raid_min_disks(disks, self.get_min_disks())?;
Ok(())
}
}

-serde_plain::derive_display_from_serialize!(BtrfsRaidLevel);
-
-#[derive(Copy, Clone, Debug, Deserialize, Serialize, Eq, PartialEq)]
-#[serde(rename_all(deserialize = "lowercase", serialize = "UPPERCASE"))]
-pub enum ZfsRaidLevel {
- #[serde(alias = "RAID0")]
- Raid0,
- #[serde(alias = "RAID1")]
- Raid1,
- #[serde(alias = "RAID10")]
- Raid10,
- #[serde(
- alias = "RAIDZ-1",
- rename(deserialize = "raidz-1", serialize = "RAIDZ-1")
- )]
- RaidZ,
- #[serde(
- alias = "RAIDZ-2",
- rename(deserialize = "raidz-2", serialize = "RAIDZ-2")
- )]
- RaidZ2,
- #[serde(
- alias = "RAIDZ-3",
- rename(deserialize = "raidz-3", serialize = "RAIDZ-3")
- )]
- RaidZ3,
-}
-
-impl ZfsRaidLevel {
- pub fn get_min_disks(&self) -> usize {
+impl RaidLevel for ZfsRaidLevel {
+ fn get_min_disks(&self) -> usize {
match self {
ZfsRaidLevel::Raid0 => 1,
ZfsRaidLevel::Raid1 => 2,
@@ -84,23 +60,7 @@ impl ZfsRaidLevel {
}
}

- fn check_mirror_size(&self, disk1: &Disk, disk2: &Disk) -> Result<(), String> {
- if (disk1.size - disk2.size).abs() > disk1.size / 10. {
- Err(format!(
- "Mirrored disks must have same size:\n\n * {disk1}\n * {disk2}"
- ))
- } else {
- Ok(())
- }
- }
-
- /// Checks whether a user-supplied ZFS RAID setup is valid or not, such as disk sizes andminimum
- /// number of disks.
- ///
- /// # Arguments
- ///
- /// * `disks` - List of disks designated as RAID targets.
- pub fn check_raid_disks_setup(&self, disks: &[Disk]) -> Result<(), String> {
+ fn check_raid_disks_setup(&self, disks: &[Disk]) -> Result<(), String> {
check_raid_min_disks(disks, self.get_min_disks())?;

match self {
@@ -130,93 +90,18 @@ impl ZfsRaidLevel {

Ok(())
}
-}

-serde_plain::derive_display_from_serialize!(ZfsRaidLevel);
-
-#[derive(Copy, Clone, Debug, Eq, PartialEq)]
-pub enum FsType {
- Ext4,
- Xfs,
- Zfs(ZfsRaidLevel),
- Btrfs(BtrfsRaidLevel),
-}
-
-impl FsType {
- pub fn is_btrfs(&self) -> bool {
- matches!(self, FsType::Btrfs(_))
- }
-
- /// Returns true if the filesystem is used on top of LVM, e.g. ext4 or XFS.
- pub fn is_lvm(&self) -> bool {
- matches!(self, FsType::Ext4 | FsType::Xfs)
- }
-
- pub fn get_min_disks(&self) -> usize {
- match self {
- FsType::Ext4 => 1,
- FsType::Xfs => 1,
- FsType::Zfs(level) => level.get_min_disks(),
- FsType::Btrfs(level) => level.get_min_disks(),
+ fn check_mirror_size(&self, disk1: &Disk, disk2: &Disk) -> Result<(), String> {
+ if (disk1.size - disk2.size).abs() > disk1.size / 10. {
+ Err(format!(
+ "Mirrored disks must have same size:\n\n * {disk1}\n * {disk2}"
+ ))
+ } else {
+ Ok(())
}
}
}

-impl fmt::Display for FsType {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- // Values displayed to the user in the installer UI
- match self {
- FsType::Ext4 => write!(f, "ext4"),
- FsType::Xfs => write!(f, "XFS"),
- FsType::Zfs(level) => write!(f, "ZFS ({level})"),
- FsType::Btrfs(level) => write!(f, "BTRFS ({level})"),
- }
- }
-}
-
-impl Serialize for FsType {
- fn serialize(&self, serializer: S) -> Result<S::Ok, S::Error>
- where
- S: serde::Serializer,
- {
- // These values must match exactly what the low-level installer expects
- let value = match self {
- // proxinstall::$fssetup
- FsType::Ext4 => "ext4",
- FsType::Xfs => "xfs",
- // proxinstall::get_zfs_raid_setup()
- FsType::Zfs(level) => &format!("zfs ({level})"),
- // proxinstall::get_btrfs_raid_setup()
- FsType::Btrfs(level) => &format!("btrfs ({level})"),
- };
-
- serializer.collect_str(value)
- }
-}
-
-impl FromStr for FsType {
- type Err = String;
-
- fn from_str(s: &str) -> Result<Self, Self::Err> {
- match s {
- "ext4" => Ok(FsType::Ext4),
- "xfs" => Ok(FsType::Xfs),
- "zfs (RAID0)" => Ok(FsType::Zfs(ZfsRaidLevel::Raid0)),
- "zfs (RAID1)" => Ok(FsType::Zfs(ZfsRaidLevel::Raid1)),
- "zfs (RAID10)" => Ok(FsType::Zfs(ZfsRaidLevel::Raid10)),
- "zfs (RAIDZ-1)" => Ok(FsType::Zfs(ZfsRaidLevel::RaidZ)),
- "zfs (RAIDZ-2)" => Ok(FsType::Zfs(ZfsRaidLevel::RaidZ2)),
- "zfs (RAIDZ-3)" => Ok(FsType::Zfs(ZfsRaidLevel::RaidZ3)),
- "btrfs (RAID0)" => Ok(FsType::Btrfs(BtrfsRaidLevel::Raid0)),
- "btrfs (RAID1)" => Ok(FsType::Btrfs(BtrfsRaidLevel::Raid1)),
- "btrfs (RAID10)" => Ok(FsType::Btrfs(BtrfsRaidLevel::Raid10)),
- _ => Err(format!("Could not find file system: {s}")),
- }
- }
-}
-
-serde_plain::derive_deserialize_from_fromstr!(FsType, "valid filesystem");
-
#[derive(Clone, Debug)]
pub struct LvmBootdiskOptions {
pub total_size: f64,
@@ -426,7 +311,7 @@ impl cmp::Ord for Disk {
#[derive(Clone, Debug)]
pub struct BootdiskOptions {
pub disks: Vec<Disk>,
- pub fstype: FsType,
+ pub fstype: FilesystemType,
pub advanced: AdvancedBootdiskOptions,
}

@@ -434,7 +319,7 @@ impl BootdiskOptions {
pub fn defaults_from(disk: &Disk) -> Self {
Self {
disks: vec![disk.clone()],
- fstype: FsType::Ext4,
+ fstype: FilesystemType::Ext4,
advanced: AdvancedBootdiskOptions::Lvm(LvmBootdiskOptions::defaults_from(disk)),
}
}
diff --git a/proxmox-installer-common/src/setup.rs b/proxmox-installer-common/src/setup.rs
index 35a5436..91f1250 100644
--- a/proxmox-installer-common/src/setup.rs
+++ b/proxmox-installer-common/src/setup.rs
@@ -14,9 +14,10 @@ use proxmox_network_types::Cidr;
use serde::{Deserialize, Deserializer, Serialize, Serializer, de};

use crate::options::{
- BtrfsBootdiskOptions, BtrfsCompressOption, Disk, FsType, NetworkInterfacePinningOptions,
+ BtrfsBootdiskOptions, BtrfsCompressOption, Disk, NetworkInterfacePinningOptions,
ZfsBootdiskOptions, ZfsChecksumOption, ZfsCompressOption,
};
+use proxmox_installer_types::answer::FilesystemType;

#[allow(clippy::upper_case_acronyms)]
#[derive(Debug, Clone, Copy, Deserialize, PartialEq, Serialize)]
@@ -565,7 +566,7 @@ pub fn spawn_low_level_installer(test_mode: bool) -> io::Result<process::Child>
pub struct InstallConfig {
pub autoreboot: usize,

- pub filesys: FsType,
+ pub filesys: FilesystemType,
pub hdsize: f64,
#[serde(skip_serializing_if = "Option::is_none")]
pub swapsize: Option<f64>,
diff --git a/proxmox-post-hook/Cargo.toml b/proxmox-post-hook/Cargo.toml
index beaaa26..f0c344e 100644
--- a/proxmox-post-hook/Cargo.toml
+++ b/proxmox-post-hook/Cargo.toml
@@ -15,5 +15,6 @@ anyhow.workspace = true
proxmox-auto-installer.workspace = true
proxmox-installer-common = { workspace = true, features = ["http"] }
proxmox-network-types.workspace = true
+proxmox-installer-types.workspace = true
serde = { workspace = true, features = ["derive"] }
serde_json.workspace = true
diff --git a/proxmox-post-hook/src/main.rs b/proxmox-post-hook/src/main.rs
index 71fdde2..a05b30f 100644
--- a/proxmox-post-hook/src/main.rs
+++ b/proxmox-post-hook/src/main.rs
@@ -10,6 +10,24 @@
//! previously installed system.

use anyhow::{Context, Result, anyhow, bail};
+use proxmox_auto_installer::{
+ answer::{
+ Answer, FqdnConfig, FqdnExtendedConfig, FqdnSourceMode, PostNotificationHookInfo,
+ RebootMode,
+ },
+ udevinfo::{UdevInfo, UdevProperties},
+};
+use proxmox_installer_common::http::{self, header::HeaderMap};
+use proxmox_installer_common::{
+ options::{Disk, NetworkOptions},
+ setup::{
+ BootType, InstallConfig, IsoInfo, ProxmoxProduct, RuntimeInfo, SetupInfo,
+ load_installer_setup_files,
+ },
+ sysinfo::SystemDMI,
+};
+use proxmox_installer_types::answer::FilesystemType;
+use proxmox_network_types::ip_address::Cidr;
use serde::Serialize;
use std::{
collections::HashSet,
@@ -20,23 +38,6 @@ use std::{
path::PathBuf,
process::{Command, ExitCode},
};
-use proxmox_auto_installer::{
- answer::{
- Answer, FqdnConfig, FqdnExtendedConfig, FqdnSourceMode, PostNotificationHookInfo,
- RebootMode,
- },
- udevinfo::{UdevInfo, UdevProperties},
-};
-use proxmox_installer_common::http::{self, header::HeaderMap};
-use proxmox_installer_common::{
- options::{Disk, FsType, NetworkOptions},
- setup::{
- BootType, InstallConfig, IsoInfo, ProxmoxProduct, RuntimeInfo, SetupInfo,
- load_installer_setup_files,
- },
- sysinfo::SystemDMI,
-};
-use proxmox_network_types::ip_address::Cidr;

/// Information about the system boot status.
#[derive(Serialize)]
@@ -195,7 +196,7 @@ struct PostHookInfo {
/// DMI information about the system
dmi: SystemDMI,
/// Filesystem used for boot disk(s)
- filesystem: FsType,
+ filesystem: FilesystemType,
/// Fully qualified domain name of the installed system
fqdn: String,
/// Unique systemd-id128 identifier of the installed system (128-bit, 16 bytes)
diff --git a/proxmox-tui-installer/Cargo.toml b/proxmox-tui-installer/Cargo.toml
index 1ca91cb..56395a4 100644
--- a/proxmox-tui-installer/Cargo.toml
+++ b/proxmox-tui-installer/Cargo.toml
@@ -10,6 +10,7 @@ homepage = "https://www.proxmox.com"
[dependencies]
proxmox-installer-common.workspace = true
proxmox-network-types.workspace = true
+proxmox-installer-types.workspace = true
anyhow.workspace = true
serde_json.workspace = true

diff --git a/proxmox-tui-installer/src/options.rs b/proxmox-tui-installer/src/options.rs
index c80877f..ff15fa0 100644
--- a/proxmox-tui-installer/src/options.rs
+++ b/proxmox-tui-installer/src/options.rs
@@ -2,29 +2,10 @@ use crate::SummaryOption;

use proxmox_installer_common::{
EMAIL_DEFAULT_PLACEHOLDER,
- options::{
- BootdiskOptions, BtrfsRaidLevel, FsType, NetworkOptions, TimezoneOptions, ZfsRaidLevel,
- },
+ options::{BootdiskOptions, NetworkOptions, TimezoneOptions},
setup::LocaleInfo,
};

-pub const FS_TYPES: &[FsType] = {
- use FsType::*;
- &[
- Ext4,
- Xfs,
- Zfs(ZfsRaidLevel::Raid0),
- Zfs(ZfsRaidLevel::Raid1),
- Zfs(ZfsRaidLevel::Raid10),
- Zfs(ZfsRaidLevel::RaidZ),
- Zfs(ZfsRaidLevel::RaidZ2),
- Zfs(ZfsRaidLevel::RaidZ3),
- Btrfs(BtrfsRaidLevel::Raid0),
- Btrfs(BtrfsRaidLevel::Raid1),
- Btrfs(BtrfsRaidLevel::Raid10),
- ]
-};
-
#[derive(Clone)]
pub struct PasswordOptions {
pub email: String,
diff --git a/proxmox-tui-installer/src/views/bootdisk.rs b/proxmox-tui-installer/src/views/bootdisk.rs
index 5ec3e83..ed3936f 100644
--- a/proxmox-tui-installer/src/views/bootdisk.rs
+++ b/proxmox-tui-installer/src/views/bootdisk.rs
@@ -16,7 +16,6 @@ use cursive::{

use super::{DiskSizeEditView, FormView, IntegerEditView, TabbedView};
use crate::InstallerState;
-use crate::options::FS_TYPES;

use proxmox_installer_common::{
disk_checks::{
@@ -24,11 +23,12 @@ use proxmox_installer_common::{
},
options::{
AdvancedBootdiskOptions, BTRFS_COMPRESS_OPTIONS, BootdiskOptions, BtrfsBootdiskOptions,
- Disk, FsType, LvmBootdiskOptions, ZFS_CHECKSUM_OPTIONS, ZFS_COMPRESS_OPTIONS,
+ Disk, LvmBootdiskOptions, RaidLevel, ZFS_CHECKSUM_OPTIONS, ZFS_COMPRESS_OPTIONS,
ZfsBootdiskOptions,
},
setup::{BootType, ProductConfig, ProxmoxProduct, RuntimeInfo},
};
+use proxmox_installer_types::answer::{FILESYSTEM_TYPE_OPTIONS, FilesystemType};

/// OpenZFS specifies 64 MiB as the absolute minimum:
/// <https://openzfs.github.io/openzfs-docs/Performance%20and%20Tuning/Module%20Parameters.html#zfs-arc-max>
@@ -125,19 +125,19 @@ impl AdvancedBootdiskOptionsView {
product_conf: ProductConfig,
) -> Self {
let filter_btrfs =
- |fstype: &&FsType| -> bool { product_conf.enable_btrfs || !fstype.is_btrfs() };
+ |fstype: &&FilesystemType| -> bool { product_conf.enable_btrfs || !fstype.is_btrfs() };
let options = options_ref.lock().unwrap();

let fstype_select = SelectView::new()
.popup()
.with_all(
- FS_TYPES
+ FILESYSTEM_TYPE_OPTIONS
.iter()
.filter(filter_btrfs)
.map(|t| (t.to_string(), *t)),
)
.selected(
- FS_TYPES
+ FILESYSTEM_TYPE_OPTIONS
.iter()
.filter(filter_btrfs)
.position(|t| *t == options.fstype)
@@ -185,7 +185,11 @@ impl AdvancedBootdiskOptionsView {
/// * `fstype` - The chosen filesystem type by the user, for which the UI should be
/// updated accordingly
/// * `options_ref` - [`BootdiskOptionsRef`] where advanced disk options should be saved to
- fn fstype_on_submit(siv: &mut Cursive, fstype: &FsType, options_ref: BootdiskOptionsRef) {
+ fn fstype_on_submit(
+ siv: &mut Cursive,
+ fstype: &FilesystemType,
+ options_ref: BootdiskOptionsRef,
+ ) {
let state = siv.user_data::<InstallerState>().unwrap();
let runinfo = state.runtime_info.clone();
let product_conf = state.setup_info.config.clone();
@@ -208,16 +212,16 @@ impl AdvancedBootdiskOptionsView {
{
view.remove_child(3);
match fstype {
- FsType::Ext4 | FsType::Xfs => {
+ FilesystemType::Ext4 | FilesystemType::Xfs => {
view.add_child(LvmBootdiskOptionsView::new_with_defaults(
&selected_lvm_disk,
&product_conf,
))
}
- FsType::Zfs(_) => {
+ FilesystemType::Zfs(_) => {
view.add_child(ZfsBootdiskOptionsView::new_with_defaults(&runinfo))
}
- FsType::Btrfs(_) => {
+ FilesystemType::Btrfs(_) => {
view.add_child(BtrfsBootdiskOptionsView::new_with_defaults(&runinfo))
}
}
@@ -236,7 +240,7 @@ impl AdvancedBootdiskOptionsView {
siv.call_on_name(
"bootdisk-options-target-disk",
move |view: &mut FormView| match fstype {
- FsType::Ext4 | FsType::Xfs => {
+ FilesystemType::Ext4 | FilesystemType::Xfs => {
view.replace_child(
0,
target_bootdisk_selectview(&runinfo.disks, options_ref, &selected_lvm_disk),
@@ -252,7 +256,7 @@ impl AdvancedBootdiskOptionsView {
.view
.get_child(1)
.and_then(|v| v.downcast_ref::<FormView>())
- .and_then(|v| v.get_value::<SelectView<FsType>, _>(0))
+ .and_then(|v| v.get_value::<SelectView<FilesystemType>, _>(0))
.ok_or("Failed to retrieve filesystem type".to_owned())?;

let advanced = self
@@ -279,7 +283,7 @@ impl AdvancedBootdiskOptionsView {
.get_values()
.ok_or("Failed to retrieve advanced bootdisk options")?;

- if let FsType::Zfs(level) = fstype {
+ if let FilesystemType::Zfs(level) = fstype {
level
.check_raid_disks_setup(&disks)
.map_err(|err| format!("{fstype}: {err}"))?;
@@ -295,7 +299,7 @@ impl AdvancedBootdiskOptionsView {
.get_values()
.ok_or("Failed to retrieve advanced bootdisk options")?;

- if let FsType::Btrfs(level) = fstype {
+ if let FilesystemType::Btrfs(level) = fstype {
level
.check_raid_disks_setup(&disks)
.map_err(|err| format!("{fstype}: {err}"))?;
--
2.53.0