From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: <pve-devel-bounces@lists.proxmox.com> Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68]) by lore.proxmox.com (Postfix) with ESMTPS id B59F91FF165 for <inbox@lore.proxmox.com>; Thu, 27 Mar 2025 16:18:52 +0100 (CET) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id C702918940; Thu, 27 Mar 2025 16:18:34 +0100 (CET) From: Christoph Heiss <c.heiss@proxmox.com> To: pve-devel@lists.proxmox.com Date: Thu, 27 Mar 2025 16:17:17 +0100 Message-ID: <20250327151718.1084841-7-c.heiss@proxmox.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250327151718.1084841-1-c.heiss@proxmox.com> References: <20250327151718.1084841-1-c.heiss@proxmox.com> MIME-Version: 1.0 X-SPAM-LEVEL: Spam detection results: 0 AWL 0.029 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 Subject: [pve-devel] [PATCH installer 6/6] fix #5811: auto: add option to retrieve FQDN from DHCP configuration X-BeenThere: pve-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox VE development discussion <pve-devel.lists.proxmox.com> List-Unsubscribe: <https://lists.proxmox.com/cgi-bin/mailman/options/pve-devel>, <mailto:pve-devel-request@lists.proxmox.com?subject=unsubscribe> List-Archive: <http://lists.proxmox.com/pipermail/pve-devel/> List-Post: <mailto:pve-devel@lists.proxmox.com> List-Help: <mailto:pve-devel-request@lists.proxmox.com?subject=help> List-Subscribe: <https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel>, <mailto:pve-devel-request@lists.proxmox.com?subject=subscribe> Reply-To: Proxmox VE development discussion <pve-devel@lists.proxmox.com> Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: pve-devel-bounces@lists.proxmox.com Sender: "pve-devel" <pve-devel-bounces@lists.proxmox.com> Fixes #5811 [0]. Adds a new option to the answer file for specifying to use the DHCP-provided hostname and domain. For the domain, an additional fallback/default can be specified, in case the DHCP server only provides hostnames. The hostname is always required in this mode. The addition to the answer file format is done in a backwards-compatible way. Users can now either directly specify the desired FQDN in the answer file as before through ``` [global] fqdn = "node.example.local" ``` or, with the new mechanism, if the DHCP server provides all the information already: ``` [global] fqdn.source = "from-dhcp" ``` or additionally with a custom domain: ``` [global.fqdn] source = "from-dhcp" domain = "custom.domain.local" ``` The DHCP-provided hostname and domain are already provided to the auto-installer through the runtime environment, so its just a matter of using them. The test suite is extended quite a bit, to cover all the different cases. [0] https://bugzilla.proxmox.com/show_bug.cgi?id=5811 Signed-off-by: Christoph Heiss <c.heiss@proxmox.com> --- proxmox-auto-installer/src/answer.rs | 36 +++++++++++++++++- proxmox-auto-installer/src/utils.rs | 37 ++++++++++++++++--- proxmox-auto-installer/tests/parse-answer.rs | 8 ++++ .../parse_answer/fqdn_from_dhcp.json | 19 ++++++++++ .../parse_answer/fqdn_from_dhcp.toml | 14 +++++++ ...cp_no_dhcp_domain_with_default_domain.json | 19 ++++++++++ ...cp_no_dhcp_domain_with_default_domain.toml | 17 +++++++++ ...ll_fqdn_from_dhcp_with_default_domain.json | 19 ++++++++++ ...ll_fqdn_from_dhcp_with_default_domain.toml | 17 +++++++++ .../fqdn_from_dhcp_no_default_domain.json | 3 ++ ...n_from_dhcp_no_default_domain.run-env.json | 1 + .../fqdn_from_dhcp_no_default_domain.toml | 14 +++++++ .../parse_answer_fail/fqdn_hostname_only.json | 3 ++ .../parse_answer_fail/fqdn_hostname_only.toml | 14 +++++++ .../parse_answer_fail/no_fqdn_from_dhcp.json | 3 ++ .../no_fqdn_from_dhcp.run-env.json | 1 + .../parse_answer_fail/no_fqdn_from_dhcp.toml | 14 +++++++ .../tests/resources/run-env-info.json | 2 +- proxmox-post-hook/src/main.rs | 19 ++++++++-- 19 files changed, 250 insertions(+), 10 deletions(-) create mode 100644 proxmox-auto-installer/tests/resources/parse_answer/fqdn_from_dhcp.json create mode 100644 proxmox-auto-installer/tests/resources/parse_answer/fqdn_from_dhcp.toml create mode 100644 proxmox-auto-installer/tests/resources/parse_answer/fqdn_from_dhcp_no_dhcp_domain_with_default_domain.json create mode 100644 proxmox-auto-installer/tests/resources/parse_answer/fqdn_from_dhcp_no_dhcp_domain_with_default_domain.toml create mode 100644 proxmox-auto-installer/tests/resources/parse_answer/full_fqdn_from_dhcp_with_default_domain.json create mode 100644 proxmox-auto-installer/tests/resources/parse_answer/full_fqdn_from_dhcp_with_default_domain.toml create mode 100644 proxmox-auto-installer/tests/resources/parse_answer_fail/fqdn_from_dhcp_no_default_domain.json create mode 100644 proxmox-auto-installer/tests/resources/parse_answer_fail/fqdn_from_dhcp_no_default_domain.run-env.json create mode 100644 proxmox-auto-installer/tests/resources/parse_answer_fail/fqdn_from_dhcp_no_default_domain.toml create mode 100644 proxmox-auto-installer/tests/resources/parse_answer_fail/fqdn_hostname_only.json create mode 100644 proxmox-auto-installer/tests/resources/parse_answer_fail/fqdn_hostname_only.toml create mode 100644 proxmox-auto-installer/tests/resources/parse_answer_fail/no_fqdn_from_dhcp.json create mode 100644 proxmox-auto-installer/tests/resources/parse_answer_fail/no_fqdn_from_dhcp.run-env.json create mode 100644 proxmox-auto-installer/tests/resources/parse_answer_fail/no_fqdn_from_dhcp.toml diff --git a/proxmox-auto-installer/src/answer.rs b/proxmox-auto-installer/src/answer.rs index c11818e..dd7fa06 100644 --- a/proxmox-auto-installer/src/answer.rs +++ b/proxmox-auto-installer/src/answer.rs @@ -46,7 +46,8 @@ impl Answer { #[serde(rename_all = "kebab-case", deny_unknown_fields)] pub struct Global { pub country: String, - pub fqdn: Fqdn, + /// FQDN to set for the installed system. + pub fqdn: FqdnConfig, pub keyboard: KeyboardLayout, pub mailto: String, pub timezone: String, @@ -60,6 +61,39 @@ pub struct Global { pub root_ssh_keys: Vec<String>, } +/// Allow the user to either set the FQDN of the installation to either some +/// fixed value or retrieve it dynamically via e.g.DHCP. +#[derive(Clone, Deserialize, Debug)] +#[serde( + untagged, + expecting = "either a fully-qualified domain name or extendend configuration for usage with DHCP must be specified" +)] +pub enum FqdnConfig { + /// Sets the FQDN to the exact value. + Simple(Fqdn), + /// Extended configuration, e.g. to use hostname and domain from DHCP. + Extended(FqdnExtendedConfig), +} + +/// Extended configuration for retrieving the FQDN from external sources. +#[derive(Clone, Deserialize, Debug)] +#[serde(rename_all = "kebab-case", deny_unknown_fields)] +pub struct FqdnExtendedConfig { + /// Source to gather the FQDN from. + #[serde(default)] + pub source: FqdnSourceMode, + /// Domain to use if none is received via DHCP. + pub domain: Option<String>, +} + +/// Describes the source to retrieve the FQDN of the installation. +#[derive(Clone, Deserialize, Debug, Default, PartialEq)] +#[serde(rename_all = "kebab-case", deny_unknown_fields)] +pub enum FqdnSourceMode { + #[default] + FromDhcp, +} + #[derive(Clone, Deserialize, Debug)] #[serde(rename_all = "kebab-case", deny_unknown_fields)] pub struct PostNotificationHookInfo { diff --git a/proxmox-auto-installer/src/utils.rs b/proxmox-auto-installer/src/utils.rs index cf072b8..5bff8b2 100644 --- a/proxmox-auto-installer/src/utils.rs +++ b/proxmox-auto-installer/src/utils.rs @@ -5,7 +5,9 @@ use log::info; use std::{collections::BTreeMap, process::Command}; use crate::{ - answer::{self, Answer, FirstBootHookSourceMode}, + answer::{ + self, Answer, FirstBootHookSourceMode, FqdnConfig, FqdnExtendedConfig, FqdnSourceMode, + }, udevinfo::UdevInfo, }; use proxmox_installer_common::{ @@ -24,12 +26,37 @@ fn get_network_settings( runtime_info: &RuntimeInfo, setup_info: &SetupInfo, ) -> Result<NetworkOptions> { - let mut network_options = NetworkOptions::defaults_from(setup_info, &runtime_info.network, None); + info!("Setting up network configuration"); - info!("Setting network configuration"); + let mut network_options = match &answer.global.fqdn { + // If the user set a static FQDN in the answer file, override it + FqdnConfig::Simple(name) => { + let mut opts = NetworkOptions::defaults_from(setup_info, &runtime_info.network, None); + opts.fqdn = name.to_owned(); + opts + } + FqdnConfig::Extended(FqdnExtendedConfig { + source: FqdnSourceMode::FromDhcp, + domain, + }) => { + // A FQDN from DHCP information and/or defaults is constructed in + // `NetworkOptions::defaults_from()` below, just check that the DHCP server actually + // provided a hostname. + if runtime_info.network.hostname.is_none() { + bail!( + "`global.fqdn.source` set to \"from-dhcp\", but DHCP server did not provide a hostname!" + ); + } - // Always use the FQDN from the answer file - network_options.fqdn = answer.global.fqdn.clone(); + // Either a domain must be received from the DHCP server or it must be set manually + // (even just as fallback) in the answer file. + if runtime_info.network.dns.domain.is_none() && domain.is_none() { + bail!("no domain received from DHCP server and `global.fqdn.domain` is unset!"); + } + + NetworkOptions::defaults_from(setup_info, &runtime_info.network, domain.as_deref()) + } + }; if let answer::NetworkSettings::Manual(settings) = &answer.network.network_settings { network_options.address = settings.cidr.clone(); diff --git a/proxmox-auto-installer/tests/parse-answer.rs b/proxmox-auto-installer/tests/parse-answer.rs index 57e20b3..34bc969 100644 --- a/proxmox-auto-installer/tests/parse-answer.rs +++ b/proxmox-auto-installer/tests/parse-answer.rs @@ -116,12 +116,16 @@ mod tests { declare_tests!( run_named_test, + // Keep below entries alphabetically sorted btrfs, btrfs_raid_level_uppercase, disk_match, disk_match_all, disk_match_any, first_boot, + fqdn_from_dhcp, + fqdn_from_dhcp_no_dhcp_domain_with_default_domain, + full_fqdn_from_dhcp_with_default_domain, hashed_root_password, minimal, nic_matching, @@ -136,7 +140,11 @@ mod tests { declare_tests!( run_named_fail_parse_test, + // Keep below entries alphabetically sorted both_password_and_hashed_set, + fqdn_from_dhcp_no_default_domain, + fqdn_hostname_only, + no_fqdn_from_dhcp, no_root_password_set, short_password ); diff --git a/proxmox-auto-installer/tests/resources/parse_answer/fqdn_from_dhcp.json b/proxmox-auto-installer/tests/resources/parse_answer/fqdn_from_dhcp.json new file mode 100644 index 0000000..5ec6656 --- /dev/null +++ b/proxmox-auto-installer/tests/resources/parse_answer/fqdn_from_dhcp.json @@ -0,0 +1,19 @@ +{ + "autoreboot": 1, + "cidr": "192.168.1.114/24", + "country": "at", + "dns": "192.168.1.254", + "domain": "test.local", + "filesys": "ext4", + "gateway": "192.168.1.1", + "hdsize": 223.57088470458984, + "existing_storage_auto_rename": 1, + "hostname": "pveauto", + "keymap": "de", + "mailto": "mail@no.invalid", + "mngmt_nic": "eno1", + "root_password": { "plain": "12345678" }, + "target_hd": "/dev/sda", + "timezone": "Europe/Vienna", + "first_boot": { "enabled": 0 } +} diff --git a/proxmox-auto-installer/tests/resources/parse_answer/fqdn_from_dhcp.toml b/proxmox-auto-installer/tests/resources/parse_answer/fqdn_from_dhcp.toml new file mode 100644 index 0000000..9d13a5f --- /dev/null +++ b/proxmox-auto-installer/tests/resources/parse_answer/fqdn_from_dhcp.toml @@ -0,0 +1,14 @@ +[global] +keyboard = "de" +country = "at" +fqdn.source = "from-dhcp" +mailto = "mail@no.invalid" +timezone = "Europe/Vienna" +root_password = "12345678" + +[network] +source = "from-dhcp" + +[disk-setup] +filesystem = "ext4" +disk_list = ["sda"] diff --git a/proxmox-auto-installer/tests/resources/parse_answer/fqdn_from_dhcp_no_dhcp_domain_with_default_domain.json b/proxmox-auto-installer/tests/resources/parse_answer/fqdn_from_dhcp_no_dhcp_domain_with_default_domain.json new file mode 100644 index 0000000..7ed46a2 --- /dev/null +++ b/proxmox-auto-installer/tests/resources/parse_answer/fqdn_from_dhcp_no_dhcp_domain_with_default_domain.json @@ -0,0 +1,19 @@ +{ + "autoreboot": 1, + "cidr": "192.168.1.114/24", + "country": "at", + "dns": "192.168.1.254", + "domain": "custom.local", + "filesys": "ext4", + "gateway": "192.168.1.1", + "hdsize": 223.57088470458984, + "existing_storage_auto_rename": 1, + "hostname": "pveauto", + "keymap": "de", + "mailto": "mail@no.invalid", + "mngmt_nic": "eno1", + "root_password": { "plain": "12345678" }, + "target_hd": "/dev/sda", + "timezone": "Europe/Vienna", + "first_boot": { "enabled": 0 } +} diff --git a/proxmox-auto-installer/tests/resources/parse_answer/fqdn_from_dhcp_no_dhcp_domain_with_default_domain.toml b/proxmox-auto-installer/tests/resources/parse_answer/fqdn_from_dhcp_no_dhcp_domain_with_default_domain.toml new file mode 100644 index 0000000..8fbbede --- /dev/null +++ b/proxmox-auto-installer/tests/resources/parse_answer/fqdn_from_dhcp_no_dhcp_domain_with_default_domain.toml @@ -0,0 +1,17 @@ +[global] +keyboard = "de" +country = "at" +mailto = "mail@no.invalid" +timezone = "Europe/Vienna" +root_password = "12345678" + +[global.fqdn] +source = "from-dhcp" +domain = "custom.local" + +[network] +source = "from-dhcp" + +[disk-setup] +filesystem = "ext4" +disk_list = ["sda"] diff --git a/proxmox-auto-installer/tests/resources/parse_answer/full_fqdn_from_dhcp_with_default_domain.json b/proxmox-auto-installer/tests/resources/parse_answer/full_fqdn_from_dhcp_with_default_domain.json new file mode 100644 index 0000000..7ed46a2 --- /dev/null +++ b/proxmox-auto-installer/tests/resources/parse_answer/full_fqdn_from_dhcp_with_default_domain.json @@ -0,0 +1,19 @@ +{ + "autoreboot": 1, + "cidr": "192.168.1.114/24", + "country": "at", + "dns": "192.168.1.254", + "domain": "custom.local", + "filesys": "ext4", + "gateway": "192.168.1.1", + "hdsize": 223.57088470458984, + "existing_storage_auto_rename": 1, + "hostname": "pveauto", + "keymap": "de", + "mailto": "mail@no.invalid", + "mngmt_nic": "eno1", + "root_password": { "plain": "12345678" }, + "target_hd": "/dev/sda", + "timezone": "Europe/Vienna", + "first_boot": { "enabled": 0 } +} diff --git a/proxmox-auto-installer/tests/resources/parse_answer/full_fqdn_from_dhcp_with_default_domain.toml b/proxmox-auto-installer/tests/resources/parse_answer/full_fqdn_from_dhcp_with_default_domain.toml new file mode 100644 index 0000000..8fbbede --- /dev/null +++ b/proxmox-auto-installer/tests/resources/parse_answer/full_fqdn_from_dhcp_with_default_domain.toml @@ -0,0 +1,17 @@ +[global] +keyboard = "de" +country = "at" +mailto = "mail@no.invalid" +timezone = "Europe/Vienna" +root_password = "12345678" + +[global.fqdn] +source = "from-dhcp" +domain = "custom.local" + +[network] +source = "from-dhcp" + +[disk-setup] +filesystem = "ext4" +disk_list = ["sda"] diff --git a/proxmox-auto-installer/tests/resources/parse_answer_fail/fqdn_from_dhcp_no_default_domain.json b/proxmox-auto-installer/tests/resources/parse_answer_fail/fqdn_from_dhcp_no_default_domain.json new file mode 100644 index 0000000..da7850f --- /dev/null +++ b/proxmox-auto-installer/tests/resources/parse_answer_fail/fqdn_from_dhcp_no_default_domain.json @@ -0,0 +1,3 @@ +{ + "error": "no domain received from DHCP server and `global.fqdn.domain` is unset!" +} diff --git a/proxmox-auto-installer/tests/resources/parse_answer_fail/fqdn_from_dhcp_no_default_domain.run-env.json b/proxmox-auto-installer/tests/resources/parse_answer_fail/fqdn_from_dhcp_no_default_domain.run-env.json new file mode 100644 index 0000000..eb17092 --- /dev/null +++ b/proxmox-auto-installer/tests/resources/parse_answer_fail/fqdn_from_dhcp_no_default_domain.run-env.json @@ -0,0 +1 @@ +{"boot_type":"efi","country":"at","disks":[[0,"/dev/nvme0n1",6251233968,"Micron_9300_MTFDHAL3T2TDR",4096,"/sys/block/nvme0n1"],[1,"/dev/nvme1n1",6251233968,"Micron_9300_MTFDHAL3T2TDR",4096,"/sys/block/nvme1n1"],[2,"/dev/nvme2n1",6251233968,"Micron_9300_MTFDHAL3T2TDR",4096,"/sys/block/nvme2n1"],[3,"/dev/nvme3n1",6251233968,"Micron_9300_MTFDHAL3T2TDR",4096,"/sys/block/nvme3n1"],[4,"/dev/nvme4n1",976773168,"Samsung SSD 970 EVO Plus 500GB",512,"/sys/block/nvme4n1"],[5,"/dev/nvme5n1",732585168,"INTEL SSDPED1K375GA",512,"/sys/block/nvme5n1"],[6,"/dev/sda",468862128,"SAMSUNG MZ7KM240",512,"/sys/block/sda"],[7,"/dev/sdb",468862128,"SAMSUNG MZ7KM240",512,"/sys/block/sdb"],[8,"/dev/sdc",468862128,"SAMSUNG MZ7KM240",512,"/sys/block/sdc"],[9,"/dev/sdd",468862128,"SAMSUNG MZ7KM240",512,"/sys/block/sdd"]],"hvm_supported":1,"ipconf":{"default":"4","dnsserver":"192.168.1.254","domain":null,"gateway":"192.168.1.1","ifaces":{"10":{"driver":"mlx5_core","flags":"NO-CARRIER,BROADCAST,MULTICAST,UP","mac" :"24:8a:07:1e:05:bd","name":"enp193s0f1np1","state":"DOWN"},"2":{"driver":"igb","flags":"NO-CARRIER,BROADCAST,MULTICAST,UP","mac":"a0:36:9f:0a:b3:82","name":"enp65s0f0","state":"DOWN"},"3":{"driver":"igb","flags":"NO-CARRIER,BROADCAST,MULTICAST,UP","mac":"a0:36:9f:0a:b3:83","name":"enp65s0f1","state":"DOWN"},"4":{"driver":"igb","flags":"BROADCAST,MULTICAST,UP,LOWER_UP","inet":{"addr":"192.168.1.114","mask":"255.255.240.0","prefix":20},"mac":"b4:2e:99:ac:ad:b4","name":"eno1","state":"UP"},"5":{"driver":"cdc_ether","flags":"BROADCAST,MULTICAST,UP,LOWER_UP","mac":"5a:47:32:dd:c7:47","name":"enx5a4732ddc747","state":"UNKNOWN"},"6":{"driver":"igb","flags":"BROADCAST,MULTICAST,UP,LOWER_UP","mac":"b4:2e:99:ac:ad:b5","name":"eno2","state":"UP"},"7":{"driver":"mlx5_core","flags":"NO-CARRIER,BROADCAST,MULTICAST,UP","mac":"1c:34:da:5c:5e:24","name":"enp129s0f0np0","state":"DOWN"},"8":{"driver":"mlx5_core","flags":"NO-CARRIER,BROADCAST,MULTICAST,UP","mac":"1c:34:da:5c:5e:25","name":"enp129s0f1n p1","state":"DOWN"},"9":{"driver":"mlx5_core","flags":"BROADCAST,MULTICAST,UP,LOWER_UP","mac":"24:8a:07:1e:05:bc","name":"enp193s0f0np0","state":"UP"}}},"kernel_cmdline":"BOOT_IMAGE=/boot/linux26 ro ramdisk_size=16777216 rw splash=verbose proxdebug vga=788","network":{"hostname":"pveauto","dns":{"dns":["192.168.1.254"],"domain":null},"interfaces":{"eno1":{"addresses":[{"address":"192.168.1.114","family":"inet","prefix":24}],"index":4,"mac":"b4:2e:99:ac:ad:b4","name":"eno1","state":"UP"},"eno2":{"index":6,"mac":"b4:2e:99:ac:ad:b5","name":"eno2","state":"UP"},"enp129s0f0np0":{"index":7,"mac":"1c:34:da:5c:5e:24","name":"enp129s0f0np0","state":"DOWN"},"enp129s0f1np1":{"index":8,"mac":"1c:34:da:5c:5e:25","name":"enp129s0f1np1","state":"DOWN"},"enp193s0f0np0":{"index":9,"mac":"24:8a:07:1e:05:bc","name":"enp193s0f0np0","state":"UP"},"enp193s0f1np1":{"index":10,"mac":"24:8a:07:1e:05:bd","name":"enp193s0f1np1","state":"DOWN"},"enp65s0f0":{"index":2,"mac":"a0:36:9f:0a:b3:82","name":"enp65s0f0 ","state":"DOWN"},"enp65s0f1":{"index":3,"mac":"a0:36:9f:0a:b3:83","name":"enp65s0f1","state":"DOWN"},"enx5a4732ddc747":{"index":5,"mac":"5a:47:32:dd:c7:47","name":"enx5a4732ddc747","state":"UNKNOWN"}},"routes":{"gateway4":{"dev":"eno1","gateway":"192.168.1.1"}}},"total_memory":257597} diff --git a/proxmox-auto-installer/tests/resources/parse_answer_fail/fqdn_from_dhcp_no_default_domain.toml b/proxmox-auto-installer/tests/resources/parse_answer_fail/fqdn_from_dhcp_no_default_domain.toml new file mode 100644 index 0000000..9d13a5f --- /dev/null +++ b/proxmox-auto-installer/tests/resources/parse_answer_fail/fqdn_from_dhcp_no_default_domain.toml @@ -0,0 +1,14 @@ +[global] +keyboard = "de" +country = "at" +fqdn.source = "from-dhcp" +mailto = "mail@no.invalid" +timezone = "Europe/Vienna" +root_password = "12345678" + +[network] +source = "from-dhcp" + +[disk-setup] +filesystem = "ext4" +disk_list = ["sda"] diff --git a/proxmox-auto-installer/tests/resources/parse_answer_fail/fqdn_hostname_only.json b/proxmox-auto-installer/tests/resources/parse_answer_fail/fqdn_hostname_only.json new file mode 100644 index 0000000..5293b40 --- /dev/null +++ b/proxmox-auto-installer/tests/resources/parse_answer_fail/fqdn_hostname_only.json @@ -0,0 +1,3 @@ +{ + "parse-error": "error parsing answer.toml: either a fully-qualified domain name or extendend configuration for usage with DHCP must be specified" +} diff --git a/proxmox-auto-installer/tests/resources/parse_answer_fail/fqdn_hostname_only.toml b/proxmox-auto-installer/tests/resources/parse_answer_fail/fqdn_hostname_only.toml new file mode 100644 index 0000000..a0a22ef --- /dev/null +++ b/proxmox-auto-installer/tests/resources/parse_answer_fail/fqdn_hostname_only.toml @@ -0,0 +1,14 @@ +[global] +keyboard = "de" +country = "at" +fqdn = "foobar" +mailto = "mail@no.invalid" +timezone = "Europe/Vienna" +root_password = "12345678" + +[network] +source = "from-dhcp" + +[disk-setup] +filesystem = "ext4" +disk_list = ["sda"] diff --git a/proxmox-auto-installer/tests/resources/parse_answer_fail/no_fqdn_from_dhcp.json b/proxmox-auto-installer/tests/resources/parse_answer_fail/no_fqdn_from_dhcp.json new file mode 100644 index 0000000..49a64e5 --- /dev/null +++ b/proxmox-auto-installer/tests/resources/parse_answer_fail/no_fqdn_from_dhcp.json @@ -0,0 +1,3 @@ +{ + "error": "`global.fqdn.source` set to \"from-dhcp\", but DHCP server did not provide a hostname!" +} diff --git a/proxmox-auto-installer/tests/resources/parse_answer_fail/no_fqdn_from_dhcp.run-env.json b/proxmox-auto-installer/tests/resources/parse_answer_fail/no_fqdn_from_dhcp.run-env.json new file mode 100644 index 0000000..6762470 --- /dev/null +++ b/proxmox-auto-installer/tests/resources/parse_answer_fail/no_fqdn_from_dhcp.run-env.json @@ -0,0 +1 @@ +{"boot_type":"efi","country":"at","disks":[[0,"/dev/nvme0n1",6251233968,"Micron_9300_MTFDHAL3T2TDR",4096,"/sys/block/nvme0n1"],[1,"/dev/nvme1n1",6251233968,"Micron_9300_MTFDHAL3T2TDR",4096,"/sys/block/nvme1n1"],[2,"/dev/nvme2n1",6251233968,"Micron_9300_MTFDHAL3T2TDR",4096,"/sys/block/nvme2n1"],[3,"/dev/nvme3n1",6251233968,"Micron_9300_MTFDHAL3T2TDR",4096,"/sys/block/nvme3n1"],[4,"/dev/nvme4n1",976773168,"Samsung SSD 970 EVO Plus 500GB",512,"/sys/block/nvme4n1"],[5,"/dev/nvme5n1",732585168,"INTEL SSDPED1K375GA",512,"/sys/block/nvme5n1"],[6,"/dev/sda",468862128,"SAMSUNG MZ7KM240",512,"/sys/block/sda"],[7,"/dev/sdb",468862128,"SAMSUNG MZ7KM240",512,"/sys/block/sdb"],[8,"/dev/sdc",468862128,"SAMSUNG MZ7KM240",512,"/sys/block/sdc"],[9,"/dev/sdd",468862128,"SAMSUNG MZ7KM240",512,"/sys/block/sdd"]],"hvm_supported":1,"ipconf":{"default":"4","dnsserver":"192.168.1.254","domain":null,"gateway":"192.168.1.1","ifaces":{"10":{"driver":"mlx5_core","flags":"NO-CARRIER,BROADCAST,MULTICAST,UP","mac" :"24:8a:07:1e:05:bd","name":"enp193s0f1np1","state":"DOWN"},"2":{"driver":"igb","flags":"NO-CARRIER,BROADCAST,MULTICAST,UP","mac":"a0:36:9f:0a:b3:82","name":"enp65s0f0","state":"DOWN"},"3":{"driver":"igb","flags":"NO-CARRIER,BROADCAST,MULTICAST,UP","mac":"a0:36:9f:0a:b3:83","name":"enp65s0f1","state":"DOWN"},"4":{"driver":"igb","flags":"BROADCAST,MULTICAST,UP,LOWER_UP","inet":{"addr":"192.168.1.114","mask":"255.255.240.0","prefix":20},"mac":"b4:2e:99:ac:ad:b4","name":"eno1","state":"UP"},"5":{"driver":"cdc_ether","flags":"BROADCAST,MULTICAST,UP,LOWER_UP","mac":"5a:47:32:dd:c7:47","name":"enx5a4732ddc747","state":"UNKNOWN"},"6":{"driver":"igb","flags":"BROADCAST,MULTICAST,UP,LOWER_UP","mac":"b4:2e:99:ac:ad:b5","name":"eno2","state":"UP"},"7":{"driver":"mlx5_core","flags":"NO-CARRIER,BROADCAST,MULTICAST,UP","mac":"1c:34:da:5c:5e:24","name":"enp129s0f0np0","state":"DOWN"},"8":{"driver":"mlx5_core","flags":"NO-CARRIER,BROADCAST,MULTICAST,UP","mac":"1c:34:da:5c:5e:25","name":"enp129s0f1n p1","state":"DOWN"},"9":{"driver":"mlx5_core","flags":"BROADCAST,MULTICAST,UP,LOWER_UP","mac":"24:8a:07:1e:05:bc","name":"enp193s0f0np0","state":"UP"}}},"kernel_cmdline":"BOOT_IMAGE=/boot/linux26 ro ramdisk_size=16777216 rw splash=verbose proxdebug vga=788","network":{"dns":{"dns":["192.168.1.254"],"domain":null},"interfaces":{"eno1":{"addresses":[{"address":"192.168.1.114","family":"inet","prefix":24}],"index":4,"mac":"b4:2e:99:ac:ad:b4","name":"eno1","state":"UP"},"eno2":{"index":6,"mac":"b4:2e:99:ac:ad:b5","name":"eno2","state":"UP"},"enp129s0f0np0":{"index":7,"mac":"1c:34:da:5c:5e:24","name":"enp129s0f0np0","state":"DOWN"},"enp129s0f1np1":{"index":8,"mac":"1c:34:da:5c:5e:25","name":"enp129s0f1np1","state":"DOWN"},"enp193s0f0np0":{"index":9,"mac":"24:8a:07:1e:05:bc","name":"enp193s0f0np0","state":"UP"},"enp193s0f1np1":{"index":10,"mac":"24:8a:07:1e:05:bd","name":"enp193s0f1np1","state":"DOWN"},"enp65s0f0":{"index":2,"mac":"a0:36:9f:0a:b3:82","name":"enp65s0f0","state":"DOWN"},"en p65s0f1":{"index":3,"mac":"a0:36:9f:0a:b3:83","name":"enp65s0f1","state":"DOWN"},"enx5a4732ddc747":{"index":5,"mac":"5a:47:32:dd:c7:47","name":"enx5a4732ddc747","state":"UNKNOWN"}},"routes":{"gateway4":{"dev":"eno1","gateway":"192.168.1.1"}}},"total_memory":257597} diff --git a/proxmox-auto-installer/tests/resources/parse_answer_fail/no_fqdn_from_dhcp.toml b/proxmox-auto-installer/tests/resources/parse_answer_fail/no_fqdn_from_dhcp.toml new file mode 100644 index 0000000..9d13a5f --- /dev/null +++ b/proxmox-auto-installer/tests/resources/parse_answer_fail/no_fqdn_from_dhcp.toml @@ -0,0 +1,14 @@ +[global] +keyboard = "de" +country = "at" +fqdn.source = "from-dhcp" +mailto = "mail@no.invalid" +timezone = "Europe/Vienna" +root_password = "12345678" + +[network] +source = "from-dhcp" + +[disk-setup] +filesystem = "ext4" +disk_list = ["sda"] diff --git a/proxmox-auto-installer/tests/resources/run-env-info.json b/proxmox-auto-installer/tests/resources/run-env-info.json index 6762470..2687a8a 100644 --- a/proxmox-auto-installer/tests/resources/run-env-info.json +++ b/proxmox-auto-installer/tests/resources/run-env-info.json @@ -1 +1 @@ -{"boot_type":"efi","country":"at","disks":[[0,"/dev/nvme0n1",6251233968,"Micron_9300_MTFDHAL3T2TDR",4096,"/sys/block/nvme0n1"],[1,"/dev/nvme1n1",6251233968,"Micron_9300_MTFDHAL3T2TDR",4096,"/sys/block/nvme1n1"],[2,"/dev/nvme2n1",6251233968,"Micron_9300_MTFDHAL3T2TDR",4096,"/sys/block/nvme2n1"],[3,"/dev/nvme3n1",6251233968,"Micron_9300_MTFDHAL3T2TDR",4096,"/sys/block/nvme3n1"],[4,"/dev/nvme4n1",976773168,"Samsung SSD 970 EVO Plus 500GB",512,"/sys/block/nvme4n1"],[5,"/dev/nvme5n1",732585168,"INTEL SSDPED1K375GA",512,"/sys/block/nvme5n1"],[6,"/dev/sda",468862128,"SAMSUNG MZ7KM240",512,"/sys/block/sda"],[7,"/dev/sdb",468862128,"SAMSUNG MZ7KM240",512,"/sys/block/sdb"],[8,"/dev/sdc",468862128,"SAMSUNG MZ7KM240",512,"/sys/block/sdc"],[9,"/dev/sdd",468862128,"SAMSUNG MZ7KM240",512,"/sys/block/sdd"]],"hvm_supported":1,"ipconf":{"default":"4","dnsserver":"192.168.1.254","domain":null,"gateway":"192.168.1.1","ifaces":{"10":{"driver":"mlx5_core","flags":"NO-CARRIER,BROADCAST,MULTICAST,UP","mac" :"24:8a:07:1e:05:bd","name":"enp193s0f1np1","state":"DOWN"},"2":{"driver":"igb","flags":"NO-CARRIER,BROADCAST,MULTICAST,UP","mac":"a0:36:9f:0a:b3:82","name":"enp65s0f0","state":"DOWN"},"3":{"driver":"igb","flags":"NO-CARRIER,BROADCAST,MULTICAST,UP","mac":"a0:36:9f:0a:b3:83","name":"enp65s0f1","state":"DOWN"},"4":{"driver":"igb","flags":"BROADCAST,MULTICAST,UP,LOWER_UP","inet":{"addr":"192.168.1.114","mask":"255.255.240.0","prefix":20},"mac":"b4:2e:99:ac:ad:b4","name":"eno1","state":"UP"},"5":{"driver":"cdc_ether","flags":"BROADCAST,MULTICAST,UP,LOWER_UP","mac":"5a:47:32:dd:c7:47","name":"enx5a4732ddc747","state":"UNKNOWN"},"6":{"driver":"igb","flags":"BROADCAST,MULTICAST,UP,LOWER_UP","mac":"b4:2e:99:ac:ad:b5","name":"eno2","state":"UP"},"7":{"driver":"mlx5_core","flags":"NO-CARRIER,BROADCAST,MULTICAST,UP","mac":"1c:34:da:5c:5e:24","name":"enp129s0f0np0","state":"DOWN"},"8":{"driver":"mlx5_core","flags":"NO-CARRIER,BROADCAST,MULTICAST,UP","mac":"1c:34:da:5c:5e:25","name":"enp129s0f1n p1","state":"DOWN"},"9":{"driver":"mlx5_core","flags":"BROADCAST,MULTICAST,UP,LOWER_UP","mac":"24:8a:07:1e:05:bc","name":"enp193s0f0np0","state":"UP"}}},"kernel_cmdline":"BOOT_IMAGE=/boot/linux26 ro ramdisk_size=16777216 rw splash=verbose proxdebug vga=788","network":{"dns":{"dns":["192.168.1.254"],"domain":null},"interfaces":{"eno1":{"addresses":[{"address":"192.168.1.114","family":"inet","prefix":24}],"index":4,"mac":"b4:2e:99:ac:ad:b4","name":"eno1","state":"UP"},"eno2":{"index":6,"mac":"b4:2e:99:ac:ad:b5","name":"eno2","state":"UP"},"enp129s0f0np0":{"index":7,"mac":"1c:34:da:5c:5e:24","name":"enp129s0f0np0","state":"DOWN"},"enp129s0f1np1":{"index":8,"mac":"1c:34:da:5c:5e:25","name":"enp129s0f1np1","state":"DOWN"},"enp193s0f0np0":{"index":9,"mac":"24:8a:07:1e:05:bc","name":"enp193s0f0np0","state":"UP"},"enp193s0f1np1":{"index":10,"mac":"24:8a:07:1e:05:bd","name":"enp193s0f1np1","state":"DOWN"},"enp65s0f0":{"index":2,"mac":"a0:36:9f:0a:b3:82","name":"enp65s0f0","state":"DOWN"},"en p65s0f1":{"index":3,"mac":"a0:36:9f:0a:b3:83","name":"enp65s0f1","state":"DOWN"},"enx5a4732ddc747":{"index":5,"mac":"5a:47:32:dd:c7:47","name":"enx5a4732ddc747","state":"UNKNOWN"}},"routes":{"gateway4":{"dev":"eno1","gateway":"192.168.1.1"}}},"total_memory":257597} +{"boot_type":"efi","country":"at","disks":[[0,"/dev/nvme0n1",6251233968,"Micron_9300_MTFDHAL3T2TDR",4096,"/sys/block/nvme0n1"],[1,"/dev/nvme1n1",6251233968,"Micron_9300_MTFDHAL3T2TDR",4096,"/sys/block/nvme1n1"],[2,"/dev/nvme2n1",6251233968,"Micron_9300_MTFDHAL3T2TDR",4096,"/sys/block/nvme2n1"],[3,"/dev/nvme3n1",6251233968,"Micron_9300_MTFDHAL3T2TDR",4096,"/sys/block/nvme3n1"],[4,"/dev/nvme4n1",976773168,"Samsung SSD 970 EVO Plus 500GB",512,"/sys/block/nvme4n1"],[5,"/dev/nvme5n1",732585168,"INTEL SSDPED1K375GA",512,"/sys/block/nvme5n1"],[6,"/dev/sda",468862128,"SAMSUNG MZ7KM240",512,"/sys/block/sda"],[7,"/dev/sdb",468862128,"SAMSUNG MZ7KM240",512,"/sys/block/sdb"],[8,"/dev/sdc",468862128,"SAMSUNG MZ7KM240",512,"/sys/block/sdc"],[9,"/dev/sdd",468862128,"SAMSUNG MZ7KM240",512,"/sys/block/sdd"]],"hvm_supported":1,"ipconf":{"default":"4","dnsserver":"192.168.1.254","domain":"test.local","gateway":"192.168.1.1","ifaces":{"10":{"driver":"mlx5_core","flags":"NO-CARRIER,BROADCAST,MULTICAST,U P","mac":"24:8a:07:1e:05:bd","name":"enp193s0f1np1","state":"DOWN"},"2":{"driver":"igb","flags":"NO-CARRIER,BROADCAST,MULTICAST,UP","mac":"a0:36:9f:0a:b3:82","name":"enp65s0f0","state":"DOWN"},"3":{"driver":"igb","flags":"NO-CARRIER,BROADCAST,MULTICAST,UP","mac":"a0:36:9f:0a:b3:83","name":"enp65s0f1","state":"DOWN"},"4":{"driver":"igb","flags":"BROADCAST,MULTICAST,UP,LOWER_UP","inet":{"addr":"192.168.1.114","mask":"255.255.240.0","prefix":20},"mac":"b4:2e:99:ac:ad:b4","name":"eno1","state":"UP"},"5":{"driver":"cdc_ether","flags":"BROADCAST,MULTICAST,UP,LOWER_UP","mac":"5a:47:32:dd:c7:47","name":"enx5a4732ddc747","state":"UNKNOWN"},"6":{"driver":"igb","flags":"BROADCAST,MULTICAST,UP,LOWER_UP","mac":"b4:2e:99:ac:ad:b5","name":"eno2","state":"UP"},"7":{"driver":"mlx5_core","flags":"NO-CARRIER,BROADCAST,MULTICAST,UP","mac":"1c:34:da:5c:5e:24","name":"enp129s0f0np0","state":"DOWN"},"8":{"driver":"mlx5_core","flags":"NO-CARRIER,BROADCAST,MULTICAST,UP","mac":"1c:34:da:5c:5e:25","name":"enp 129s0f1np1","state":"DOWN"},"9":{"driver":"mlx5_core","flags":"BROADCAST,MULTICAST,UP,LOWER_UP","mac":"24:8a:07:1e:05:bc","name":"enp193s0f0np0","state":"UP"}}},"kernel_cmdline":"BOOT_IMAGE=/boot/linux26 ro ramdisk_size=16777216 rw splash=verbose proxdebug vga=788","network":{"hostname":"pveauto","dns":{"dns":["192.168.1.254"],"domain":"test.local"},"interfaces":{"eno1":{"addresses":[{"address":"192.168.1.114","family":"inet","prefix":24}],"index":4,"mac":"b4:2e:99:ac:ad:b4","name":"eno1","state":"UP"},"eno2":{"index":6,"mac":"b4:2e:99:ac:ad:b5","name":"eno2","state":"UP"},"enp129s0f0np0":{"index":7,"mac":"1c:34:da:5c:5e:24","name":"enp129s0f0np0","state":"DOWN"},"enp129s0f1np1":{"index":8,"mac":"1c:34:da:5c:5e:25","name":"enp129s0f1np1","state":"DOWN"},"enp193s0f0np0":{"index":9,"mac":"24:8a:07:1e:05:bc","name":"enp193s0f0np0","state":"UP"},"enp193s0f1np1":{"index":10,"mac":"24:8a:07:1e:05:bd","name":"enp193s0f1np1","state":"DOWN"},"enp65s0f0":{"index":2,"mac":"a0:36:9f:0a:b3:82"," name":"enp65s0f0","state":"DOWN"},"enp65s0f1":{"index":3,"mac":"a0:36:9f:0a:b3:83","name":"enp65s0f1","state":"DOWN"},"enx5a4732ddc747":{"index":5,"mac":"5a:47:32:dd:c7:47","name":"enx5a4732ddc747","state":"UNKNOWN"}},"routes":{"gateway4":{"dev":"eno1","gateway":"192.168.1.1"}}},"total_memory":257597} diff --git a/proxmox-post-hook/src/main.rs b/proxmox-post-hook/src/main.rs index d03ce21..959a0d7 100644 --- a/proxmox-post-hook/src/main.rs +++ b/proxmox-post-hook/src/main.rs @@ -21,11 +21,11 @@ use std::{ use anyhow::{Context, Result, anyhow, bail}; use proxmox_auto_installer::{ - answer::{Answer, PostNotificationHookInfo}, + answer::{Answer, FqdnConfig, FqdnExtendedConfig, FqdnSourceMode, PostNotificationHookInfo}, udevinfo::{UdevInfo, UdevProperties}, }; use proxmox_installer_common::{ - options::{Disk, FsType}, + options::{Disk, FsType, NetworkOptions}, setup::{ BootType, InstallConfig, IsoInfo, ProxmoxProduct, RuntimeInfo, SetupInfo, load_installer_setup_files, @@ -247,6 +247,19 @@ impl PostHookInfo { .and_then(|r| Ok(String::from_utf8(r.stdout)?)) }; + let fqdn = match &answer.global.fqdn { + FqdnConfig::Simple(name) => name.to_string(), + FqdnConfig::Extended(FqdnExtendedConfig { + source: FqdnSourceMode::FromDhcp, + domain, + }) => NetworkOptions::construct_fqdn( + &run_env.network, + setup_info.config.product.default_hostname(), + domain.as_deref(), + ) + .to_string(), + }; + Ok(Self { schema: PostHookInfoSchema::default(), debian_version: read_file("/etc/debian_version")?, @@ -260,7 +273,7 @@ impl PostHookInfo { cpu_info: Self::gather_cpu_info(&run_env)?, dmi: SystemDMI::get()?, filesystem: answer.disks.fs_type, - fqdn: answer.global.fqdn.to_string(), + fqdn, machine_id: read_file("/etc/machine-id")?, disks: Self::gather_disks(&config, &run_env, &udev)?, network_interfaces: Self::gather_nic(&config, &run_env, &udev)?, -- 2.48.1 _______________________________________________ pve-devel mailing list pve-devel@lists.proxmox.com https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel