public inbox for pve-devel@lists.proxmox.com
 help / color / mirror / Atom feed
* [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; only message 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] only message in thread

only message in thread, other threads:[~2025-09-22 17:47 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-09-22 12:30 [pve-devel] [PATCH installer 1/1] fix #2164: add option to define a vlan tag within the installer 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
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal