* Re: [pve-devel] [PATCH installer 1/1] fix #2164: add option to define a vlan tag within the installer
[not found] <3978889E-73FA-4473-A70B-2C660662CC3D@credativ.de>
@ 2025-09-23 12:07 ` Christoph Heiss
2025-09-24 8:48 ` Aaron Lauterer
0 siblings, 1 reply; 4+ messages in thread
From: Christoph Heiss @ 2025-09-23 12:07 UTC (permalink / raw)
To: Florian Paul Azim Hoberg; +Cc: pve-devel
The subject should be rephrased to e.g. "partially fix #2164", as the
Bugzilla entry also mentions setting up bonds.
Didn't do any testing yet, but some comments inline:
On Mon Sep 22, 2025 at 2:30 PM CEST, Florian Paul Azim Hoberg wrote:
> To ensure a Promox node can access a desired network
> resource which requires a given vlan tag, this feature
> adds the possibility to optionally define a vlan tag
> within the auto installer, tui and gui.
s/this feature adds/add/g
Also could mention that it only applies to the selected management
interface/bridge.
>
> Signed-off-by: Florian Paul Azim Hoberg @gyptazy <florian.hoberg@credativ.de>
> ---
>
> initial commit:
> * Add possibility to optionally add vlan tag in:
> - auto installer
> - tui
> - gui
> * Tagged interface will be generated as:
> $interface.$tag in /etc/network/interfaces
> * Simple validation of given vlan tag:
> - Must be digit
> - Must be smaller than int(4094)
That can all be part of the commit message, as that is useful
information.
[..]
> diff --git a/html/ack_template.htm b/html/ack_template.htm
> index 48d7213..4404321 100644
> --- a/html/ack_template.htm
> +++ b/html/ack_template.htm
> @@ -54,6 +54,8 @@
>
> <tr><td>Management Interface:</td> <td>__interface__</td></tr>
>
> + <tr><td>Management Interface vlan tag:</td> <td>__vlan__</td></tr>
VLAN should be consistently spelled uppercase everywhere user-visible.
Also; wondering if we maybe should just hide this if no VLAN tag is set,
no not clutter the summary page unnecessarily?
> +
> <tr><td>Hostname:</td> <td>__hostname__</td></tr>
>
> <tr><td>IP CIDR:</td> <td>__cidr__</td></tr>
> diff --git a/proxinstall b/proxinstall
> index 5ba65fa..13ece1d 100755
> --- a/proxinstall
> +++ b/proxinstall
> @@ -472,6 +472,14 @@ sub create_ipconf_view {
> $grid->attach($dns_label, 0, 4, 1, 1);
> $grid->attach($ipconf_entry_dns, 1, 4, 1, 1);
>
> + my $cfg_vlan = Proxmox::Install::Config::get_vlan();
> + my $vlan = defined($cfg_vlan) ? $cfg_vlan : '';
Can be simplified to
my $cfg_vlan = Proxmox::Install::Config::get_vlan() // '';
> +
> + my ($vlan_label, $ipconf_entry_vlan) = create_text_input($vlan, 'VLAN Tag (Optional)');
> +
> + $grid->attach($vlan_label, 0, 5, 1, 1);
> + $grid->attach($ipconf_entry_vlan, 1, 5, 1, 1);
> +
> $gtk_state->{inbox}->show_all;
> set_next(
> undef,
> @@ -538,7 +546,19 @@ sub create_ipconf_view {
> }
> Proxmox::Install::Config::set_dns($dns_ip);
>
> - #print STDERR "TEST $ipaddress/$netmask $gateway_ip $dns_ip\n";
> + my $vlan = $ipconf_entry_vlan->get_text();
> + if ($vlan !~ /^\d*$/) {
> + Proxmox::UI::message("VLAN must contain only digits.");
> + $ipconf_entry_vlan->grab_focus();
> + return;
> + }
> + if ($vlan ne '' && $vlan >= 4094) {
> + Proxmox::UI::message("VLAN must be smaller than 4094.");
> + $ipconf_entry_vlan->grab_focus();
> + return;
> + }
Should also check for 0, as that is also a reserved value.
> + $vlan = undef if $vlan eq '';
> + Proxmox::Install::Config::set_vlan($vlan);
>
> $step_number++;
> create_ack_view();
> @@ -585,6 +605,7 @@ sub create_ack_view {
> __cidr__ => Proxmox::Install::Config::get_cidr(),
> __gateway__ => Proxmox::Install::Config::get_gateway(),
> __dnsserver__ => Proxmox::Install::Config::get_dns(),
> + __vlan__ => Proxmox::Install::Config::get_vlan(),
Depending on above, whether to hide it if unset or not, in the latter
case this should at least default to 'None' as in the TUI.
> );
>
> while (my ($k, $v) = each %config_values) {
> diff --git a/proxmox-auto-installer/src/answer.rs b/proxmox-auto-installer/src/answer.rs
> index 88f4c87..cea5cb1 100644
> --- a/proxmox-auto-installer/src/answer.rs
> +++ b/proxmox-auto-installer/src/answer.rs
> @@ -186,6 +186,7 @@ struct NetworkInAnswer {
> pub cidr: Option<CidrAddress>,
> pub dns: Option<IpAddr>,
> pub gateway: Option<IpAddr>,
> + pub vlan: Option<u16>,
> #[serde(default)]
> pub filter: BTreeMap<String, String>,
> }
> @@ -219,6 +220,7 @@ impl TryFrom<NetworkInAnswer> for Network {
> cidr: network.cidr.unwrap(),
> dns: network.dns.unwrap(),
> gateway: network.gateway.unwrap(),
> + vlan: network.vlan,
Before setting this, the same check as for the GUI/TUI can be
implemented above.
And it's missing the check that `vlan` is unset as with the other
properties below in the DHCP case.
> filter: network.filter,
> }),
> })
> @@ -254,6 +256,7 @@ pub struct NetworkManual {
> pub cidr: CidrAddress,
> pub dns: IpAddr,
> pub gateway: IpAddr,
> + pub vlan: Option<u16>,
> pub filter: BTreeMap<String, String>,
> }
>
> diff --git a/proxmox-auto-installer/src/utils.rs b/proxmox-auto-installer/src/utils.rs
> index 7d42f2c..2fdb6df 100644
> --- a/proxmox-auto-installer/src/utils.rs
> +++ b/proxmox-auto-installer/src/utils.rs
> @@ -66,6 +66,7 @@ fn get_network_settings(
> network_options.address = settings.cidr.clone();
> network_options.dns_server = settings.dns;
> network_options.gateway = settings.gateway;
> + network_options.vlan = settings.vlan;
> network_options.ifname = get_single_udev_index(&settings.filter, &udev_info.nics)?;
> }
> info!("Network interface used is '{}'", &network_options.ifname);
> @@ -494,6 +495,7 @@ pub fn parse_answer(
> domain: network_settings.fqdn.domain(),
> cidr: network_settings.address,
> gateway: network_settings.gateway,
> + vlan: network_settings.vlan,
> dns: network_settings.dns_server,
>
> first_boot: InstallFirstBootSetup::default(),
[..]
> diff --git a/proxmox-auto-installer/tests/resources/parse_answer/network_vlan.toml b/proxmox-auto-installer/tests/resources/parse_answer/network_vlan.toml
> new file mode 100644
> index 0000000..fad56c6
> --- /dev/null
> +++ b/proxmox-auto-installer/tests/resources/parse_answer/network_vlan.toml
> @@ -0,0 +1,19 @@
> +[global]
> +keyboard = "de"
> +country = "at"
> +fqdn = "pveauto.testinstall"
> +mailto = "mail@no.invalid"
> +timezone = "Europe/Vienna"
> +root-password = "12345678"
> +
> +[network]
> +source = "from-answer"
> +cidr = "10.10.10.10/24"
> +dns = "10.10.10.1"
> +vlan = 123
> +gateway = "10.10.10.1"
> +filter.ID_NET_NAME = "enp129s0f1np1"
> +
> +[disk-setup]
> +filesystem = "ext4"
> +disk-list = ["sda"]
[..]
> diff --git a/proxmox-auto-installer/tests/resources/parse_answer/nic_matching.toml b/proxmox-auto-installer/tests/resources/parse_answer/nic_matching.toml
> index 901f894..723dfc8 100644
> --- a/proxmox-auto-installer/tests/resources/parse_answer/nic_matching.toml
> +++ b/proxmox-auto-installer/tests/resources/parse_answer/nic_matching.toml
> @@ -10,6 +10,7 @@ root-password = "12345678"
> source = "from-answer"
> cidr = "10.10.10.10/24"
> dns = "10.10.10.1"
> +vlan = 123
Any reason for adding it to this test too, as the `network_vlan` test
above seems to be the exact same?
> gateway = "10.10.10.1"
> filter.ID_NET_NAME_MAC = "*a0369f0ab382"
>
[..]
> diff --git a/proxmox-installer-common/src/setup.rs b/proxmox-installer-common/src/setup.rs
> index 66cea72..23e43d2 100644
> --- a/proxmox-installer-common/src/setup.rs
> +++ b/proxmox-installer-common/src/setup.rs
> @@ -580,6 +580,7 @@ pub struct InstallConfig {
> #[serde(serialize_with = "serialize_as_display")]
> pub cidr: CidrAddress,
> pub gateway: IpAddr,
> + pub vlan: Option<u16>,
Should be annotated with
#[serde(skip_serializing_if = "Option::is_none")]
to avoid serializing it as `null` if unset.
> pub dns: IpAddr,
>
> pub first_boot: InstallFirstBootSetup,
> diff --git a/proxmox-tui-installer/src/main.rs b/proxmox-tui-installer/src/main.rs
> index 15ee5d3..21ef16f 100644
> --- a/proxmox-tui-installer/src/main.rs
> +++ b/proxmox-tui-installer/src/main.rs
[..]
> @@ -552,6 +560,23 @@ fn network_dialog(siv: &mut Cursive) -> InstallerView {
> .parse::<IpAddr>()
> .map_err(|err| err.to_string())?;
>
> + let vlan_str = view
> + .get_value::<EditView, _>(5)
> + .ok_or("failed to retrieve VLAN")?;
> +
> + let vlan = if vlan_str.trim().is_empty() {
> + None
> + } else {
> + let parsed_vlan = vlan_str.trim().parse::<u16>()
> + .map_err(|e| format!("Invalid VLAN: {e}"))?;
> +
> + if parsed_vlan >= 4094 {
> + return Err(format!("VLAN must be smaller than 4094."));
> + }
Same tag 0 check as for the GUI.
[..]
> diff --git a/proxmox-tui-installer/src/options.rs b/proxmox-tui-installer/src/options.rs
> index c80877f..c59712e 100644
> --- a/proxmox-tui-installer/src/options.rs
> +++ b/proxmox-tui-installer/src/options.rs
> @@ -72,6 +72,7 @@ impl InstallerOptions {
> SummaryOption::new("Keyboard layout", kb_layout),
> SummaryOption::new("Administrator email", &self.password.email),
> SummaryOption::new("Management interface", &self.network.ifname),
> + SummaryOption::new("Management interface vlan tag", &self.network.vlan.map(|v| v.to_string()).unwrap_or("None".to_string())),
Uppercase spelling as in the GUI.
_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [pve-devel] [PATCH installer 1/1] fix #2164: add option to define a vlan tag within the installer
2025-09-23 12:07 ` [pve-devel] [PATCH installer 1/1] fix #2164: add option to define a vlan tag within the installer Christoph Heiss
@ 2025-09-24 8:48 ` Aaron Lauterer
2025-09-24 10:06 ` Florian Paul Azim Hoberg via pve-devel
0 siblings, 1 reply; 4+ messages in thread
From: Aaron Lauterer @ 2025-09-24 8:48 UTC (permalink / raw)
To: Proxmox VE development discussion, Christoph Heiss,
Florian Paul Azim Hoberg
Thanks for working on this. One more comment from my side.
Since the default network configs are often used as a guideline by our
users, they should reflect best practices.
Instead of the dot notation, I would prefer the vlan-raw-device, vlan-id
variant. This allows us to give the interface a name that matches the
use, and the whole config is more explicit.
The final config could look like this:
auto management
iface management inet static
address {host ip}/{cidr}
gateway {gateway ip}
vlan-id {vlan tag}
vlan-raw-device {physical nic}
#Management interface
On 2025-09-23 14:08, Christoph Heiss wrote:
> The subject should be rephrased to e.g. "partially fix #2164", as the
> Bugzilla entry also mentions setting up bonds.
>
> Didn't do any testing yet, but some comments inline:
>
> On Mon Sep 22, 2025 at 2:30 PM CEST, Florian Paul Azim Hoberg wrote:
>> To ensure a Promox node can access a desired network
>> resource which requires a given vlan tag, this feature
>> adds the possibility to optionally define a vlan tag
>> within the auto installer, tui and gui.
>
> s/this feature adds/add/g
>
> Also could mention that it only applies to the selected management
> interface/bridge.
>
>>
>> Signed-off-by: Florian Paul Azim Hoberg @gyptazy <florian.hoberg@credativ.de>
>> ---
>>
>> initial commit:
>> * Add possibility to optionally add vlan tag in:
>> - auto installer
>> - tui
>> - gui
>> * Tagged interface will be generated as:
>> $interface.$tag in /etc/network/interfaces
>> * Simple validation of given vlan tag:
>> - Must be digit
>> - Must be smaller than int(4094)
>
> That can all be part of the commit message, as that is useful
> information.
>
> [..]
>> diff --git a/html/ack_template.htm b/html/ack_template.htm
>> index 48d7213..4404321 100644
>> --- a/html/ack_template.htm
>> +++ b/html/ack_template.htm
>> @@ -54,6 +54,8 @@
>>
>> <tr><td>Management Interface:</td> <td>__interface__</td></tr>
>>
>> + <tr><td>Management Interface vlan tag:</td> <td>__vlan__</td></tr>
>
> VLAN should be consistently spelled uppercase everywhere user-visible.
>
> Also; wondering if we maybe should just hide this if no VLAN tag is set,
> no not clutter the summary page unnecessarily?
>
>> +
>> <tr><td>Hostname:</td> <td>__hostname__</td></tr>
>>
>> <tr><td>IP CIDR:</td> <td>__cidr__</td></tr>
>> diff --git a/proxinstall b/proxinstall
>> index 5ba65fa..13ece1d 100755
>> --- a/proxinstall
>> +++ b/proxinstall
>> @@ -472,6 +472,14 @@ sub create_ipconf_view {
>> $grid->attach($dns_label, 0, 4, 1, 1);
>> $grid->attach($ipconf_entry_dns, 1, 4, 1, 1);
>>
>> + my $cfg_vlan = Proxmox::Install::Config::get_vlan();
>> + my $vlan = defined($cfg_vlan) ? $cfg_vlan : '';
>
> Can be simplified to
>
> my $cfg_vlan = Proxmox::Install::Config::get_vlan() // '';
>
>> +
>> + my ($vlan_label, $ipconf_entry_vlan) = create_text_input($vlan, 'VLAN Tag (Optional)');
>> +
>> + $grid->attach($vlan_label, 0, 5, 1, 1);
>> + $grid->attach($ipconf_entry_vlan, 1, 5, 1, 1);
>> +
>> $gtk_state->{inbox}->show_all;
>> set_next(
>> undef,
>> @@ -538,7 +546,19 @@ sub create_ipconf_view {
>> }
>> Proxmox::Install::Config::set_dns($dns_ip);
>>
>> - #print STDERR "TEST $ipaddress/$netmask $gateway_ip $dns_ip\n";
>> + my $vlan = $ipconf_entry_vlan->get_text();
>> + if ($vlan !~ /^\d*$/) {
>> + Proxmox::UI::message("VLAN must contain only digits.");
>> + $ipconf_entry_vlan->grab_focus();
>> + return;
>> + }
>> + if ($vlan ne '' && $vlan >= 4094) {
>> + Proxmox::UI::message("VLAN must be smaller than 4094.");
>> + $ipconf_entry_vlan->grab_focus();
>> + return;
>> + }
>
> Should also check for 0, as that is also a reserved value.
>
>> + $vlan = undef if $vlan eq '';
>> + Proxmox::Install::Config::set_vlan($vlan);
>>
>> $step_number++;
>> create_ack_view();
>> @@ -585,6 +605,7 @@ sub create_ack_view {
>> __cidr__ => Proxmox::Install::Config::get_cidr(),
>> __gateway__ => Proxmox::Install::Config::get_gateway(),
>> __dnsserver__ => Proxmox::Install::Config::get_dns(),
>> + __vlan__ => Proxmox::Install::Config::get_vlan(),
>
> Depending on above, whether to hide it if unset or not, in the latter
> case this should at least default to 'None' as in the TUI.
>
>> );
>>
>> while (my ($k, $v) = each %config_values) {
>> diff --git a/proxmox-auto-installer/src/answer.rs b/proxmox-auto-installer/src/answer.rs
>> index 88f4c87..cea5cb1 100644
>> --- a/proxmox-auto-installer/src/answer.rs
>> +++ b/proxmox-auto-installer/src/answer.rs
>> @@ -186,6 +186,7 @@ struct NetworkInAnswer {
>> pub cidr: Option<CidrAddress>,
>> pub dns: Option<IpAddr>,
>> pub gateway: Option<IpAddr>,
>> + pub vlan: Option<u16>,
>> #[serde(default)]
>> pub filter: BTreeMap<String, String>,
>> }
>> @@ -219,6 +220,7 @@ impl TryFrom<NetworkInAnswer> for Network {
>> cidr: network.cidr.unwrap(),
>> dns: network.dns.unwrap(),
>> gateway: network.gateway.unwrap(),
>> + vlan: network.vlan,
>
> Before setting this, the same check as for the GUI/TUI can be
> implemented above.
>
> And it's missing the check that `vlan` is unset as with the other
> properties below in the DHCP case.
>
>> filter: network.filter,
>> }),
>> })
>> @@ -254,6 +256,7 @@ pub struct NetworkManual {
>> pub cidr: CidrAddress,
>> pub dns: IpAddr,
>> pub gateway: IpAddr,
>> + pub vlan: Option<u16>,
>> pub filter: BTreeMap<String, String>,
>> }
>>
>> diff --git a/proxmox-auto-installer/src/utils.rs b/proxmox-auto-installer/src/utils.rs
>> index 7d42f2c..2fdb6df 100644
>> --- a/proxmox-auto-installer/src/utils.rs
>> +++ b/proxmox-auto-installer/src/utils.rs
>> @@ -66,6 +66,7 @@ fn get_network_settings(
>> network_options.address = settings.cidr.clone();
>> network_options.dns_server = settings.dns;
>> network_options.gateway = settings.gateway;
>> + network_options.vlan = settings.vlan;
>> network_options.ifname = get_single_udev_index(&settings.filter, &udev_info.nics)?;
>> }
>> info!("Network interface used is '{}'", &network_options.ifname);
>> @@ -494,6 +495,7 @@ pub fn parse_answer(
>> domain: network_settings.fqdn.domain(),
>> cidr: network_settings.address,
>> gateway: network_settings.gateway,
>> + vlan: network_settings.vlan,
>> dns: network_settings.dns_server,
>>
>> first_boot: InstallFirstBootSetup::default(),
> [..]
>> diff --git a/proxmox-auto-installer/tests/resources/parse_answer/network_vlan.toml b/proxmox-auto-installer/tests/resources/parse_answer/network_vlan.toml
>> new file mode 100644
>> index 0000000..fad56c6
>> --- /dev/null
>> +++ b/proxmox-auto-installer/tests/resources/parse_answer/network_vlan.toml
>> @@ -0,0 +1,19 @@
>> +[global]
>> +keyboard = "de"
>> +country = "at"
>> +fqdn = "pveauto.testinstall"
>> +mailto = "mail@no.invalid"
>> +timezone = "Europe/Vienna"
>> +root-password = "12345678"
>> +
>> +[network]
>> +source = "from-answer"
>> +cidr = "10.10.10.10/24"
>> +dns = "10.10.10.1"
>> +vlan = 123
>> +gateway = "10.10.10.1"
>> +filter.ID_NET_NAME = "enp129s0f1np1"
>> +
>> +[disk-setup]
>> +filesystem = "ext4"
>> +disk-list = ["sda"]
> [..]
>> diff --git a/proxmox-auto-installer/tests/resources/parse_answer/nic_matching.toml b/proxmox-auto-installer/tests/resources/parse_answer/nic_matching.toml
>> index 901f894..723dfc8 100644
>> --- a/proxmox-auto-installer/tests/resources/parse_answer/nic_matching.toml
>> +++ b/proxmox-auto-installer/tests/resources/parse_answer/nic_matching.toml
>> @@ -10,6 +10,7 @@ root-password = "12345678"
>> source = "from-answer"
>> cidr = "10.10.10.10/24"
>> dns = "10.10.10.1"
>> +vlan = 123
>
> Any reason for adding it to this test too, as the `network_vlan` test
> above seems to be the exact same?
>
>> gateway = "10.10.10.1"
>> filter.ID_NET_NAME_MAC = "*a0369f0ab382"
>>
> [..]
>> diff --git a/proxmox-installer-common/src/setup.rs b/proxmox-installer-common/src/setup.rs
>> index 66cea72..23e43d2 100644
>> --- a/proxmox-installer-common/src/setup.rs
>> +++ b/proxmox-installer-common/src/setup.rs
>> @@ -580,6 +580,7 @@ pub struct InstallConfig {
>> #[serde(serialize_with = "serialize_as_display")]
>> pub cidr: CidrAddress,
>> pub gateway: IpAddr,
>> + pub vlan: Option<u16>,
>
> Should be annotated with
>
> #[serde(skip_serializing_if = "Option::is_none")]
>
> to avoid serializing it as `null` if unset.
>
>> pub dns: IpAddr,
>>
>> pub first_boot: InstallFirstBootSetup,
>> diff --git a/proxmox-tui-installer/src/main.rs b/proxmox-tui-installer/src/main.rs
>> index 15ee5d3..21ef16f 100644
>> --- a/proxmox-tui-installer/src/main.rs
>> +++ b/proxmox-tui-installer/src/main.rs
> [..]
>> @@ -552,6 +560,23 @@ fn network_dialog(siv: &mut Cursive) -> InstallerView {
>> .parse::<IpAddr>()
>> .map_err(|err| err.to_string())?;
>>
>> + let vlan_str = view
>> + .get_value::<EditView, _>(5)
>> + .ok_or("failed to retrieve VLAN")?;
>> +
>> + let vlan = if vlan_str.trim().is_empty() {
>> + None
>> + } else {
>> + let parsed_vlan = vlan_str.trim().parse::<u16>()
>> + .map_err(|e| format!("Invalid VLAN: {e}"))?;
>> +
>> + if parsed_vlan >= 4094 {
>> + return Err(format!("VLAN must be smaller than 4094."));
>> + }
>
> Same tag 0 check as for the GUI.
>
> [..]
>> diff --git a/proxmox-tui-installer/src/options.rs b/proxmox-tui-installer/src/options.rs
>> index c80877f..c59712e 100644
>> --- a/proxmox-tui-installer/src/options.rs
>> +++ b/proxmox-tui-installer/src/options.rs
>> @@ -72,6 +72,7 @@ impl InstallerOptions {
>> SummaryOption::new("Keyboard layout", kb_layout),
>> SummaryOption::new("Administrator email", &self.password.email),
>> SummaryOption::new("Management interface", &self.network.ifname),
>> + SummaryOption::new("Management interface vlan tag", &self.network.vlan.map(|v| v.to_string()).unwrap_or("None".to_string())),
>
> Uppercase spelling as in the GUI.
>
>
> _______________________________________________
> pve-devel mailing list
> pve-devel@lists.proxmox.com
> https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
>
>
_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [pve-devel] [PATCH installer 1/1] fix #2164: add option to define a vlan tag within the installer
2025-09-24 8:48 ` Aaron Lauterer
@ 2025-09-24 10:06 ` Florian Paul Azim Hoberg via pve-devel
0 siblings, 0 replies; 4+ messages in thread
From: Florian Paul Azim Hoberg via pve-devel @ 2025-09-24 10:06 UTC (permalink / raw)
To: Aaron Lauterer
Cc: Florian Paul Azim Hoberg, Proxmox VE development discussion
[-- Attachment #1: Type: message/rfc822, Size: 16973 bytes --]
From: Florian Paul Azim Hoberg <florian.hoberg@credativ.de>
To: Aaron Lauterer <a.lauterer@proxmox.com>
Cc: Proxmox VE development discussion <pve-devel@lists.proxmox.com>, Christoph Heiss <c.heiss@proxmox.com>
Subject: Re: [pve-devel] [PATCH installer 1/1] fix #2164: add option to define a vlan tag within the installer
Date: Wed, 24 Sep 2025 10:06:02 +0000
Message-ID: <6332E062-AB08-4F81-AA0B-B9D8D1C75B2E@credativ.de>
Hey Aaron, hey Christoph!
Thanks for your inputs. I already adjusted the code by Christoph’s suggestions which ensure that we have a proper validation of vlans (jftr, we start at vlan id 2 instead of 1 which is also special) and made the overview pages dynamically representing the given vlan tag id only when present. At this point, I just want to make sure this also fits your expectations to keep the review rounds short.
> Also; wondering if we maybe should just hide this if no VLAN tag is set,
> no not clutter the summary page unnecessarily?
Honestly, I have no better idea than this approach except of a complete refactor. So, I’m not sure if you’re fine with this approach within the GUI part where the HTML ack page would look like this:
<tr><td>Management Interface:</td> <td>__interface__</td></tr>
__vlan__
<tr><td>Hostname:</td> <td>__hostname__</td></tr>
And the content gets set by:
my $vlan_row = defined $vlan ? "<tr><td>Management Interface VLAN tag:</td><td>$vlan</td></tr>" : '';
Which then gets pushed and set if present:
if let Some(vlan) = self.network.vlan {
summary.push(SummaryOption::new(
"Management interface VLAN tag",
&vlan.to_string(),
));
}
> Instead of the dot notation, I would prefer the vlan-raw-device, vlan-id variant.
> This allows us to give the interface a name that matches the use, and the whole config is more explicit.
Would this fit to you?
my $ifaces = "auto lo\niface lo inet loopback\n\n";
my $ip_version = Proxmox::Install::Config::get_ip_version();
my $ntype = $ip_version == 4 ? 'inet' : 'inet6';
my $cidr = Proxmox::Install::Config::get_cidr();
my $vlan = Proxmox::Install::Config::get_vlan();
my $gateway = Proxmox::Install::Config::get_gateway();
my $ethdev = Proxmox::Install::Config::get_mngmt_nic();
my $bridgedev = "vmbr0";
my $mgmtdev = "management";
if ($iso_env->{cfg}->{bridged_network}) {
$ifaces .= "iface $ethdev $ntype manual\n";
$ifaces .=
"\nauto $bridgedev\n"
. "\tiface $bridgedev $ntype manual\n"
. "\tbridge-ports $ethdev\n"
. "\tbridge-stp off\n"
. "\tbridge-fd 0\n"
. "\n"
"\nauto $mgmtdev\niface $mgmtdev $ntype static\n"
. "\taddress $cidr\n"
. "\tgateway $gateway\n"
. "\tvlan-id $vlan\n"
. "\tvlan-raw-device $bridgedev\n";
} else {
$ifaces .=
"auto $ethdev\n"
. "iface $ethdev $ntype manual\n"
. "\n"
"auto $mgmtdev\n"
. "iface $mgmtdev $ntype static\n"
. "\taddress $cidr\n"
. "\tgateway $gateway\n"
. "\tvlan-id $vlan\n"
. "\tvlan-raw-device $ethdev\n";
}
Happy to hear your feedback.
Thanks!
[-- Attachment #2: Type: text/plain, Size: 160 bytes --]
_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
^ permalink raw reply [flat|nested] 4+ messages in thread
* [pve-devel] [PATCH installer 1/1] fix #2164: add option to define a vlan tag within the installer
@ 2025-09-22 12:30 Florian Paul Azim Hoberg via pve-devel
0 siblings, 0 replies; 4+ messages in thread
From: Florian Paul Azim Hoberg via pve-devel @ 2025-09-22 12:30 UTC (permalink / raw)
To: pve-devel; +Cc: Florian Paul Azim Hoberg
[-- Attachment #1: Type: message/rfc822, Size: 38405 bytes --]
From: Florian Paul Azim Hoberg <florian.hoberg@credativ.de>
To: "pve-devel@lists.proxmox.com" <pve-devel@lists.proxmox.com>
Subject: [PATCH installer 1/1] fix #2164: add option to define a vlan tag within the installer
Date: Mon, 22 Sep 2025 12:30:30 +0000
Message-ID: <3978889E-73FA-4473-A70B-2C660662CC3D@credativ.de>
To ensure a Promox node can access a desired network
resource which requires a given vlan tag, this feature
adds the possibility to optionally define a vlan tag
within the auto installer, tui and gui.
Signed-off-by: Florian Paul Azim Hoberg @gyptazy <florian.hoberg@credativ.de>
---
initial commit:
* Add possibility to optionally add vlan tag in:
- auto installer
- tui
- gui
* Tagged interface will be generated as:
$interface.$tag in /etc/network/interfaces
* Simple validation of given vlan tag:
- Must be digit
- Must be smaller than int(4094)
Proxmox/Install.pm | 19 +++++++++++---
Proxmox/Install/Config.pm | 4 +++
html/ack_template.htm | 2 ++
proxinstall | 23 +++++++++++++++-
proxmox-auto-installer/src/answer.rs | 3 +++
proxmox-auto-installer/src/utils.rs | 2 ++
proxmox-auto-installer/tests/parse-answer.rs | 1 +
.../tests/resources/parse_answer/btrfs.json | 1 +
.../btrfs_raid_level_uppercase.json | 1 +
.../resources/parse_answer/disk_match.json | 1 +
.../parse_answer/disk_match_all.json | 1 +
.../parse_answer/disk_match_any.json | 1 +
.../resources/parse_answer/first_boot.json | 1 +
.../parse_answer/fqdn_from_dhcp.json | 1 +
...n_from_dhcp_empty_dhcp_domain_setting.json | 1 +
...cp_no_dhcp_domain_with_default_domain.json | 1 +
...ll_fqdn_from_dhcp_with_default_domain.json | 1 +
.../parse_answer/hashed_root_password.json | 1 +
.../tests/resources/parse_answer/minimal.json | 1 +
.../resources/parse_answer/network_vlan.json | 20 ++++++++++++++
.../resources/parse_answer/network_vlan.toml | 19 ++++++++++++++
.../resources/parse_answer/nic_matching.json | 1 +
.../resources/parse_answer/nic_matching.toml | 1 +
.../resources/parse_answer/specific_nic.json | 1 +
.../tests/resources/parse_answer/zfs.json | 1 +
.../zfs_raid_level_uppercase.json | 1 +
proxmox-installer-common/src/options.rs | 10 +++++++
proxmox-installer-common/src/setup.rs | 1 +
proxmox-tui-installer/src/main.rs | 26 +++++++++++++++++++
proxmox-tui-installer/src/options.rs | 1 +
proxmox-tui-installer/src/setup.rs | 1 +
31 files changed, 145 insertions(+), 4 deletions(-)
create mode 100644 proxmox-auto-installer/tests/resources/parse_answer/network_vlan.json
create mode 100644 proxmox-auto-installer/tests/resources/parse_answer/network_vlan.toml
diff --git a/Proxmox/Install.pm b/Proxmox/Install.pm
index 9cb88bc..aa8e6c7 100644
--- a/Proxmox/Install.pm
+++ b/Proxmox/Install.pm
@@ -1099,13 +1099,26 @@ sub extract_data {
my $ethdev = Proxmox::Install::Config::get_mngmt_nic();
my $cidr = Proxmox::Install::Config::get_cidr();
+ my $vlan = Proxmox::Install::Config::get_vlan();
my $gateway = Proxmox::Install::Config::get_gateway();
+ # apply vlan tag to bridge if present
+ my $bridge = "vmbr0";
+ if (defined $vlan) {
+ $bridge .= ".$vlan";
+ }
+
+ # apply vlan tag directly to interface if present
+ my $ethdev_non_bridge = $ethdev;
+ if (defined $vlan && !$iso_env->{cfg}->{bridged_network}) {
+ $ethdev_non_bridge .= ".$vlan";
+ }
+
if ($iso_env->{cfg}->{bridged_network}) {
$ifaces .= "iface $ethdev $ntype manual\n";
$ifaces .=
- "\nauto vmbr0\niface vmbr0 $ntype static\n"
+ "\nauto $bridge\niface $bridge $ntype static\n"
. "\taddress $cidr\n"
. "\tgateway $gateway\n"
. "\tbridge-ports $ethdev\n"
@@ -1113,8 +1126,8 @@ sub extract_data {
. "\tbridge-fd 0\n";
} else {
$ifaces .=
- "auto $ethdev\n"
- . "iface $ethdev $ntype static\n"
+ "auto $ethdev_non_bridge\n"
+ . "iface $ethdev_non_bridge $ntype static\n"
. "\taddress $cidr\n"
. "\tgateway $gateway\n";
}
diff --git a/Proxmox/Install/Config.pm b/Proxmox/Install/Config.pm
index da476da..c8232a8 100644
--- a/Proxmox/Install/Config.pm
+++ b/Proxmox/Install/Config.pm
@@ -106,6 +106,7 @@ my sub init_cfg {
cidr => undef,
gateway => undef,
dns => undef,
+ vlan => undef,
target_cmdline => undef,
# proxmox-first-boot setup
@@ -279,6 +280,9 @@ sub get_gateway { return get('gateway'); }
sub set_dns { set_key('dns', $_[0]); }
sub get_dns { return get('dns'); }
+sub set_vlan { set_key('vlan', $_[0]); }
+sub get_vlan { return get('vlan'); }
+
sub set_target_cmdline { set_key('target_cmdline', $_[0]); }
sub get_target_cmdline { return get('target_cmdline'); }
diff --git a/html/ack_template.htm b/html/ack_template.htm
index 48d7213..4404321 100644
--- a/html/ack_template.htm
+++ b/html/ack_template.htm
@@ -54,6 +54,8 @@
<tr><td>Management Interface:</td> <td>__interface__</td></tr>
+ <tr><td>Management Interface vlan tag:</td> <td>__vlan__</td></tr>
+
<tr><td>Hostname:</td> <td>__hostname__</td></tr>
<tr><td>IP CIDR:</td> <td>__cidr__</td></tr>
diff --git a/proxinstall b/proxinstall
index 5ba65fa..13ece1d 100755
--- a/proxinstall
+++ b/proxinstall
@@ -472,6 +472,14 @@ sub create_ipconf_view {
$grid->attach($dns_label, 0, 4, 1, 1);
$grid->attach($ipconf_entry_dns, 1, 4, 1, 1);
+ my $cfg_vlan = Proxmox::Install::Config::get_vlan();
+ my $vlan = defined($cfg_vlan) ? $cfg_vlan : '';
+
+ my ($vlan_label, $ipconf_entry_vlan) = create_text_input($vlan, 'VLAN Tag (Optional)');
+
+ $grid->attach($vlan_label, 0, 5, 1, 1);
+ $grid->attach($ipconf_entry_vlan, 1, 5, 1, 1);
+
$gtk_state->{inbox}->show_all;
set_next(
undef,
@@ -538,7 +546,19 @@ sub create_ipconf_view {
}
Proxmox::Install::Config::set_dns($dns_ip);
- #print STDERR "TEST $ipaddress/$netmask $gateway_ip $dns_ip\n";
+ my $vlan = $ipconf_entry_vlan->get_text();
+ if ($vlan !~ /^\d*$/) {
+ Proxmox::UI::message("VLAN must contain only digits.");
+ $ipconf_entry_vlan->grab_focus();
+ return;
+ }
+ if ($vlan ne '' && $vlan >= 4094) {
+ Proxmox::UI::message("VLAN must be smaller than 4094.");
+ $ipconf_entry_vlan->grab_focus();
+ return;
+ }
+ $vlan = undef if $vlan eq '';
+ Proxmox::Install::Config::set_vlan($vlan);
$step_number++;
create_ack_view();
@@ -585,6 +605,7 @@ sub create_ack_view {
__cidr__ => Proxmox::Install::Config::get_cidr(),
__gateway__ => Proxmox::Install::Config::get_gateway(),
__dnsserver__ => Proxmox::Install::Config::get_dns(),
+ __vlan__ => Proxmox::Install::Config::get_vlan(),
);
while (my ($k, $v) = each %config_values) {
diff --git a/proxmox-auto-installer/src/answer.rs b/proxmox-auto-installer/src/answer.rs
index 88f4c87..cea5cb1 100644
--- a/proxmox-auto-installer/src/answer.rs
+++ b/proxmox-auto-installer/src/answer.rs
@@ -186,6 +186,7 @@ struct NetworkInAnswer {
pub cidr: Option<CidrAddress>,
pub dns: Option<IpAddr>,
pub gateway: Option<IpAddr>,
+ pub vlan: Option<u16>,
#[serde(default)]
pub filter: BTreeMap<String, String>,
}
@@ -219,6 +220,7 @@ impl TryFrom<NetworkInAnswer> for Network {
cidr: network.cidr.unwrap(),
dns: network.dns.unwrap(),
gateway: network.gateway.unwrap(),
+ vlan: network.vlan,
filter: network.filter,
}),
})
@@ -254,6 +256,7 @@ pub struct NetworkManual {
pub cidr: CidrAddress,
pub dns: IpAddr,
pub gateway: IpAddr,
+ pub vlan: Option<u16>,
pub filter: BTreeMap<String, String>,
}
diff --git a/proxmox-auto-installer/src/utils.rs b/proxmox-auto-installer/src/utils.rs
index 7d42f2c..2fdb6df 100644
--- a/proxmox-auto-installer/src/utils.rs
+++ b/proxmox-auto-installer/src/utils.rs
@@ -66,6 +66,7 @@ fn get_network_settings(
network_options.address = settings.cidr.clone();
network_options.dns_server = settings.dns;
network_options.gateway = settings.gateway;
+ network_options.vlan = settings.vlan;
network_options.ifname = get_single_udev_index(&settings.filter, &udev_info.nics)?;
}
info!("Network interface used is '{}'", &network_options.ifname);
@@ -494,6 +495,7 @@ pub fn parse_answer(
domain: network_settings.fqdn.domain(),
cidr: network_settings.address,
gateway: network_settings.gateway,
+ vlan: network_settings.vlan,
dns: network_settings.dns_server,
first_boot: InstallFirstBootSetup::default(),
diff --git a/proxmox-auto-installer/tests/parse-answer.rs b/proxmox-auto-installer/tests/parse-answer.rs
index 6754374..e7836d3 100644
--- a/proxmox-auto-installer/tests/parse-answer.rs
+++ b/proxmox-auto-installer/tests/parse-answer.rs
@@ -129,6 +129,7 @@ mod tests {
full_fqdn_from_dhcp_with_default_domain,
hashed_root_password,
minimal,
+ network_vlan,
nic_matching,
specific_nic,
zfs,
diff --git a/proxmox-auto-installer/tests/resources/parse_answer/btrfs.json b/proxmox-auto-installer/tests/resources/parse_answer/btrfs.json
index 0c1f032..f4b4b23 100644
--- a/proxmox-auto-installer/tests/resources/parse_answer/btrfs.json
+++ b/proxmox-auto-installer/tests/resources/parse_answer/btrfs.json
@@ -18,6 +18,7 @@
"mngmt_nic": "eno1",
"root_password": { "plain": "12345678" },
"timezone": "Europe/Vienna",
+ "vlan": null,
"btrfs_opts": {
"compress": "zlib"
},
diff --git a/proxmox-auto-installer/tests/resources/parse_answer/btrfs_raid_level_uppercase.json b/proxmox-auto-installer/tests/resources/parse_answer/btrfs_raid_level_uppercase.json
index cb6711c..88fb75c 100644
--- a/proxmox-auto-installer/tests/resources/parse_answer/btrfs_raid_level_uppercase.json
+++ b/proxmox-auto-installer/tests/resources/parse_answer/btrfs_raid_level_uppercase.json
@@ -18,6 +18,7 @@
"mngmt_nic": "eno1",
"root_password": { "plain": "12345678" },
"timezone": "Europe/Vienna",
+ "vlan": null,
"btrfs_opts": { "compress": "off" },
"first_boot": { "enabled": 0 }
}
diff --git a/proxmox-auto-installer/tests/resources/parse_answer/disk_match.json b/proxmox-auto-installer/tests/resources/parse_answer/disk_match.json
index d5ffddd..331a210 100644
--- a/proxmox-auto-installer/tests/resources/parse_answer/disk_match.json
+++ b/proxmox-auto-installer/tests/resources/parse_answer/disk_match.json
@@ -20,6 +20,7 @@
"mngmt_nic": "eno1",
"root_password": { "plain": "12345678" },
"timezone": "Europe/Vienna",
+ "vlan": null,
"zfs_opts": {
"arc_max": 2048,
"ashift": 12,
diff --git a/proxmox-auto-installer/tests/resources/parse_answer/disk_match_all.json b/proxmox-auto-installer/tests/resources/parse_answer/disk_match_all.json
index 78a5e0c..23ca3b6 100644
--- a/proxmox-auto-installer/tests/resources/parse_answer/disk_match_all.json
+++ b/proxmox-auto-installer/tests/resources/parse_answer/disk_match_all.json
@@ -17,6 +17,7 @@
"mngmt_nic": "eno1",
"root_password": { "plain": "12345678" },
"timezone": "Europe/Vienna",
+ "vlan": null,
"zfs_opts": {
"arc_max": 2048,
"ashift": 12,
diff --git a/proxmox-auto-installer/tests/resources/parse_answer/disk_match_any.json b/proxmox-auto-installer/tests/resources/parse_answer/disk_match_any.json
index 2e65fce..631cd66 100644
--- a/proxmox-auto-installer/tests/resources/parse_answer/disk_match_any.json
+++ b/proxmox-auto-installer/tests/resources/parse_answer/disk_match_any.json
@@ -24,6 +24,7 @@
"mngmt_nic": "eno1",
"root_password": { "plain": "12345678" },
"timezone": "Europe/Vienna",
+ "vlan": null,
"zfs_opts": {
"arc_max": 2048,
"ashift": 12,
diff --git a/proxmox-auto-installer/tests/resources/parse_answer/first_boot.json b/proxmox-auto-installer/tests/resources/parse_answer/first_boot.json
index fafde51..eff4227 100644
--- a/proxmox-auto-installer/tests/resources/parse_answer/first_boot.json
+++ b/proxmox-auto-installer/tests/resources/parse_answer/first_boot.json
@@ -15,5 +15,6 @@
"root_password": { "plain": "12345678" },
"target_hd": "/dev/sda",
"timezone": "Europe/Vienna",
+ "vlan": null,
"first_boot": { "enabled": 1, "ordering_target": "network-pre" }
}
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
index 5ec6656..860d5b2 100644
--- a/proxmox-auto-installer/tests/resources/parse_answer/fqdn_from_dhcp.json
+++ b/proxmox-auto-installer/tests/resources/parse_answer/fqdn_from_dhcp.json
@@ -15,5 +15,6 @@
"root_password": { "plain": "12345678" },
"target_hd": "/dev/sda",
"timezone": "Europe/Vienna",
+ "vlan": null,
"first_boot": { "enabled": 0 }
}
diff --git a/proxmox-auto-installer/tests/resources/parse_answer/fqdn_from_dhcp_empty_dhcp_domain_setting.json b/proxmox-auto-installer/tests/resources/parse_answer/fqdn_from_dhcp_empty_dhcp_domain_setting.json
index 5ec6656..860d5b2 100644
--- a/proxmox-auto-installer/tests/resources/parse_answer/fqdn_from_dhcp_empty_dhcp_domain_setting.json
+++ b/proxmox-auto-installer/tests/resources/parse_answer/fqdn_from_dhcp_empty_dhcp_domain_setting.json
@@ -15,5 +15,6 @@
"root_password": { "plain": "12345678" },
"target_hd": "/dev/sda",
"timezone": "Europe/Vienna",
+ "vlan": null,
"first_boot": { "enabled": 0 }
}
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
index 7ed46a2..aeaf145 100644
--- 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
@@ -15,5 +15,6 @@
"root_password": { "plain": "12345678" },
"target_hd": "/dev/sda",
"timezone": "Europe/Vienna",
+ "vlan": null,
"first_boot": { "enabled": 0 }
}
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
index 7ed46a2..aeaf145 100644
--- 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
@@ -15,5 +15,6 @@
"root_password": { "plain": "12345678" },
"target_hd": "/dev/sda",
"timezone": "Europe/Vienna",
+ "vlan": null,
"first_boot": { "enabled": 0 }
}
diff --git a/proxmox-auto-installer/tests/resources/parse_answer/hashed_root_password.json b/proxmox-auto-installer/tests/resources/parse_answer/hashed_root_password.json
index 4e049bd..a33aca5 100644
--- a/proxmox-auto-installer/tests/resources/parse_answer/hashed_root_password.json
+++ b/proxmox-auto-installer/tests/resources/parse_answer/hashed_root_password.json
@@ -17,5 +17,6 @@
},
"target_hd": "/dev/sda",
"timezone": "Europe/Vienna",
+ "vlan": null,
"first_boot": { "enabled": 0 }
}
diff --git a/proxmox-auto-installer/tests/resources/parse_answer/minimal.json b/proxmox-auto-installer/tests/resources/parse_answer/minimal.json
index 0339dbc..3d79f68 100644
--- a/proxmox-auto-installer/tests/resources/parse_answer/minimal.json
+++ b/proxmox-auto-installer/tests/resources/parse_answer/minimal.json
@@ -15,5 +15,6 @@
"root_password": { "plain": "12345678" },
"target_hd": "/dev/sda",
"timezone": "Europe/Vienna",
+ "vlan": null,
"first_boot": { "enabled": 0 }
}
diff --git a/proxmox-auto-installer/tests/resources/parse_answer/network_vlan.json b/proxmox-auto-installer/tests/resources/parse_answer/network_vlan.json
new file mode 100644
index 0000000..4b93e6d
--- /dev/null
+++ b/proxmox-auto-installer/tests/resources/parse_answer/network_vlan.json
@@ -0,0 +1,20 @@
+{
+ "autoreboot": 1,
+ "cidr": "10.10.10.10/24",
+ "country": "at",
+ "dns": "10.10.10.1",
+ "domain": "testinstall",
+ "filesys": "ext4",
+ "gateway": "10.10.10.1",
+ "hdsize": 223.57088470458984,
+ "existing_storage_auto_rename": 1,
+ "hostname": "pveauto",
+ "keymap": "de",
+ "mailto": "mail@no.invalid",
+ "mngmt_nic": "enp129s0f1np1",
+ "root_password": { "plain": "12345678" },
+ "target_hd": "/dev/sda",
+ "timezone": "Europe/Vienna",
+ "vlan": 123,
+ "first_boot": { "enabled": 0 }
+}
diff --git a/proxmox-auto-installer/tests/resources/parse_answer/network_vlan.toml b/proxmox-auto-installer/tests/resources/parse_answer/network_vlan.toml
new file mode 100644
index 0000000..fad56c6
--- /dev/null
+++ b/proxmox-auto-installer/tests/resources/parse_answer/network_vlan.toml
@@ -0,0 +1,19 @@
+[global]
+keyboard = "de"
+country = "at"
+fqdn = "pveauto.testinstall"
+mailto = "mail@no.invalid"
+timezone = "Europe/Vienna"
+root-password = "12345678"
+
+[network]
+source = "from-answer"
+cidr = "10.10.10.10/24"
+dns = "10.10.10.1"
+vlan = 123
+gateway = "10.10.10.1"
+filter.ID_NET_NAME = "enp129s0f1np1"
+
+[disk-setup]
+filesystem = "ext4"
+disk-list = ["sda"]
diff --git a/proxmox-auto-installer/tests/resources/parse_answer/nic_matching.json b/proxmox-auto-installer/tests/resources/parse_answer/nic_matching.json
index 5d707c4..58969af 100644
--- a/proxmox-auto-installer/tests/resources/parse_answer/nic_matching.json
+++ b/proxmox-auto-installer/tests/resources/parse_answer/nic_matching.json
@@ -15,5 +15,6 @@
"root_password": { "plain": "12345678" },
"target_hd": "/dev/sda",
"timezone": "Europe/Vienna",
+ "vlan": 123,
"first_boot": { "enabled": 0 }
}
diff --git a/proxmox-auto-installer/tests/resources/parse_answer/nic_matching.toml b/proxmox-auto-installer/tests/resources/parse_answer/nic_matching.toml
index 901f894..723dfc8 100644
--- a/proxmox-auto-installer/tests/resources/parse_answer/nic_matching.toml
+++ b/proxmox-auto-installer/tests/resources/parse_answer/nic_matching.toml
@@ -10,6 +10,7 @@ root-password = "12345678"
source = "from-answer"
cidr = "10.10.10.10/24"
dns = "10.10.10.1"
+vlan = 123
gateway = "10.10.10.1"
filter.ID_NET_NAME_MAC = "*a0369f0ab382"
diff --git a/proxmox-auto-installer/tests/resources/parse_answer/specific_nic.json b/proxmox-auto-installer/tests/resources/parse_answer/specific_nic.json
index 49240b4..3e4fdd4 100644
--- a/proxmox-auto-installer/tests/resources/parse_answer/specific_nic.json
+++ b/proxmox-auto-installer/tests/resources/parse_answer/specific_nic.json
@@ -15,5 +15,6 @@
"root_password": { "plain": "12345678" },
"target_hd": "/dev/sda",
"timezone": "Europe/Vienna",
+ "vlan": null,
"first_boot": { "enabled": 0 }
}
diff --git a/proxmox-auto-installer/tests/resources/parse_answer/zfs.json b/proxmox-auto-installer/tests/resources/parse_answer/zfs.json
index 622f6d6..0b9b912 100644
--- a/proxmox-auto-installer/tests/resources/parse_answer/zfs.json
+++ b/proxmox-auto-installer/tests/resources/parse_answer/zfs.json
@@ -18,6 +18,7 @@
"mngmt_nic": "eno1",
"root_password": { "plain": "12345678" },
"timezone": "Europe/Vienna",
+ "vlan": null,
"zfs_opts": {
"arc_max": 2048,
"ashift": 12,
diff --git a/proxmox-auto-installer/tests/resources/parse_answer/zfs_raid_level_uppercase.json b/proxmox-auto-installer/tests/resources/parse_answer/zfs_raid_level_uppercase.json
index 46b8344..033168e 100644
--- a/proxmox-auto-installer/tests/resources/parse_answer/zfs_raid_level_uppercase.json
+++ b/proxmox-auto-installer/tests/resources/parse_answer/zfs_raid_level_uppercase.json
@@ -19,6 +19,7 @@
"mngmt_nic": "eno1",
"root_password": { "plain": "12345678" },
"timezone": "Europe/Vienna",
+ "vlan": null,
"zfs_opts": {
"arc_max": 2048,
"ashift": 12,
diff --git a/proxmox-installer-common/src/options.rs b/proxmox-installer-common/src/options.rs
index 48c77c9..1f849cb 100644
--- a/proxmox-installer-common/src/options.rs
+++ b/proxmox-installer-common/src/options.rs
@@ -483,6 +483,7 @@ pub struct NetworkOptions {
pub address: CidrAddress,
pub gateway: IpAddr,
pub dns_server: IpAddr,
+ pub vlan: Option<u16>,
}
impl NetworkOptions {
@@ -507,6 +508,7 @@ impl NetworkOptions {
address: CidrAddress::new(Ipv4Addr::new(192, 168, 100, 2), 24).unwrap(),
gateway: Ipv4Addr::new(192, 168, 100, 1).into(),
dns_server: Ipv4Addr::new(192, 168, 100, 1).into(),
+ vlan: None,
};
if let Some(ip) = network.dns.dns.first() {
@@ -715,6 +717,7 @@ mod tests {
address: CidrAddress::new(Ipv4Addr::new(192, 168, 0, 2), 24).unwrap(),
gateway: IpAddr::V4(Ipv4Addr::new(192, 168, 0, 1)),
dns_server: Ipv4Addr::new(192, 168, 100, 1).into(),
+ vlan: None,
}
);
@@ -727,6 +730,7 @@ mod tests {
address: CidrAddress::new(Ipv4Addr::new(192, 168, 0, 2), 24).unwrap(),
gateway: IpAddr::V4(Ipv4Addr::new(192, 168, 0, 1)),
dns_server: Ipv4Addr::new(192, 168, 100, 1).into(),
+ vlan: None,
}
);
@@ -739,6 +743,7 @@ mod tests {
address: CidrAddress::new(Ipv4Addr::new(192, 168, 0, 2), 24).unwrap(),
gateway: IpAddr::V4(Ipv4Addr::new(192, 168, 0, 1)),
dns_server: Ipv4Addr::new(192, 168, 100, 1).into(),
+ vlan: None,
}
);
@@ -751,6 +756,7 @@ mod tests {
address: CidrAddress::new(Ipv4Addr::new(192, 168, 0, 2), 24).unwrap(),
gateway: IpAddr::V4(Ipv4Addr::new(192, 168, 0, 1)),
dns_server: Ipv4Addr::new(192, 168, 100, 1).into(),
+ vlan: None,
}
);
}
@@ -767,6 +773,7 @@ mod tests {
address: CidrAddress::new(Ipv4Addr::new(192, 168, 0, 2), 24).unwrap(),
gateway: IpAddr::V4(Ipv4Addr::new(192, 168, 0, 1)),
dns_server: Ipv4Addr::new(192, 168, 100, 1).into(),
+ vlan: None,
}
);
@@ -779,6 +786,7 @@ mod tests {
address: CidrAddress::new(Ipv4Addr::new(192, 168, 0, 2), 24).unwrap(),
gateway: IpAddr::V4(Ipv4Addr::new(192, 168, 0, 1)),
dns_server: Ipv4Addr::new(192, 168, 100, 1).into(),
+ vlan: None,
}
);
@@ -791,6 +799,7 @@ mod tests {
address: CidrAddress::new(Ipv4Addr::new(192, 168, 0, 2), 24).unwrap(),
gateway: IpAddr::V4(Ipv4Addr::new(192, 168, 0, 1)),
dns_server: Ipv4Addr::new(192, 168, 100, 1).into(),
+ vlan: None,
}
);
}
@@ -829,6 +838,7 @@ mod tests {
address: CidrAddress::new(Ipv4Addr::new(192, 168, 100, 2), 24).unwrap(),
gateway: IpAddr::V4(Ipv4Addr::new(192, 168, 100, 1)),
dns_server: Ipv4Addr::new(192, 168, 100, 1).into(),
+ vlan: None,
}
);
}
diff --git a/proxmox-installer-common/src/setup.rs b/proxmox-installer-common/src/setup.rs
index 66cea72..23e43d2 100644
--- a/proxmox-installer-common/src/setup.rs
+++ b/proxmox-installer-common/src/setup.rs
@@ -580,6 +580,7 @@ pub struct InstallConfig {
#[serde(serialize_with = "serialize_as_display")]
pub cidr: CidrAddress,
pub gateway: IpAddr,
+ pub vlan: Option<u16>,
pub dns: IpAddr,
pub first_boot: InstallFirstBootSetup,
diff --git a/proxmox-tui-installer/src/main.rs b/proxmox-tui-installer/src/main.rs
index 15ee5d3..21ef16f 100644
--- a/proxmox-tui-installer/src/main.rs
+++ b/proxmox-tui-installer/src/main.rs
@@ -516,6 +516,14 @@ fn network_dialog(siv: &mut Cursive) -> InstallerView {
"DNS server address",
EditView::new().content(options.dns_server.to_string()),
)
+ .child(
+ "VLAN Tag (optional)",
+ EditView::new().content(
+ options.vlan
+ .map(|v| v.to_string())
+ .unwrap_or_default(),
+ ),
+ )
.with_name("network-options");
InstallerView::new(
@@ -552,6 +560,23 @@ fn network_dialog(siv: &mut Cursive) -> InstallerView {
.parse::<IpAddr>()
.map_err(|err| err.to_string())?;
+ let vlan_str = view
+ .get_value::<EditView, _>(5)
+ .ok_or("failed to retrieve VLAN")?;
+
+ let vlan = if vlan_str.trim().is_empty() {
+ None
+ } else {
+ let parsed_vlan = vlan_str.trim().parse::<u16>()
+ .map_err(|e| format!("Invalid VLAN: {e}"))?;
+
+ if parsed_vlan >= 4094 {
+ return Err(format!("VLAN must be smaller than 4094."));
+ }
+
+ Some(parsed_vlan)
+ };
+
if address.addr().is_ipv4() != gateway.is_ipv4() {
Err("host and gateway IP address version must not differ".to_owned())
} else if address.addr().is_ipv4() != dns_server.is_ipv4() {
@@ -565,6 +590,7 @@ fn network_dialog(siv: &mut Cursive) -> InstallerView {
address,
gateway,
dns_server,
+ vlan,
})
}
});
diff --git a/proxmox-tui-installer/src/options.rs b/proxmox-tui-installer/src/options.rs
index c80877f..c59712e 100644
--- a/proxmox-tui-installer/src/options.rs
+++ b/proxmox-tui-installer/src/options.rs
@@ -72,6 +72,7 @@ impl InstallerOptions {
SummaryOption::new("Keyboard layout", kb_layout),
SummaryOption::new("Administrator email", &self.password.email),
SummaryOption::new("Management interface", &self.network.ifname),
+ SummaryOption::new("Management interface vlan tag", &self.network.vlan.map(|v| v.to_string()).unwrap_or("None".to_string())),
SummaryOption::new("Hostname", self.network.fqdn.to_string()),
SummaryOption::new("Host IP (CIDR)", self.network.address.to_string()),
SummaryOption::new("Gateway", self.network.gateway.to_string()),
diff --git a/proxmox-tui-installer/src/setup.rs b/proxmox-tui-installer/src/setup.rs
index b90c7dc..5114106 100644
--- a/proxmox-tui-installer/src/setup.rs
+++ b/proxmox-tui-installer/src/setup.rs
@@ -41,6 +41,7 @@ impl From<InstallerOptions> for InstallConfig {
cidr: options.network.address,
gateway: options.network.gateway,
dns: options.network.dns_server,
+ vlan: options.network.vlan,
first_boot: InstallFirstBootSetup::default(),
};
--
2.47.3
[-- Attachment #2: Type: text/plain, Size: 160 bytes --]
_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2025-09-24 14:58 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
[not found] <3978889E-73FA-4473-A70B-2C660662CC3D@credativ.de>
2025-09-23 12:07 ` [pve-devel] [PATCH installer 1/1] fix #2164: add option to define a vlan tag within the installer Christoph Heiss
2025-09-24 8:48 ` Aaron Lauterer
2025-09-24 10:06 ` Florian Paul Azim Hoberg via pve-devel
2025-09-22 12:30 Florian Paul Azim Hoberg via pve-devel
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox