From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68]) by lore.proxmox.com (Postfix) with ESMTPS id DBDE61FF13E for ; Fri, 03 Apr 2026 18:57:04 +0200 (CEST) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id A267F8A08; Fri, 3 Apr 2026 18:57:35 +0200 (CEST) From: Christoph Heiss 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 Message-ID: <20260403165437.2166551-32-c.heiss@proxmox.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260403165437.2166551-1-c.heiss@proxmox.com> References: <20260403165437.2166551-1-c.heiss@proxmox.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Bm-Milter-Handled: 55990f41-d878-4baa-be0a-ee34c49e34d2 X-Bm-Transport-Timestamp: 1775235386008 X-SPAM-LEVEL: Spam detection results: 0 AWL -1.433 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record URIBL_BLACK 3 Contains an URL listed in the URIBL blacklist [openzfs.github.io] Message-ID-Hash: UPJIUHQKIPN4JPQTZSHYH63PR7ZTSSFE X-Message-ID-Hash: UPJIUHQKIPN4JPQTZSHYH63PR7ZTSSFE X-MailFrom: c.heiss@proxmox.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.10 Precedence: list List-Id: Proxmox Datacenter Manager development discussion List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: No functional changes. Signed-off-by: Christoph Heiss --- 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, pub fs_options: FsOptions, @@ -351,11 +351,17 @@ impl TryFrom 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 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 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, + filesystem: Option, /// 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, + filesystem: Option, } impl cli::Subcommand for CommandCleanupArgs { @@ -105,39 +104,6 @@ OPTIONS: } } -#[derive(Copy, Clone, Debug)] -enum Filesystems { - Zfs, - Ext4, - Xfs, - Btrfs, -} - -impl From 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 { - 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) -> Result { +fn get_fs(filesystem: Option) -> Result { let fs = match filesystem { None => { let low_level_config = match get_low_level_config() { @@ -210,7 +176,7 @@ fn get_fs(filesystem: Option) -> Result { "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 - 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 { - 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, - 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 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, 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: /// @@ -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::().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::()) - .and_then(|v| v.get_value::, _>(0)) + .and_then(|v| v.get_value::, _>(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