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 3E7DC1FF13E for ; Fri, 03 Apr 2026 18:55:25 +0200 (CEST) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id F2C2C7DE2; Fri, 3 Apr 2026 18:55:55 +0200 (CEST) From: Christoph Heiss To: pdm-devel@lists.proxmox.com Subject: [PATCH proxmox v3 12/38] installer-types: implement api type for all externally-used types Date: Fri, 3 Apr 2026 18:53:44 +0200 Message-ID: <20260403165437.2166551-13-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: 1775235288001 X-SPAM-LEVEL: Spam detection results: 0 AWL 0.066 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 Message-ID-Hash: J55NDUCN7LGLPJYVE6W5NJWDWHOTNW3B X-Message-ID-Hash: J55NDUCN7LGLPJYVE6W5NJWDWHOTNW3B 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: PDM will (re-)use most of these types directly in the API, thus make them compatible. Signed-off-by: Christoph Heiss --- Changes v2 -> v3: * describe all API properties, some fields were previously missing * implement api for a few more types as necessary Changes v1 -> v2: * no changes proxmox-installer-types/Cargo.toml | 4 + proxmox-installer-types/debian/control | 21 ++ proxmox-installer-types/src/answer.rs | 268 ++++++++++++++++++++++- proxmox-installer-types/src/lib.rs | 37 ++++ proxmox-installer-types/src/post_hook.rs | 55 +++++ 5 files changed, 384 insertions(+), 1 deletion(-) diff --git a/proxmox-installer-types/Cargo.toml b/proxmox-installer-types/Cargo.toml index b4906fc9..c37e1baf 100644 --- a/proxmox-installer-types/Cargo.toml +++ b/proxmox-installer-types/Cargo.toml @@ -15,10 +15,14 @@ rust-version.workspace = true anyhow.workspace = true serde = { workspace = true, features = ["derive"] } serde_plain.workspace = true +regex = { workspace = true, optional = true } proxmox-network-types.workspace = true +proxmox-schema = { workspace = true, optional = true, features = ["api-macro"] } +proxmox-section-config = { workspace = true, optional = true } proxmox-node-status.workspace = true [features] default = [] +api-types = ["dep:regex", "dep:proxmox-schema", "dep:proxmox-section-config", "proxmox-network-types/api-types"] # enable old-style answer file keys with underscores for backwards compatibility legacy = [] diff --git a/proxmox-installer-types/debian/control b/proxmox-installer-types/debian/control index 5971fd6a..2c6be448 100644 --- a/proxmox-installer-types/debian/control +++ b/proxmox-installer-types/debian/control @@ -30,6 +30,8 @@ Depends: librust-serde-1+default-dev, librust-serde-1+derive-dev, librust-serde-plain-1+default-dev +Suggests: + librust-proxmox-installer-types+api-types-dev (= ${binary:Version}) Provides: librust-proxmox-installer-types+default-dev (= ${binary:Version}), librust-proxmox-installer-types+legacy-dev (= ${binary:Version}), @@ -44,3 +46,22 @@ Provides: librust-proxmox-installer-types-0.1.0+legacy-dev (= ${binary:Version}) Description: Type definitions used within the installer - Rust source code Source code for Debianized Rust crate "proxmox-installer-types" + +Package: librust-proxmox-installer-types+api-types-dev +Architecture: any +Multi-Arch: same +Depends: + ${misc:Depends}, + librust-proxmox-installer-types-dev (= ${binary:Version}), + librust-proxmox-network-types-1+api-types-dev (>= 1.0.2-~~), + librust-proxmox-schema-5+api-macro-dev (>= 5.1.1-~~), + librust-proxmox-schema-5+default-dev (>= 5.1.1-~~), + librust-proxmox-section-config-3+default-dev (>= 3.1.0-~~), + librust-regex-1+default-dev (>= 1.5-~~) +Provides: + librust-proxmox-installer-types-0+api-types-dev (= ${binary:Version}), + librust-proxmox-installer-types-0.1+api-types-dev (= ${binary:Version}), + librust-proxmox-installer-types-0.1.0+api-types-dev (= ${binary:Version}) +Description: Type definitions used within the installer - feature "api-types" + This metapackage enables feature "api-types" for the Rust proxmox-installer- + types crate, by pulling in any additional dependencies needed by that feature. diff --git a/proxmox-installer-types/src/answer.rs b/proxmox-installer-types/src/answer.rs index 10cd57a0..975063ba 100644 --- a/proxmox-installer-types/src/answer.rs +++ b/proxmox-installer-types/src/answer.rs @@ -15,15 +15,37 @@ use std::{ }; use proxmox_network_types::{fqdn::Fqdn, ip_address::Cidr}; + +#[cfg(feature = "api-types")] +use proxmox_schema::{ + api, + api_types::{DISK_ARRAY_SCHEMA, PASSWORD_FORMAT}, + ApiType, IntegerSchema, NumberSchema, ObjectSchema, OneOfSchema, Schema, StringSchema, Updater, + UpdaterType, +}; + +#[cfg(feature = "api-types")] +type IpAddr = proxmox_network_types::ip_address::api_types::IpAddr; +#[cfg(not(feature = "api-types"))] type IpAddr = std::net::IpAddr; +#[cfg(feature = "api-types")] +proxmox_schema::const_regex! { + /// A unique two-letter country code, according to ISO 3166-1 (alpha-2). + pub COUNTRY_CODE_REGEX = r"^[a-z]{2}$"; +} + /// Defines API types used by proxmox-fetch-answer, the first part of the /// auto-installer. pub mod fetch { use serde::{Deserialize, Serialize}; + #[cfg(feature = "api-types")] + use proxmox_schema::api; + use crate::SystemInfo; + #[cfg_attr(feature = "api-types", api)] #[derive(Deserialize, Serialize)] #[serde(rename_all = "kebab-case")] /// Metadata of the HTTP POST payload, such as schema version of the document. @@ -50,6 +72,13 @@ pub mod fetch { } } + #[cfg_attr(feature = "api-types", api( + properties: { + sysinfo: { + flatten: true, + }, + }, + ))] #[derive(Deserialize, Serialize)] #[serde(rename_all = "kebab-case")] /// Data sent in the body of POST request when retrieving the answer file via HTTP(S). @@ -68,6 +97,7 @@ pub mod fetch { } } +#[cfg_attr(feature = "api-types", api)] #[derive(Clone, Deserialize, Debug, Serialize, PartialEq)] #[serde(rename_all = "kebab-case", deny_unknown_fields)] /// Top-level answer file structure, describing all possible options for an @@ -91,6 +121,25 @@ pub struct AutoInstallerConfig { pub first_boot: Option, } +/// Machine root password schema. +#[cfg(feature = "api-types")] +pub const ROOT_PASSWORD_SCHEMA: proxmox_schema::Schema = StringSchema::new("Root Password.") + .format(&PASSWORD_FORMAT) + .min_length(8) + .max_length(64) + .schema(); + +#[cfg_attr(feature = "api-types", api( + properties: { + "root-ssh-keys": { + type: Array, + items: { + description: "Public SSH key.", + type: String, + } + }, + }, +))] #[derive(Clone, Default, Deserialize, Debug, Serialize, PartialEq)] #[serde(rename_all = "kebab-case", deny_unknown_fields)] /// General target system options for setting up the system in an automated @@ -130,6 +179,7 @@ pub struct GlobalOptions { pub root_ssh_keys: Vec, } +#[cfg_attr(feature = "api-types", api)] #[derive(Copy, Clone, Deserialize, Serialize, Debug, Default, PartialEq, Eq)] #[serde(rename_all = "kebab-case", deny_unknown_fields)] /// Action to take after the installation completed successfully. @@ -144,6 +194,7 @@ pub enum RebootMode { serde_plain::derive_fromstr_from_deserialize!(RebootMode); #[derive(Clone, Deserialize, Debug, Serialize, PartialEq)] +#[cfg_attr(feature = "api-types", derive(Updater))] #[serde( untagged, expecting = "either a fully-qualified domain name or extendend configuration for usage with DHCP must be specified" @@ -163,6 +214,23 @@ impl Default for FqdnConfig { } } +#[cfg(feature = "api-types")] +impl ApiType for FqdnConfig { + const API_SCHEMA: Schema = OneOfSchema::new( + "Either a FQDN as string or an object describing the retrieval method.", + &( + "type", + false, + &StringSchema::new("A string or an object").schema(), + ), + &[ + ("from-dhcp", &::API_SCHEMA), + ("simple", &StringSchema::new("Plain FQDN").schema()), + ], + ) + .schema(); +} + impl FqdnConfig { /// Constructs a new "simple" FQDN configuration, i.e. a fixed hostname. pub fn simple>(fqdn: S) -> Result { @@ -183,6 +251,7 @@ impl FqdnConfig { } } +#[cfg_attr(feature = "api-types", api)] #[derive(Clone, Default, Deserialize, Debug, Serialize, PartialEq)] #[serde(rename_all = "kebab-case", deny_unknown_fields)] /// Extended configuration for retrieving the FQDN from external sources. @@ -195,6 +264,7 @@ pub struct FqdnFromDhcpConfig { pub domain: Option, } +#[cfg_attr(feature = "api-types", api)] #[derive(Clone, Deserialize, Debug, Default, PartialEq, Serialize)] #[serde(rename_all = "kebab-case", deny_unknown_fields)] /// Describes the source to retrieve the FQDN of the installation. @@ -204,6 +274,7 @@ pub enum FqdnSourceMode { FromDhcp, } +#[cfg_attr(feature = "api-types", api)] #[derive(Clone, Deserialize, Debug, Serialize, PartialEq)] #[serde(rename_all = "kebab-case", deny_unknown_fields)] /// Configuration for the post-installation hook, which runs after an @@ -216,6 +287,7 @@ pub struct PostNotificationHookInfo { pub cert_fingerprint: Option, } +#[cfg_attr(feature = "api-types", api)] #[derive(Clone, Deserialize, Debug, PartialEq, Serialize)] #[serde(rename_all = "kebab-case", deny_unknown_fields)] /// Possible sources for the optional first-boot hook script/executable file. @@ -227,6 +299,7 @@ pub enum FirstBootHookSourceMode { FromIso, } +#[cfg_attr(feature = "api-types", api)] #[derive(Clone, Default, Deserialize, Debug, PartialEq, Serialize)] #[serde(rename_all = "kebab-case", deny_unknown_fields)] /// Possible orderings for the `proxmox-first-boot` systemd service. @@ -256,6 +329,7 @@ impl FirstBootHookServiceOrdering { } } +#[cfg_attr(feature = "api-types", api)] #[derive(Clone, Deserialize, Debug, Serialize, PartialEq)] #[serde(rename_all = "kebab-case", deny_unknown_fields)] /// Describes from where to fetch the first-boot hook script, either being baked into the ISO or @@ -276,6 +350,15 @@ pub struct FirstBootHookInfo { pub cert_fingerprint: Option, } +#[cfg_attr(feature = "api-types", api( + properties: { + mapping: { + type: Object, + properties: {}, + additional_properties: true, + } + }, +))] #[derive(Clone, Deserialize, Debug, Serialize, PartialEq)] #[serde(rename_all = "kebab-case", deny_unknown_fields)] /// Options controlling the behaviour of the network interface pinning (by @@ -288,6 +371,15 @@ pub struct NetworkInterfacePinningOptionsAnswer { pub mapping: HashMap, } +#[cfg_attr(feature = "api-types", api( + properties: { + filter: { + type: Object, + properties: {}, + additional_properties: true, + } + }, +))] #[derive(Clone, Deserialize, Debug, Serialize, PartialEq)] #[serde(rename_all = "kebab-case", deny_unknown_fields)] /// Static network configuration given by the user. @@ -307,6 +399,7 @@ pub struct NetworkConfigFromAnswer { pub interface_name_pinning: Option, } +#[cfg_attr(feature = "api-types", api)] #[derive(Clone, Deserialize, Debug, Serialize, PartialEq)] #[serde(rename_all = "kebab-case", deny_unknown_fields)] /// Use the network configuration received from the DHCP server. @@ -317,6 +410,13 @@ pub struct NetworkConfigFromDhcp { pub interface_name_pinning: Option, } +#[cfg_attr(feature = "api-types", api( + "id-property": "source", + "id-schema": { + type: String, + description: "'from-dhcp' or 'from-answer'", + } +))] #[derive(Clone, Deserialize, Debug, Serialize, PartialEq)] #[serde(rename_all = "kebab-case", deny_unknown_fields, tag = "source")] /// Network configuration to set up inside the target installation. @@ -339,6 +439,7 @@ impl NetworkConfig { } #[derive(Clone, Debug, Deserialize, Serialize, PartialEq)] +#[cfg_attr(feature = "api-types", derive(UpdaterType))] #[serde(rename_all = "kebab-case", tag = "filesystem")] /// Filesystem-specific options to set on the root disk. pub enum FilesystemOptions { @@ -368,6 +469,66 @@ impl FilesystemOptions { } } +#[cfg(feature = "api-types")] +impl ApiType for FilesystemOptions { + // FIXME: proxmox-schema can not correctly differentiate between different + // enums in struct members with the same name. + const API_SCHEMA: Schema = ObjectSchema::new( + "Filesystem-specific options to set on the root disk.", + &[ + ( + "ashift", + true, + &IntegerSchema::new("`ashift` value to create the zpool with.") + .minimum(9) + .maximum(16) + .default(12) + .schema(), + ), + ("filesystem", false, &Filesystem::API_SCHEMA), + ( + "hdsize", + true, + &NumberSchema::new("Size of the root disk to use, in GiB.") + .minimum(2.) + .schema(), + ), + ( + "maxfree", + true, + &NumberSchema::new( + "Minimum amount of free space to leave on the LVM volume group, in GiB.", + ) + .minimum(0.) + .schema(), + ), + ( + "maxroot", + true, + &NumberSchema::new("Maximum size of the `root` volume, in GiB.") + .minimum(2.) + .schema(), + ), + ( + "maxvz", + true, + &NumberSchema::new("Maximum size of the `data` volume, in GiB.") + .minimum(0.) + .schema(), + ), + ( + "swapsize", + true, + &NumberSchema::new("Size of the swap volume, in GiB.") + .minimum(0.) + .schema(), + ), + ], + ) + .additional_properties(true) + .schema(); +} + #[derive(Clone, Debug, Serialize)] /// Defines the disks to use for the installation. Can either be a fixed list /// of disk names or a dynamic filter list. @@ -393,6 +554,7 @@ impl Display for DiskSelection { } } +#[cfg_attr(feature = "api-types", api)] #[derive(Copy, Clone, Default, Deserialize, Debug, PartialEq, Serialize)] #[serde(rename_all = "lowercase", deny_unknown_fields)] /// Whether the associated filters must all match for a device or if any one @@ -407,6 +569,18 @@ pub enum FilterMatch { serde_plain::derive_fromstr_from_deserialize!(FilterMatch); +#[cfg_attr(feature = "api-types", api( + properties: { + "disk-list": { + schema: DISK_ARRAY_SCHEMA, + }, + filter: { + type: Object, + properties: {}, + additional_properties: true, + } + }, +))] #[derive(Clone, Debug, Deserialize, Serialize, PartialEq)] #[serde(rename_all = "kebab-case", deny_unknown_fields)] /// Disk configuration for the target installation. @@ -502,7 +676,7 @@ impl DiskSetup { } } - +#[cfg_attr(feature = "api-types", api)] #[derive(Copy, Clone, Deserialize, Serialize, Debug, PartialEq)] #[serde(rename_all = "lowercase", deny_unknown_fields)] /// Available filesystem during installation. @@ -531,6 +705,46 @@ impl From for Filesystem { serde_plain::derive_display_from_serialize!(Filesystem); serde_plain::derive_fromstr_from_deserialize!(Filesystem); +#[cfg_attr(feature = "api-types", api( + properties: { + raid: { + type: ZfsRaidLevel, + optional: true, + }, + ashift: { + type: Integer, + minimum: 9, + maximum: 16, + default: 12, + optional: true, + }, + "arc-max": { + type: Integer, + // ZFS specifies 64 MiB as the absolute minimum. + minimum: 64, + optional: true, + }, + checksum: { + type: ZfsChecksumOption, + optional: true, + }, + compress: { + type: ZfsChecksumOption, + optional: true, + }, + copies: { + type: Integer, + minimum: 1, + maximum: 3, + optional: true, + }, + hdsize: { + type: Number, + minimum: 2., + optional: true, + }, + }, +), derive(Updater))] #[derive(Clone, Copy, Default, Deserialize, Debug, Serialize, PartialEq)] #[serde(rename_all = "kebab-case", deny_unknown_fields)] /// ZFS-specific filesystem options. @@ -561,6 +775,35 @@ pub struct ZfsOptions { pub hdsize: Option, } +#[cfg_attr(feature = "api-types", api( + properties: { + hdsize: { + type: Number, + minimum: 2., + optional: true, + }, + swapsize: { + type: Number, + minimum: 0., + optional: true, + }, + maxroot: { + type: Number, + minimum: 2., + optional: true, + }, + maxvz: { + type: Number, + minimum: 0., + optional: true, + }, + minfree: { + type: Number, + minimum: 0., + optional: true, + }, + }, +), derive(Updater))] #[derive(Clone, Copy, Default, Deserialize, Serialize, Debug, PartialEq)] #[serde(rename_all = "kebab-case", deny_unknown_fields)] /// LVM-specific filesystem options, when using ext4 or xfs as filesystem. @@ -588,6 +831,23 @@ pub struct LvmOptions { pub minfree: Option, } +#[cfg_attr(feature = "api-types", api( + properties: { + hdsize: { + type: Number, + minimum: 2., + optional: true, + }, + raid: { + type: BtrfsRaidLevel, + optional: true, + }, + compress: { + type: BtrfsCompressOption, + optional: true, + }, + }, +), derive(Updater))] #[derive(Clone, Copy, Default, Deserialize, Debug, Serialize, PartialEq)] #[serde(rename_all = "kebab-case", deny_unknown_fields)] /// Btrfs-specific filesystem options. @@ -604,6 +864,7 @@ pub struct BtrfsOptions { pub compress: Option, } +#[cfg_attr(feature = "api-types", api)] #[derive(Copy, Clone, Deserialize, Serialize, Debug, Default, PartialEq)] #[serde(rename_all = "kebab-case", deny_unknown_fields)] /// Keyboard layout of the system. @@ -697,6 +958,7 @@ impl KeyboardLayout { serde_plain::derive_fromstr_from_deserialize!(KeyboardLayout); serde_plain::derive_display_from_serialize!(KeyboardLayout); +#[cfg_attr(feature = "api-types", api)] #[derive(Copy, Clone, Debug, Default, Deserialize, Serialize, Eq, PartialEq)] #[serde(rename_all = "UPPERCASE")] /// Available Btrfs RAID levels. @@ -715,6 +977,7 @@ pub enum BtrfsRaidLevel { serde_plain::derive_display_from_serialize!(BtrfsRaidLevel); +#[cfg_attr(feature = "api-types", api)] #[derive(Copy, Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)] #[serde(rename_all = "lowercase")] /// Possible compression algorithms usable with Btrfs. See the accompanying @@ -742,6 +1005,7 @@ pub const BTRFS_COMPRESS_OPTIONS: &[BtrfsCompressOption] = { &[On, Off, Zlib, Lzo, Zstd] }; +#[cfg_attr(feature = "api-types", api)] #[derive(Copy, Clone, Debug, Default, Deserialize, Serialize, Eq, PartialEq)] #[serde(rename_all = "UPPERCASE")] /// Available ZFS RAID levels. @@ -769,6 +1033,7 @@ pub enum ZfsRaidLevel { serde_plain::derive_display_from_serialize!(ZfsRaidLevel); +#[cfg_attr(feature = "api-types", api)] #[derive(Copy, Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)] #[serde(rename_all = "lowercase")] /// Possible compression algorithms usable with ZFS. @@ -799,6 +1064,7 @@ pub const ZFS_COMPRESS_OPTIONS: &[ZfsCompressOption] = { &[On, Off, Lzjb, Lz4, Zle, Gzip, Zstd] }; +#[cfg_attr(feature = "api-types", api)] #[derive(Copy, Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)] #[serde(rename_all = "kebab-case")] /// Possible checksum algorithms usable with ZFS. diff --git a/proxmox-installer-types/src/lib.rs b/proxmox-installer-types/src/lib.rs index 40c61252..df1f7944 100644 --- a/proxmox-installer-types/src/lib.rs +++ b/proxmox-installer-types/src/lib.rs @@ -10,6 +10,9 @@ pub mod answer; pub mod post_hook; +#[cfg(feature = "api-types")] +use proxmox_schema::api; + use serde::{Deserialize, Serialize}; use std::collections::{BTreeMap, HashMap}; @@ -18,6 +21,7 @@ use proxmox_network_types::mac_address::MacAddress; /// Default placeholder value for the administrator email address. pub const EMAIL_DEFAULT_PLACEHOLDER: &str = "mail@example.invalid"; +#[cfg_attr(feature = "api-types", api)] #[derive(Copy, Clone, Eq, Deserialize, PartialEq, Serialize)] #[serde(rename_all = "lowercase")] /// Whether the system boots using legacy BIOS or (U)EFI. @@ -40,6 +44,16 @@ pub struct UdevInfo { pub nics: BTreeMap, } +#[cfg_attr(feature = "api-types", api( + properties: { + network_interfaces: { + type: Array, + items: { + type: NetworkInterface, + }, + }, + }, +))] #[derive(Clone, Debug, Deserialize, Serialize, PartialEq)] /// Information about the hardware and installer in use. pub struct SystemInfo { @@ -53,6 +67,7 @@ pub struct SystemInfo { pub network_interfaces: Vec, } +#[cfg_attr(feature = "api-types", api)] #[derive(Clone, Debug, Deserialize, Serialize, PartialEq)] /// The per-product configuration of the installer. pub struct ProductConfig { @@ -75,6 +90,7 @@ impl ProductConfig { } } +#[cfg_attr(feature = "api-types", api)] #[derive(Clone, Debug, Deserialize, Serialize, PartialEq)] /// Information about the ISO itself. pub struct IsoInfo { @@ -94,6 +110,25 @@ impl IsoInfo { } } +#[cfg_attr(feature = "api-types", api( + properties: { + baseboard: { + type: Object, + properties: {}, + additional_properties: true, + }, + chassis: { + type: Object, + properties: {}, + additional_properties: true, + }, + system: { + type: Object, + properties: {}, + additional_properties: true, + }, + }, +))] #[derive(Clone, Debug, Deserialize, Serialize, PartialEq)] /// Collection of various DMI information categories. pub struct SystemDMI { @@ -105,6 +140,7 @@ pub struct SystemDMI { pub system: HashMap, } +#[cfg_attr(feature = "api-types", api)] #[derive(Clone, Debug, Deserialize, Serialize, PartialEq)] /// A unique network interface. pub struct NetworkInterface { @@ -114,6 +150,7 @@ pub struct NetworkInterface { pub mac: MacAddress, } +#[cfg_attr(feature = "api-types", api)] #[allow(clippy::upper_case_acronyms)] #[derive(Debug, Clone, Copy, Deserialize, PartialEq, Eq, PartialOrd, Ord, Serialize)] #[serde(rename_all = "lowercase")] diff --git a/proxmox-installer-types/src/post_hook.rs b/proxmox-installer-types/src/post_hook.rs index a307cf7b..e505a5cf 100644 --- a/proxmox-installer-types/src/post_hook.rs +++ b/proxmox-installer-types/src/post_hook.rs @@ -3,6 +3,8 @@ use serde::{Deserialize, Serialize}; use proxmox_network_types::ip_address::Cidr; +#[cfg(feature = "api-types")] +use proxmox_schema::api; use crate::{ answer::{FilesystemType, RebootMode}, @@ -12,6 +14,13 @@ use crate::{ /// Re-export for convenience, since this is public API pub use proxmox_node_status::KernelVersionInformation; +#[cfg_attr(feature = "api-types", api( + properties: { + "secureboot": { + optional: true, + }, + }, +))] #[derive(Clone, Serialize, Deserialize, PartialEq)] /// Information about the system boot status. pub struct BootInfo { @@ -22,6 +31,7 @@ pub struct BootInfo { pub secureboot: bool, } +#[cfg_attr(feature = "api-types", api)] #[derive(Clone, Serialize, Deserialize, PartialEq)] /// Holds all the public keys for the different algorithms available. pub struct SshPublicHostKeys { @@ -33,6 +43,18 @@ pub struct SshPublicHostKeys { pub rsa: String, } +#[cfg_attr(feature = "api-types", api( + properties: { + "udev-properties": { + type: Object, + additional_properties: true, + properties: {}, + }, + "is-bootdisk": { + optional: true, + }, + }, +))] #[derive(Clone, Serialize, Deserialize, PartialEq)] #[serde(rename_all = "kebab-case")] /// Holds information about a single disk in the system. @@ -46,6 +68,21 @@ pub struct DiskInfo { pub udev_properties: UdevProperties, } +#[cfg_attr(feature = "api-types", api( + properties: { + "udev-properties": { + type: Object, + additional_properties: true, + properties: {}, + }, + "is-management": { + optional: true, + }, + "is-pinned": { + optional: true, + }, + }, +))] /// Holds information about the management network interface. #[derive(Clone, Serialize, Deserialize, PartialEq)] #[serde(rename_all = "kebab-case")] @@ -69,6 +106,7 @@ pub struct NetworkInterfaceInfo { pub udev_properties: UdevProperties, } +#[cfg_attr(feature = "api-types", api)] #[derive(Clone, Serialize, Deserialize, PartialEq)] #[serde(rename_all = "kebab-case")] /// Information about the installed product itself. @@ -81,6 +119,7 @@ pub struct ProductInfo { pub version: String, } +#[cfg_attr(feature = "api-types", api)] #[derive(Clone, Serialize, Deserialize, PartialEq)] /// Information about the CPU(s) installed in the system pub struct CpuInfo { @@ -98,6 +137,7 @@ pub struct CpuInfo { pub sockets: usize, } +#[cfg_attr(feature = "api-types", api)] #[derive(Clone, Serialize, Deserialize, PartialEq)] #[serde(rename_all = "kebab-case")] /// Metadata of the hook, such as schema version of the document. @@ -112,6 +152,21 @@ pub struct PostHookInfoSchema { pub version: String, } +#[cfg_attr(feature = "api-types", api( + properties: { + filesystem: { + type: String, + }, + disks: { + type: Array, + items: { type: DiskInfo }, + }, + "network-interfaces": { + type: Array, + items: { type: NetworkInterfaceInfo }, + } + }, +))] #[derive(Clone, Serialize, Deserialize, PartialEq)] #[serde(rename_all = "kebab-case")] /// All data sent as request payload with the post-installation-webhook POST request. -- 2.53.0