public inbox for pdm-devel@lists.proxmox.com
 help / color / mirror / Atom feed
From: Christoph Heiss <c.heiss@proxmox.com>
To: pdm-devel@lists.proxmox.com
Subject: [PATCH installer v3 31/38] tree-wide: switch to filesystem types from proxmox-installer-types
Date: Fri,  3 Apr 2026 18:54:03 +0200	[thread overview]
Message-ID: <20260403165437.2166551-32-c.heiss@proxmox.com> (raw)
In-Reply-To: <20260403165437.2166551-1-c.heiss@proxmox.com>

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<S>(&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





  parent reply	other threads:[~2026-04-03 16:57 UTC|newest]

Thread overview: 39+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-04-03 16:53 [PATCH proxmox/yew-pwt/datacenter-manager/installer v3 00/38] add auto-installer integration Christoph Heiss
2026-04-03 16:53 ` [PATCH proxmox v3 01/38] api-macro: allow $ in identifier name Christoph Heiss
2026-04-03 16:53 ` [PATCH proxmox v3 02/38] schema: oneOf: allow single string variant Christoph Heiss
2026-04-03 16:53 ` [PATCH proxmox v3 03/38] schema: implement UpdaterType for HashMap and BTreeMap Christoph Heiss
2026-04-03 16:53 ` [PATCH proxmox v3 04/38] network-types: move `Fqdn` type from proxmox-installer-common Christoph Heiss
2026-04-03 16:53 ` [PATCH proxmox v3 05/38] network-types: implement api type for Fqdn Christoph Heiss
2026-04-03 16:53 ` [PATCH proxmox v3 06/38] network-types: add api wrapper type for std::net::IpAddr Christoph Heiss
2026-04-03 16:53 ` [PATCH proxmox v3 07/38] network-types: cidr: implement generic `IpAddr::new` constructor Christoph Heiss
2026-04-03 16:53 ` [PATCH proxmox v3 08/38] network-types: fqdn: implement standard library Error for Fqdn Christoph Heiss
2026-04-03 16:53 ` [PATCH proxmox v3 09/38] node-status: make KernelVersionInformation Clone + PartialEq Christoph Heiss
2026-04-03 16:53 ` [PATCH proxmox v3 10/38] installer-types: add common types used by the installer Christoph Heiss
2026-04-03 16:53 ` [PATCH proxmox v3 11/38] installer-types: add types used by the auto-installer Christoph Heiss
2026-04-03 16:53 ` [PATCH proxmox v3 12/38] installer-types: implement api type for all externally-used types Christoph Heiss
2026-04-03 16:53 ` [PATCH yew-widget-toolkit v3 13/38] widget: kvlist: add widget for user-modifiable data tables Christoph Heiss
2026-04-03 16:53 ` [PATCH datacenter-manager v3 14/38] api-types, cli: use ReturnType::new() instead of constructing it manually Christoph Heiss
2026-04-03 16:53 ` [PATCH datacenter-manager v3 15/38] api-types: add api types for auto-installer integration Christoph Heiss
2026-04-03 16:53 ` [PATCH datacenter-manager v3 16/38] config: add auto-installer configuration module Christoph Heiss
2026-04-03 16:53 ` [PATCH datacenter-manager v3 17/38] acl: wire up new /system/auto-installation acl path Christoph Heiss
2026-04-03 16:53 ` [PATCH datacenter-manager v3 18/38] server: api: add auto-installer integration module Christoph Heiss
2026-04-03 16:53 ` [PATCH datacenter-manager v3 19/38] server: api: auto-installer: add access token management endpoints Christoph Heiss
2026-04-03 16:53 ` [PATCH datacenter-manager v3 20/38] client: add bindings for auto-installer endpoints Christoph Heiss
2026-04-03 16:53 ` [PATCH datacenter-manager v3 21/38] ui: auto-installer: add installations overview panel Christoph Heiss
2026-04-03 16:53 ` [PATCH datacenter-manager v3 22/38] ui: auto-installer: add prepared answer configuration panel Christoph Heiss
2026-04-03 16:53 ` [PATCH datacenter-manager v3 23/38] ui: auto-installer: add access token " Christoph Heiss
2026-04-03 16:53 ` [PATCH datacenter-manager v3 24/38] docs: add documentation for auto-installer integration Christoph Heiss
2026-04-03 16:53 ` [PATCH installer v3 25/38] install: iso env: use JSON boolean literals for product config Christoph Heiss
2026-04-03 16:53 ` [PATCH installer v3 26/38] common: http: allow passing custom headers to post() Christoph Heiss
2026-04-03 16:53 ` [PATCH installer v3 27/38] common: options: move regex construction out of loop Christoph Heiss
2026-04-03 16:54 ` [PATCH installer v3 28/38] assistant: support adding an authorization token for HTTP-based answers Christoph Heiss
2026-04-03 16:54 ` [PATCH installer v3 29/38] tree-wide: used moved `Fqdn` type to proxmox-network-types Christoph Heiss
2026-04-03 16:54 ` [PATCH installer v3 30/38] tree-wide: use `Cidr` type from proxmox-network-types Christoph Heiss
2026-04-03 16:54 ` Christoph Heiss [this message]
2026-04-03 16:54 ` [PATCH installer v3 32/38] post-hook: switch to types in proxmox-installer-types Christoph Heiss
2026-04-03 16:54 ` [PATCH installer v3 33/38] auto: sysinfo: switch to types from proxmox-installer-types Christoph Heiss
2026-04-03 16:54 ` [PATCH installer v3 34/38] fetch-answer: " Christoph Heiss
2026-04-03 16:54 ` [PATCH installer v3 35/38] fetch-answer: http: prefer json over toml for answer format Christoph Heiss
2026-04-03 16:54 ` [PATCH installer v3 36/38] fetch-answer: send auto-installer HTTP authorization token if set Christoph Heiss
2026-04-03 16:54 ` [PATCH installer v3 37/38] tree-wide: switch out `Answer` -> `AutoInstallerConfig` types Christoph Heiss
2026-04-03 16:54 ` [PATCH installer v3 38/38] auto: drop now-dead answer file definitions Christoph Heiss

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260403165437.2166551-32-c.heiss@proxmox.com \
    --to=c.heiss@proxmox.com \
    --cc=pdm-devel@lists.proxmox.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal