* [pbs-devel] [PATCH widget-toolkit/proxmox-backup v3 0/9] Fix #3115: VLAN Network Interface Configuration
@ 2024-04-04 10:00 Stefan Lendl
2024-04-04 10:00 ` [pbs-devel] [PATCH widget-toolkit v3 1/9] form: include vlan field widget from PVE Stefan Lendl
` (10 more replies)
0 siblings, 11 replies; 13+ messages in thread
From: Stefan Lendl @ 2024-04-04 10:00 UTC (permalink / raw)
To: pbs-devel
This patch series allows configuring a VLAN network interfaces in the PBS GUI
* Added reading and writing of VLAN network config.
* Created and updating of VLAN network interfaces via the API.
* Copied the VLAN field widget from PVE and enabled the Linux VLAN interface
type in the GUI.
* Unit tests for reading and writing the network config.
* Some cleanup to leave touched functions cleaner than before.
Changes v2 -> v3:
* slightly updated commit messages and changed typo in git trailer
Changes v1 -> v2:
* Adapted parameter handling to not expect all properties to be set
* Incorporated style suggestions
widget-toolkit:
Stefan Lendl (1):
form: include vlan field widget from PVE
src/Makefile | 1 +
src/form/VlanField.js | 40 ++++++++++++++++++++++++++++++++++++++++
src/node/NetworkEdit.js | 6 +++---
3 files changed, 44 insertions(+), 3 deletions(-)
create mode 100644 src/form/VlanField.js
proxmox-backup:
Stefan Lendl (8):
tests: move network tests to parser.rs
tests: simple tests for writing the network config
config: write vlan network interface
config: parse vlan interface from config
config: remove unnecessary pub in various methods in NetworkConfig
fmt: fix intendation in api macro
api: create and update vlan interfaces
ui: enable vlan widget
pbs-api-types/src/network.rs | 17 ++
pbs-config/src/network/lexer.rs | 6 +
pbs-config/src/network/mod.rs | 300 +++++++++++++++++--------------
pbs-config/src/network/parser.rs | 249 ++++++++++++++++++++++++-
src/api2/node/network.rs | 72 +++++++-
www/SystemConfiguration.js | 2 +-
6 files changed, 504 insertions(+), 142 deletions(-)
Summary over all repositories:
9 files changed, 548 insertions(+), 0 deletions(-)
--
Generated by git-murpp 0.5.0
^ permalink raw reply [flat|nested] 13+ messages in thread
* [pbs-devel] [PATCH widget-toolkit v3 1/9] form: include vlan field widget from PVE
2024-04-04 10:00 [pbs-devel] [PATCH widget-toolkit/proxmox-backup v3 0/9] Fix #3115: VLAN Network Interface Configuration Stefan Lendl
@ 2024-04-04 10:00 ` Stefan Lendl
2024-04-04 10:00 ` [pbs-devel] [PATCH proxmox-backup v3 2/9] tests: move network tests to parser.rs Stefan Lendl
` (9 subsequent siblings)
10 siblings, 0 replies; 13+ messages in thread
From: Stefan Lendl @ 2024-04-04 10:00 UTC (permalink / raw)
To: pbs-devel
Copied from PVE to use in PBS network configuration.
Signed-off-by: Stefan Lendl <s.lendl@proxmox.com>
Tested-by: Lukas Wagner <l.wagner@proxmox.com>
Reviewed-by: Lukas Wagner <l.wagner@proxmox.com>
---
src/Makefile | 1 +
src/form/VlanField.js | 40 ++++++++++++++++++++++++++++++++++++++++
src/node/NetworkEdit.js | 6 +++---
3 files changed, 44 insertions(+), 3 deletions(-)
create mode 100644 src/form/VlanField.js
diff --git a/src/Makefile b/src/Makefile
index 89f9962..0b1e88c 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -31,6 +31,7 @@ JSSRC= \
form/ExpireDate.js \
form/IntegerField.js \
form/TextField.js \
+ form/VlanField.js \
form/DateTimeField.js \
form/Checkbox.js \
form/KVComboBox.js \
diff --git a/src/form/VlanField.js b/src/form/VlanField.js
new file mode 100644
index 0000000..71b580d
--- /dev/null
+++ b/src/form/VlanField.js
@@ -0,0 +1,40 @@
+Ext.define('Proxmox.form.field.VlanField', {
+ extend: 'Ext.form.field.Number',
+ alias: ['widget.proxmoxvlanfield'],
+
+ deleteEmpty: false,
+
+ emptyText: gettext('no VLAN'),
+
+ fieldLabel: gettext('VLAN Tag'),
+
+ allowBlank: true,
+
+ getSubmitData: function() {
+ var me = this,
+ data = null,
+ val;
+ if (!me.disabled && me.submitValue) {
+ val = me.getSubmitValue();
+ if (val) {
+ data = {};
+ data[me.getName()] = val;
+ } else if (me.deleteEmpty) {
+ data = {};
+ data.delete = me.getName();
+ }
+ }
+ return data;
+ },
+
+ initComponent: function() {
+ var me = this;
+
+ Ext.apply(me, {
+ minValue: 1,
+ maxValue: 4094,
+ });
+
+ me.callParent();
+ },
+});
diff --git a/src/node/NetworkEdit.js b/src/node/NetworkEdit.js
index bb9add3..b81a21d 100644
--- a/src/node/NetworkEdit.js
+++ b/src/node/NetworkEdit.js
@@ -97,7 +97,7 @@ Ext.define('Proxmox.node.NetworkEdit', {
name: 'ovs_bridge',
});
column2.push({
- xtype: 'pveVlanField',
+ xtype: 'proxmoxvlanfield',
deleteEmpty: !me.isCreate,
name: 'ovs_tag',
value: '',
@@ -140,7 +140,7 @@ Ext.define('Proxmox.node.NetworkEdit', {
});
column2.push({
- xtype: 'pveVlanField',
+ xtype: 'proxmoxvlanfield',
name: 'vlan-id',
value: me.vlanidvalue,
disabled: me.disablevlanid,
@@ -211,7 +211,7 @@ Ext.define('Proxmox.node.NetworkEdit', {
name: 'ovs_bridge',
});
column2.push({
- xtype: 'pveVlanField',
+ xtype: 'proxmoxvlanfield',
deleteEmpty: !me.isCreate,
name: 'ovs_tag',
value: '',
--
2.44.0
^ permalink raw reply [flat|nested] 13+ messages in thread
* [pbs-devel] [PATCH proxmox-backup v3 2/9] tests: move network tests to parser.rs
2024-04-04 10:00 [pbs-devel] [PATCH widget-toolkit/proxmox-backup v3 0/9] Fix #3115: VLAN Network Interface Configuration Stefan Lendl
2024-04-04 10:00 ` [pbs-devel] [PATCH widget-toolkit v3 1/9] form: include vlan field widget from PVE Stefan Lendl
@ 2024-04-04 10:00 ` Stefan Lendl
2024-04-04 10:00 ` [pbs-devel] [PATCH proxmox-backup v3 3/9] tests: simple tests for writing the network config Stefan Lendl
` (8 subsequent siblings)
10 siblings, 0 replies; 13+ messages in thread
From: Stefan Lendl @ 2024-04-04 10:00 UTC (permalink / raw)
To: pbs-devel
All current tests in network/mod.rs only test parser functionality and
should therefore live in the parser module.
Signed-off-by: Stefan Lendl <s.lendl@proxmox.com>
Tested-by: Lukas Wagner <l.wagner@proxmox.com>
Reviewed-by: Lukas Wagner <l.wagner@proxmox.com>
---
pbs-config/src/network/mod.rs | 147 -------------------------------
pbs-config/src/network/parser.rs | 147 +++++++++++++++++++++++++++++++
2 files changed, 147 insertions(+), 147 deletions(-)
diff --git a/pbs-config/src/network/mod.rs b/pbs-config/src/network/mod.rs
index e2008b7c..21187ec2 100644
--- a/pbs-config/src/network/mod.rs
+++ b/pbs-config/src/network/mod.rs
@@ -503,150 +503,3 @@ pub fn complete_port_list(arg: &str, _param: &HashMap<String, String>) -> Vec<St
.map(|port| format!("{}{}", prefix, port))
.collect()
}
-
-#[cfg(test)]
-mod test {
-
- use anyhow::Error;
-
- use super::*;
-
- #[test]
- fn test_network_config_create_lo_1() -> Result<(), Error> {
- let input = "";
-
- let mut parser = NetworkParser::new(input.as_bytes());
-
- let config = parser.parse_interfaces(None)?;
-
- let output = String::try_from(config)?;
-
- let expected = "auto lo\niface lo inet loopback\n\n";
- assert_eq!(output, expected);
-
- // run again using output as input
- let mut parser = NetworkParser::new(output.as_bytes());
-
- let config = parser.parse_interfaces(None)?;
-
- let output = String::try_from(config)?;
-
- assert_eq!(output, expected);
-
- Ok(())
- }
-
- #[test]
- fn test_network_config_create_lo_2() -> Result<(), Error> {
- let input = "#c1\n\n#c2\n\niface test inet manual\n";
-
- let mut parser = NetworkParser::new(input.as_bytes());
-
- let config = parser.parse_interfaces(None)?;
-
- let output = String::try_from(config)?;
-
- // Note: loopback should be added in front of other interfaces
- let expected = "#c1\n#c2\n\nauto lo\niface lo inet loopback\n\niface test inet manual\n\n";
- assert_eq!(output, expected);
-
- Ok(())
- }
-
- #[test]
- fn test_network_config_parser_no_blank_1() -> Result<(), Error> {
- let input = "auto lo\n\
- iface lo inet loopback\n\
- iface lo inet6 loopback\n\
- auto ens18\n\
- iface ens18 inet static\n\
- \taddress 192.168.20.144/20\n\
- \tgateway 192.168.16.1\n\
- # comment\n\
- iface ens20 inet static\n\
- \taddress 192.168.20.145/20\n\
- iface ens21 inet manual\n\
- iface ens22 inet manual\n";
-
- let mut parser = NetworkParser::new(input.as_bytes());
-
- let config = parser.parse_interfaces(None)?;
-
- let output = String::try_from(config)?;
-
- let expected = "auto lo\n\
- iface lo inet loopback\n\
- \n\
- iface lo inet6 loopback\n\
- \n\
- auto ens18\n\
- iface ens18 inet static\n\
- \taddress 192.168.20.144/20\n\
- \tgateway 192.168.16.1\n\
- #comment\n\
- \n\
- iface ens20 inet static\n\
- \taddress 192.168.20.145/20\n\
- \n\
- iface ens21 inet manual\n\
- \n\
- iface ens22 inet manual\n\
- \n";
- assert_eq!(output, expected);
-
- Ok(())
- }
-
- #[test]
- fn test_network_config_parser_no_blank_2() -> Result<(), Error> {
- // Adapted from bug 2926
- let input = "### Hetzner Online GmbH installimage\n\
- \n\
- source /etc/network/interfaces.d/*\n\
- \n\
- auto lo\n\
- iface lo inet loopback\n\
- iface lo inet6 loopback\n\
- \n\
- auto enp4s0\n\
- iface enp4s0 inet static\n\
- \taddress 10.10.10.10/24\n\
- \tgateway 10.10.10.1\n\
- \t# route 10.10.20.10/24 via 10.10.20.1\n\
- \tup route add -net 10.10.20.10 netmask 255.255.255.0 gw 10.10.20.1 dev enp4s0\n\
- \n\
- iface enp4s0 inet6 static\n\
- \taddress fe80::5496:35ff:fe99:5a6a/64\n\
- \tgateway fe80::1\n";
-
- let mut parser = NetworkParser::new(input.as_bytes());
-
- let config = parser.parse_interfaces(None)?;
-
- let output = String::try_from(config)?;
-
- let expected = "### Hetzner Online GmbH installimage\n\
- \n\
- source /etc/network/interfaces.d/*\n\
- \n\
- auto lo\n\
- iface lo inet loopback\n\
- \n\
- iface lo inet6 loopback\n\
- \n\
- auto enp4s0\n\
- iface enp4s0 inet static\n\
- \taddress 10.10.10.10/24\n\
- \tgateway 10.10.10.1\n\
- \t# route 10.10.20.10/24 via 10.10.20.1\n\
- \tup route add -net 10.10.20.10 netmask 255.255.255.0 gw 10.10.20.1 dev enp4s0\n\
- \n\
- iface enp4s0 inet6 static\n\
- \taddress fe80::5496:35ff:fe99:5a6a/64\n\
- \tgateway fe80::1\n\
- \n";
- assert_eq!(output, expected);
-
- Ok(())
- }
-}
diff --git a/pbs-config/src/network/parser.rs b/pbs-config/src/network/parser.rs
index ec2c64eb..1b55569a 100644
--- a/pbs-config/src/network/parser.rs
+++ b/pbs-config/src/network/parser.rs
@@ -602,3 +602,150 @@ impl<R: BufRead> NetworkParser<R> {
Ok(config)
}
}
+
+#[cfg(test)]
+mod test {
+
+ use anyhow::Error;
+
+ use super::*;
+
+ #[test]
+ fn test_network_config_create_lo_1() -> Result<(), Error> {
+ let input = "";
+
+ let mut parser = NetworkParser::new(input.as_bytes());
+
+ let config = parser.parse_interfaces(None)?;
+
+ let output = String::try_from(config)?;
+
+ let expected = "auto lo\niface lo inet loopback\n\n";
+ assert_eq!(output, expected);
+
+ // run again using output as input
+ let mut parser = NetworkParser::new(output.as_bytes());
+
+ let config = parser.parse_interfaces(None)?;
+
+ let output = String::try_from(config)?;
+
+ assert_eq!(output, expected);
+
+ Ok(())
+ }
+
+ #[test]
+ fn test_network_config_create_lo_2() -> Result<(), Error> {
+ let input = "#c1\n\n#c2\n\niface test inet manual\n";
+
+ let mut parser = NetworkParser::new(input.as_bytes());
+
+ let config = parser.parse_interfaces(None)?;
+
+ let output = String::try_from(config)?;
+
+ // Note: loopback should be added in front of other interfaces
+ let expected = "#c1\n#c2\n\nauto lo\niface lo inet loopback\n\niface test inet manual\n\n";
+ assert_eq!(output, expected);
+
+ Ok(())
+ }
+
+ #[test]
+ fn test_network_config_parser_no_blank_1() -> Result<(), Error> {
+ let input = "auto lo\n\
+ iface lo inet loopback\n\
+ iface lo inet6 loopback\n\
+ auto ens18\n\
+ iface ens18 inet static\n\
+ \taddress 192.168.20.144/20\n\
+ \tgateway 192.168.16.1\n\
+ # comment\n\
+ iface ens20 inet static\n\
+ \taddress 192.168.20.145/20\n\
+ iface ens21 inet manual\n\
+ iface ens22 inet manual\n";
+
+ let mut parser = NetworkParser::new(input.as_bytes());
+
+ let config = parser.parse_interfaces(None)?;
+
+ let output = String::try_from(config)?;
+
+ let expected = "auto lo\n\
+ iface lo inet loopback\n\
+ \n\
+ iface lo inet6 loopback\n\
+ \n\
+ auto ens18\n\
+ iface ens18 inet static\n\
+ \taddress 192.168.20.144/20\n\
+ \tgateway 192.168.16.1\n\
+ #comment\n\
+ \n\
+ iface ens20 inet static\n\
+ \taddress 192.168.20.145/20\n\
+ \n\
+ iface ens21 inet manual\n\
+ \n\
+ iface ens22 inet manual\n\
+ \n";
+ assert_eq!(output, expected);
+
+ Ok(())
+ }
+
+ #[test]
+ fn test_network_config_parser_no_blank_2() -> Result<(), Error> {
+ // Adapted from bug 2926
+ let input = "### Hetzner Online GmbH installimage\n\
+ \n\
+ source /etc/network/interfaces.d/*\n\
+ \n\
+ auto lo\n\
+ iface lo inet loopback\n\
+ iface lo inet6 loopback\n\
+ \n\
+ auto enp4s0\n\
+ iface enp4s0 inet static\n\
+ \taddress 10.10.10.10/24\n\
+ \tgateway 10.10.10.1\n\
+ \t# route 10.10.20.10/24 via 10.10.20.1\n\
+ \tup route add -net 10.10.20.10 netmask 255.255.255.0 gw 10.10.20.1 dev enp4s0\n\
+ \n\
+ iface enp4s0 inet6 static\n\
+ \taddress fe80::5496:35ff:fe99:5a6a/64\n\
+ \tgateway fe80::1\n";
+
+ let mut parser = NetworkParser::new(input.as_bytes());
+
+ let config = parser.parse_interfaces(None)?;
+
+ let output = String::try_from(config)?;
+
+ let expected = "### Hetzner Online GmbH installimage\n\
+ \n\
+ source /etc/network/interfaces.d/*\n\
+ \n\
+ auto lo\n\
+ iface lo inet loopback\n\
+ \n\
+ iface lo inet6 loopback\n\
+ \n\
+ auto enp4s0\n\
+ iface enp4s0 inet static\n\
+ \taddress 10.10.10.10/24\n\
+ \tgateway 10.10.10.1\n\
+ \t# route 10.10.20.10/24 via 10.10.20.1\n\
+ \tup route add -net 10.10.20.10 netmask 255.255.255.0 gw 10.10.20.1 dev enp4s0\n\
+ \n\
+ iface enp4s0 inet6 static\n\
+ \taddress fe80::5496:35ff:fe99:5a6a/64\n\
+ \tgateway fe80::1\n\
+ \n";
+ assert_eq!(output, expected);
+
+ Ok(())
+ }
+}
--
2.44.0
^ permalink raw reply [flat|nested] 13+ messages in thread
* [pbs-devel] [PATCH proxmox-backup v3 3/9] tests: simple tests for writing the network config
2024-04-04 10:00 [pbs-devel] [PATCH widget-toolkit/proxmox-backup v3 0/9] Fix #3115: VLAN Network Interface Configuration Stefan Lendl
2024-04-04 10:00 ` [pbs-devel] [PATCH widget-toolkit v3 1/9] form: include vlan field widget from PVE Stefan Lendl
2024-04-04 10:00 ` [pbs-devel] [PATCH proxmox-backup v3 2/9] tests: move network tests to parser.rs Stefan Lendl
@ 2024-04-04 10:00 ` Stefan Lendl
2024-04-04 10:00 ` [pbs-devel] [PATCH proxmox-backup v3 4/9] config: write vlan network interface Stefan Lendl
` (7 subsequent siblings)
10 siblings, 0 replies; 13+ messages in thread
From: Stefan Lendl @ 2024-04-04 10:00 UTC (permalink / raw)
To: pbs-devel
Simple tests for manual and static configurations.
Signed-off-by: Stefan Lendl <s.lendl@proxmox.com>
Tested-by: Lukas Wagner <l.wagner@proxmox.com>
Reviewed-by: Lukas Wagner <l.wagner@proxmox.com>
---
pbs-config/src/network/mod.rs | 79 +++++++++++++++++++++++++++++++++++
1 file changed, 79 insertions(+)
diff --git a/pbs-config/src/network/mod.rs b/pbs-config/src/network/mod.rs
index 21187ec2..7fec7e29 100644
--- a/pbs-config/src/network/mod.rs
+++ b/pbs-config/src/network/mod.rs
@@ -503,3 +503,82 @@ pub fn complete_port_list(arg: &str, _param: &HashMap<String, String>) -> Vec<St
.map(|port| format!("{}{}", prefix, port))
.collect()
}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ use NetworkConfigMethod::*;
+ use NetworkInterfaceType::*;
+ use NetworkOrderEntry::*;
+
+ #[test]
+ fn test_write_network_config_manual() {
+ let iface_name = String::from("enp3s0");
+ let mut iface = Interface::new(iface_name.clone());
+ iface.interface_type = Eth;
+ iface.method = Some(Manual);
+ iface.active = true;
+
+ let nw_config = NetworkConfig {
+ interfaces: BTreeMap::from([(iface_name.clone(), iface)]),
+ order: vec![Iface(iface_name.clone())],
+ };
+
+ assert_eq!(
+ String::try_from(nw_config).unwrap().trim(),
+ r#"iface enp3s0 inet manual"#
+ );
+ }
+
+ #[test]
+ fn test_write_network_config_static() {
+ let iface_name = String::from("enp3s0");
+ let mut iface = Interface::new(iface_name.clone());
+ iface.interface_type = Eth;
+ iface.method = Some(Static);
+ iface.cidr = Some(String::from("10.0.0.100/16"));
+ iface.active = true;
+
+ let nw_config = NetworkConfig {
+ interfaces: BTreeMap::from([(iface_name.clone(), iface)]),
+ order: vec![Iface(iface_name.clone())],
+ };
+ assert_eq!(
+ String::try_from(nw_config).unwrap().trim(),
+ format!(
+ r#"
+iface enp3s0 inet static
+ address 10.0.0.100/16"#
+ )
+ .trim()
+ );
+ }
+
+ #[test]
+ fn test_write_network_config_static_with_gateway() {
+ let iface_name = String::from("enp3s0");
+ let mut iface = Interface::new(iface_name.clone());
+ iface.interface_type = Eth;
+ iface.method = Some(Static);
+ iface.cidr = Some(String::from("10.0.0.100/16"));
+ iface.gateway = Some(String::from("10.0.0.1"));
+ iface.active = true;
+
+ let nw_config = NetworkConfig {
+ interfaces: BTreeMap::from([(iface_name.clone(), iface)]),
+ order: vec![Iface(iface_name.clone())],
+ };
+ assert_eq!(
+ String::try_from(nw_config).unwrap().trim(),
+ format!(
+ r#"
+iface enp3s0 inet static
+ address 10.0.0.100/16
+ gateway 10.0.0.1"#
+ )
+ .trim()
+ );
+ }
+}
+
--
2.44.0
^ permalink raw reply [flat|nested] 13+ messages in thread
* [pbs-devel] [PATCH proxmox-backup v3 4/9] config: write vlan network interface
2024-04-04 10:00 [pbs-devel] [PATCH widget-toolkit/proxmox-backup v3 0/9] Fix #3115: VLAN Network Interface Configuration Stefan Lendl
` (2 preceding siblings ...)
2024-04-04 10:00 ` [pbs-devel] [PATCH proxmox-backup v3 3/9] tests: simple tests for writing the network config Stefan Lendl
@ 2024-04-04 10:00 ` Stefan Lendl
2024-04-04 10:00 ` [pbs-devel] [PATCH proxmox-backup v3 5/9] config: parse vlan interface from config Stefan Lendl
` (6 subsequent siblings)
10 siblings, 0 replies; 13+ messages in thread
From: Stefan Lendl @ 2024-04-04 10:00 UTC (permalink / raw)
To: pbs-devel
* Add vlan_id and vlan_raw_device fields to the Interface api type
* Write to the network config the vlan specific properties for vlan
interface type
* Add several tests to verify the functionally
Signed-off-by: Stefan Lendl <s.lendl@proxmox.com>
Tested-by: Lukas Wagner <l.wagner@proxmox.com>
Reviewed-by: Lukas Wagner <l.wagner@proxmox.com>
---
pbs-api-types/src/network.rs | 17 ++++++++
pbs-config/src/network/mod.rs | 73 ++++++++++++++++++++++++++++++++++-
2 files changed, 89 insertions(+), 1 deletion(-)
diff --git a/pbs-api-types/src/network.rs b/pbs-api-types/src/network.rs
index e3a5e481..fe083dc6 100644
--- a/pbs-api-types/src/network.rs
+++ b/pbs-api-types/src/network.rs
@@ -224,6 +224,15 @@ pub const NETWORK_INTERFACE_LIST_SCHEMA: Schema =
schema: NETWORK_INTERFACE_ARRAY_SCHEMA,
optional: true,
},
+ "vlan-id": {
+ description: "VLAN ID.",
+ type: u16,
+ optional: true,
+ },
+ "vlan-raw-device": {
+ schema: NETWORK_INTERFACE_NAME_SCHEMA,
+ optional: true,
+ },
bond_mode: {
type: LinuxBondMode,
optional: true,
@@ -287,6 +296,12 @@ pub struct Interface {
/// Enable bridge vlan support.
#[serde(skip_serializing_if = "Option::is_none")]
pub bridge_vlan_aware: Option<bool>,
+ #[serde(skip_serializing_if = "Option::is_none")]
+ #[serde(rename = "vlan-id")]
+ pub vlan_id: Option<u16>,
+ #[serde(skip_serializing_if = "Option::is_none")]
+ #[serde(rename = "vlan-raw-device")]
+ pub vlan_raw_device: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub slaves: Option<Vec<String>>,
@@ -319,6 +334,8 @@ impl Interface {
mtu: None,
bridge_ports: None,
bridge_vlan_aware: None,
+ vlan_id: None,
+ vlan_raw_device: None,
slaves: None,
bond_mode: None,
bond_primary: None,
diff --git a/pbs-config/src/network/mod.rs b/pbs-config/src/network/mod.rs
index 7fec7e29..02117535 100644
--- a/pbs-config/src/network/mod.rs
+++ b/pbs-config/src/network/mod.rs
@@ -79,6 +79,14 @@ fn write_iface_attributes(iface: &Interface, w: &mut dyn Write) -> Result<(), Er
writeln!(w, "\tbond-slaves {}", slaves.join(" "))?;
}
}
+ NetworkInterfaceType::Vlan => {
+ if let Some(vlan_id) = iface.vlan_id {
+ writeln!(w, "\tvlan-id {vlan_id}")?;
+ }
+ if let Some(vlan_raw_device) = &iface.vlan_raw_device {
+ writeln!(w, "\tvlan-raw-device {vlan_raw_device}")?;
+ }
+ }
_ => {}
}
@@ -580,5 +588,68 @@ iface enp3s0 inet static
.trim()
);
}
-}
+ #[test]
+ fn test_write_network_config_vlan_id_in_name() {
+ let iface_name = String::from("vmbr0.100");
+ let mut iface = Interface::new(iface_name.clone());
+ iface.interface_type = Vlan;
+ iface.method = Some(Manual);
+ iface.active = true;
+
+ let nw_config = NetworkConfig {
+ interfaces: BTreeMap::from([(iface_name.clone(), iface)]),
+ order: vec![Iface(iface_name.clone())],
+ };
+ assert_eq!(
+ String::try_from(nw_config).unwrap().trim(),
+ "iface vmbr0.100 inet manual"
+ );
+ }
+
+ #[test]
+ fn test_write_network_config_vlan_with_raw_device() {
+ let iface_name = String::from("vlan100");
+ let mut iface = Interface::new(iface_name.clone());
+ iface.interface_type = Vlan;
+ iface.vlan_raw_device = Some(String::from("vmbr0"));
+ iface.method = Some(Manual);
+ iface.active = true;
+
+ let nw_config = NetworkConfig {
+ interfaces: BTreeMap::from([(iface_name.clone(), iface)]),
+ order: vec![Iface(iface_name.clone())],
+ };
+ assert_eq!(
+ String::try_from(nw_config).unwrap().trim(),
+ r#"
+iface vlan100 inet manual
+ vlan-raw-device vmbr0"#
+ .trim()
+ );
+ }
+
+ #[test]
+ fn test_write_network_config_vlan_with_individual_name() {
+ let iface_name = String::from("individual_name");
+ let mut iface = Interface::new(iface_name.clone());
+ iface.interface_type = Vlan;
+ iface.vlan_raw_device = Some(String::from("vmbr0"));
+ iface.vlan_id = Some(100);
+ iface.method = Some(Manual);
+ iface.active = true;
+
+ let nw_config = NetworkConfig {
+ interfaces: BTreeMap::from([(iface_name.clone(), iface)]),
+ order: vec![Iface(iface_name.clone())],
+ };
+ assert_eq!(
+ String::try_from(nw_config).unwrap().trim(),
+ r#"
+iface individual_name inet manual
+ vlan-id 100
+ vlan-raw-device vmbr0"#
+ .trim()
+ );
+ }
+}
--
2.44.0
^ permalink raw reply [flat|nested] 13+ messages in thread
* [pbs-devel] [PATCH proxmox-backup v3 5/9] config: parse vlan interface from config
2024-04-04 10:00 [pbs-devel] [PATCH widget-toolkit/proxmox-backup v3 0/9] Fix #3115: VLAN Network Interface Configuration Stefan Lendl
` (3 preceding siblings ...)
2024-04-04 10:00 ` [pbs-devel] [PATCH proxmox-backup v3 4/9] config: write vlan network interface Stefan Lendl
@ 2024-04-04 10:00 ` Stefan Lendl
2024-04-04 10:00 ` [pbs-devel] [PATCH proxmox-backup v3 6/9] config: remove unnecessary pub in various methods in NetworkConfig Stefan Lendl
` (5 subsequent siblings)
10 siblings, 0 replies; 13+ messages in thread
From: Stefan Lendl @ 2024-04-04 10:00 UTC (permalink / raw)
To: pbs-devel
Support three types of vlan configurations defined in interfaces,
conforming to the PVE configurations:
iface nic.<vlan-id> inet
iface vlan<vlan-id> inet
vlan-raw-device <nic>
iface <arbitraty-name> inet
vlan-id <vlan-id>
vlan-raw-device <nic>
* Add lexer Token enum variants for vlan-id and vlan-raw-device and parse
them in parse_iface_attributes.
* Add tests to verify this works in the above scenarios
Signed-off-by: Stefan Lendl <s.lendl@proxmox.com>
Tested-by: Lukas Wagner <l.wagner@proxmox.com>
Reviewed-by: Lukas Wagner <l.wagner@proxmox.com>
---
pbs-config/src/network/lexer.rs | 6 ++
pbs-config/src/network/parser.rs | 97 +++++++++++++++++++++++++++++++-
2 files changed, 102 insertions(+), 1 deletion(-)
diff --git a/pbs-config/src/network/lexer.rs b/pbs-config/src/network/lexer.rs
index fd23e3d8..d0b7d8cd 100644
--- a/pbs-config/src/network/lexer.rs
+++ b/pbs-config/src/network/lexer.rs
@@ -24,6 +24,8 @@ pub enum Token {
MTU,
BridgePorts,
BridgeVlanAware,
+ VlanId,
+ VlanRawDevice,
BondSlaves,
BondMode,
BondPrimary,
@@ -50,6 +52,10 @@ lazy_static! {
map.insert("bridge_ports", Token::BridgePorts);
map.insert("bridge-vlan-aware", Token::BridgeVlanAware);
map.insert("bridge_vlan_aware", Token::BridgeVlanAware);
+ map.insert("vlan-id", Token::VlanId);
+ map.insert("vlan_id", Token::VlanId);
+ map.insert("vlan-raw-device", Token::VlanRawDevice);
+ map.insert("vlan_raw_device", Token::VlanRawDevice);
map.insert("bond-slaves", Token::BondSlaves);
map.insert("bond_slaves", Token::BondSlaves);
map.insert("bond-mode", Token::BondMode);
diff --git a/pbs-config/src/network/parser.rs b/pbs-config/src/network/parser.rs
index 1b55569a..796e9308 100644
--- a/pbs-config/src/network/parser.rs
+++ b/pbs-config/src/network/parser.rs
@@ -361,6 +361,20 @@ impl<R: BufRead> NetworkParser<R> {
interface.bond_xmit_hash_policy = Some(policy);
self.eat(Token::Newline)?;
}
+ Token::VlanId => {
+ self.eat(Token::VlanId)?;
+ let vlan_id = self.next_text()?.parse()?;
+ interface.vlan_id = Some(vlan_id);
+ set_interface_type(interface, NetworkInterfaceType::Vlan)?;
+ self.eat(Token::Newline)?;
+ }
+ Token::VlanRawDevice => {
+ self.eat(Token::VlanRawDevice)?;
+ let vlan_raw_device = self.next_text()?;
+ interface.vlan_raw_device = Some(vlan_raw_device);
+ set_interface_type(interface, NetworkInterfaceType::Vlan)?;
+ self.eat(Token::Newline)?;
+ }
_ => {
// parse addon attributes
let option = self.parse_to_eol()?;
@@ -522,7 +536,7 @@ impl<R: BufRead> NetworkParser<R> {
lazy_static! {
static ref INTERFACE_ALIAS_REGEX: Regex = Regex::new(r"^\S+:\d+$").unwrap();
- static ref VLAN_INTERFACE_REGEX: Regex = Regex::new(r"^\S+\.\d+$").unwrap();
+ static ref VLAN_INTERFACE_REGEX: Regex = Regex::new(r"^\S+\.\d+|vlan\d+$").unwrap();
}
if let Some(existing_interfaces) = existing_interfaces {
@@ -748,4 +762,85 @@ mod test {
Ok(())
}
+
+ #[test]
+ fn test_network_config_parser_vlan_id_in_name() {
+ let input = "iface vmbr0.100 inet static manual";
+ let mut parser = NetworkParser::new(input.as_bytes());
+ let config = parser.parse_interfaces(None).unwrap();
+
+ let iface = config.interfaces.get("vmbr0.100").unwrap();
+ assert_eq!(iface.interface_type, NetworkInterfaceType::Vlan);
+ assert_eq!(iface.vlan_raw_device, None);
+ assert_eq!(iface.vlan_id, None);
+ }
+
+ #[test]
+ fn test_network_config_parser_vlan_with_raw_device() {
+ let input = r#"
+iface vlan100 inet manual
+ vlan-raw-device vmbr0"#;
+
+ let mut parser = NetworkParser::new(input.as_bytes());
+ let config = parser.parse_interfaces(None).unwrap();
+
+ let iface = config.interfaces.get("vlan100").unwrap();
+ assert_eq!(iface.interface_type, NetworkInterfaceType::Vlan);
+ assert_eq!(iface.vlan_raw_device, Some(String::from("vmbr0")));
+ assert_eq!(iface.vlan_id, None);
+ }
+
+ #[test]
+ fn test_network_config_parser_vlan_with_raw_device_static() {
+ let input = r#"
+iface vlan100 inet static
+ vlan-raw-device vmbr0
+ address 10.0.0.100/16"#;
+
+ let mut parser = NetworkParser::new(input.as_bytes());
+ let config = parser.parse_interfaces(None).unwrap();
+
+ let iface = config.interfaces.get("vlan100").unwrap();
+ assert_eq!(iface.interface_type, NetworkInterfaceType::Vlan);
+ assert_eq!(iface.vlan_raw_device, Some(String::from("vmbr0")));
+ assert_eq!(iface.vlan_id, None);
+ assert_eq!(iface.method, Some(NetworkConfigMethod::Static));
+ assert_eq!(iface.cidr, Some(String::from("10.0.0.100/16")));
+ }
+
+ #[test]
+ fn test_network_config_parser_vlan_individual_name() {
+ let input = r#"
+iface individual_name inet manual
+ vlan-id 100
+ vlan-raw-device vmbr0"#;
+
+ let mut parser = NetworkParser::new(input.as_bytes());
+ let config = parser.parse_interfaces(None).unwrap();
+
+ let iface = config.interfaces.get("individual_name").unwrap();
+ assert_eq!(iface.interface_type, NetworkInterfaceType::Vlan);
+ assert_eq!(iface.vlan_raw_device, Some(String::from("vmbr0")));
+ assert_eq!(iface.vlan_id, Some(100));
+ }
+
+ #[test]
+ fn test_network_config_parser_vlan_individual_name_static() {
+ let input = r#"
+iface individual_name inet static
+ vlan-id 100
+ vlan-raw-device vmbr0
+ address 10.0.0.100/16
+"#;
+
+ let mut parser = NetworkParser::new(input.as_bytes());
+ let config = parser.parse_interfaces(None).unwrap();
+
+ let iface = config.interfaces.get("individual_name").unwrap();
+ assert_eq!(iface.interface_type, NetworkInterfaceType::Vlan);
+ assert_eq!(iface.vlan_raw_device, Some(String::from("vmbr0")));
+ assert_eq!(iface.vlan_id, Some(100));
+ assert_eq!(iface.method, Some(NetworkConfigMethod::Static));
+ assert_eq!(iface.cidr, Some(String::from("10.0.0.100/16")));
+ }
}
--
2.44.0
^ permalink raw reply [flat|nested] 13+ messages in thread
* [pbs-devel] [PATCH proxmox-backup v3 6/9] config: remove unnecessary pub in various methods in NetworkConfig
2024-04-04 10:00 [pbs-devel] [PATCH widget-toolkit/proxmox-backup v3 0/9] Fix #3115: VLAN Network Interface Configuration Stefan Lendl
` (4 preceding siblings ...)
2024-04-04 10:00 ` [pbs-devel] [PATCH proxmox-backup v3 5/9] config: parse vlan interface from config Stefan Lendl
@ 2024-04-04 10:00 ` Stefan Lendl
2024-04-04 10:00 ` [pbs-devel] [PATCH proxmox-backup v3 7/9] fmt: fix intendation in api macro Stefan Lendl
` (4 subsequent siblings)
10 siblings, 0 replies; 13+ messages in thread
From: Stefan Lendl @ 2024-04-04 10:00 UTC (permalink / raw)
To: pbs-devel
Signed-off-by: Stefan Lendl <s.lendl@proxmox.com>
Tested-by: Lukas Wagner <l.wagner@proxmox.com>
Reviewed-by: Lukas Wagner <l.wagner@proxmox.com>
---
pbs-config/src/network/mod.rs | 10 +++++-----
pbs-config/src/network/parser.rs | 4 ++--
2 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/pbs-config/src/network/mod.rs b/pbs-config/src/network/mod.rs
index 02117535..51b09937 100644
--- a/pbs-config/src/network/mod.rs
+++ b/pbs-config/src/network/mod.rs
@@ -251,7 +251,7 @@ impl NetworkConfig {
}
/// Check if ports are used only once
- pub fn check_port_usage(&self) -> Result<(), Error> {
+ fn check_port_usage(&self) -> Result<(), Error> {
let mut used_ports = HashMap::new();
let mut check_port_usage = |iface, ports: &Vec<String>| {
for port in ports.iter() {
@@ -280,7 +280,7 @@ impl NetworkConfig {
}
/// Check if child mtu is less or equal than parent mtu
- pub fn check_mtu(&self, parent_name: &str, child_name: &str) -> Result<(), Error> {
+ fn check_mtu(&self, parent_name: &str, child_name: &str) -> Result<(), Error> {
let parent = self
.interfaces
.get(parent_name)
@@ -320,7 +320,7 @@ impl NetworkConfig {
}
/// Check if bond slaves exists
- pub fn check_bond_slaves(&self) -> Result<(), Error> {
+ fn check_bond_slaves(&self) -> Result<(), Error> {
for (iface, interface) in self.interfaces.iter() {
if let Some(slaves) = &interface.slaves {
for slave in slaves.iter() {
@@ -348,7 +348,7 @@ impl NetworkConfig {
}
/// Check if bridge ports exists
- pub fn check_bridge_ports(&self) -> Result<(), Error> {
+ fn check_bridge_ports(&self) -> Result<(), Error> {
lazy_static! {
static ref VLAN_INTERFACE_REGEX: Regex = Regex::new(r"^(\S+)\.(\d+)$").unwrap();
}
@@ -372,7 +372,7 @@ impl NetworkConfig {
Ok(())
}
- pub fn write_config(&self, w: &mut dyn Write) -> Result<(), Error> {
+ fn write_config(&self, w: &mut dyn Write) -> Result<(), Error> {
self.check_port_usage()?;
self.check_bond_slaves()?;
self.check_bridge_ports()?;
diff --git a/pbs-config/src/network/parser.rs b/pbs-config/src/network/parser.rs
index 796e9308..e409c94c 100644
--- a/pbs-config/src/network/parser.rs
+++ b/pbs-config/src/network/parser.rs
@@ -487,11 +487,11 @@ impl<R: BufRead> NetworkParser<R> {
&mut self,
existing_interfaces: Option<&HashMap<String, bool>>,
) -> Result<NetworkConfig, Error> {
- self._parse_interfaces(existing_interfaces)
+ self.do_parse_interfaces(existing_interfaces)
.map_err(|err| format_err!("line {}: {}", self.line_nr, err))
}
- pub fn _parse_interfaces(
+ fn do_parse_interfaces(
&mut self,
existing_interfaces: Option<&HashMap<String, bool>>,
) -> Result<NetworkConfig, Error> {
--
2.44.0
^ permalink raw reply [flat|nested] 13+ messages in thread
* [pbs-devel] [PATCH proxmox-backup v3 7/9] fmt: fix intendation in api macro
2024-04-04 10:00 [pbs-devel] [PATCH widget-toolkit/proxmox-backup v3 0/9] Fix #3115: VLAN Network Interface Configuration Stefan Lendl
` (5 preceding siblings ...)
2024-04-04 10:00 ` [pbs-devel] [PATCH proxmox-backup v3 6/9] config: remove unnecessary pub in various methods in NetworkConfig Stefan Lendl
@ 2024-04-04 10:00 ` Stefan Lendl
2024-04-04 10:00 ` [pbs-devel] [PATCH proxmox-backup v3 8/9] api: create and update vlan interfaces Stefan Lendl
` (3 subsequent siblings)
10 siblings, 0 replies; 13+ messages in thread
From: Stefan Lendl @ 2024-04-04 10:00 UTC (permalink / raw)
To: pbs-devel
Signed-off-by: Stefan Lendl <s.lendl@proxmox.com>
Reviewed-by: Lukas Wagner <l.wagner@proxmox.com>
---
src/api2/node/network.rs | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/src/api2/node/network.rs b/src/api2/node/network.rs
index ade6fe40..187b27a0 100644
--- a/src/api2/node/network.rs
+++ b/src/api2/node/network.rs
@@ -227,9 +227,9 @@ pub fn read_interface(iface: String) -> Result<Value, Error> {
optional: true,
},
bridge_vlan_aware: {
- description: "Enable bridge vlan support.",
- type: bool,
- optional: true,
+ description: "Enable bridge vlan support.",
+ type: bool,
+ optional: true,
},
bond_mode: {
type: LinuxBondMode,
@@ -503,9 +503,9 @@ pub enum DeletableProperty {
optional: true,
},
bridge_vlan_aware: {
- description: "Enable bridge vlan support.",
- type: bool,
- optional: true,
+ description: "Enable bridge vlan support.",
+ type: bool,
+ optional: true,
},
bond_mode: {
type: LinuxBondMode,
--
2.44.0
^ permalink raw reply [flat|nested] 13+ messages in thread
* [pbs-devel] [PATCH proxmox-backup v3 8/9] api: create and update vlan interfaces
2024-04-04 10:00 [pbs-devel] [PATCH widget-toolkit/proxmox-backup v3 0/9] Fix #3115: VLAN Network Interface Configuration Stefan Lendl
` (6 preceding siblings ...)
2024-04-04 10:00 ` [pbs-devel] [PATCH proxmox-backup v3 7/9] fmt: fix intendation in api macro Stefan Lendl
@ 2024-04-04 10:00 ` Stefan Lendl
2024-04-04 10:00 ` [pbs-devel] [PATCH proxmox-backup v3 9/9] ui: enable vlan widget Stefan Lendl
` (2 subsequent siblings)
10 siblings, 0 replies; 13+ messages in thread
From: Stefan Lendl @ 2024-04-04 10:00 UTC (permalink / raw)
To: pbs-devel
* Implement setting vlan-id and vlan-raw-device in the create and update api.
* Checking if the provided vlan-raw-device exists
* Moved VLAN_INTERFACE_REGEX to top level network module to use it in
the checking functions there. Changed to match with named capture groups.
* Unit tests to verify parsing vlan_id and vlan_raw_device from name.
Signed-off-by: Stefan Lendl <s.lendl@proxmox.com>
Tested-by: Lukas Wagner <l.wagner@proxmox.com>
Reviewed-by: Lukas Wagner <l.wagner@proxmox.com>
---
pbs-config/src/network/mod.rs | 35 +++++++++++++++++++
pbs-config/src/network/parser.rs | 3 +-
src/api2/node/network.rs | 60 +++++++++++++++++++++++++++++++-
3 files changed, 96 insertions(+), 2 deletions(-)
diff --git a/pbs-config/src/network/mod.rs b/pbs-config/src/network/mod.rs
index 51b09937..19a2df8c 100644
--- a/pbs-config/src/network/mod.rs
+++ b/pbs-config/src/network/mod.rs
@@ -25,6 +25,8 @@ use crate::{open_backup_lockfile, BackupLockGuard};
lazy_static! {
static ref PHYSICAL_NIC_REGEX: Regex = Regex::new(r"^(?:eth\d+|en[^:.]+|ib\d+)$").unwrap();
+ static ref VLAN_INTERFACE_REGEX: Regex =
+ Regex::new(r"^(?P<vlan_raw_device>\S+)\.(?P<vlan_id>\d+)|vlan(?P<vlan_id2>\d+)$").unwrap();
}
pub fn is_physical_nic(iface: &str) -> bool {
@@ -41,6 +43,21 @@ pub fn bond_xmit_hash_policy_from_str(s: &str) -> Result<BondXmitHashPolicy, Err
.map_err(|_: value::Error| format_err!("invalid bond_xmit_hash_policy '{}'", s))
}
+pub fn parse_vlan_id_from_name(iface_name: &str) -> Option<u16> {
+ VLAN_INTERFACE_REGEX.captures(iface_name).and_then(|cap| {
+ cap.name("vlan_id")
+ .or(cap.name("vlan_id2"))
+ .and_then(|id| id.as_str().parse::<u16>().ok())
+ })
+}
+
+pub fn parse_vlan_raw_device_from_name(iface_name: &str) -> Option<&str> {
+ VLAN_INTERFACE_REGEX
+ .captures(iface_name)
+ .and_then(|cap| cap.name("vlan_raw_device"))
+ .map(Into::into)
+}
+
// Write attributes not depending on address family
fn write_iface_attributes(iface: &Interface, w: &mut dyn Write) -> Result<(), Error> {
static EMPTY_LIST: Vec<String> = Vec::new();
@@ -652,4 +669,22 @@ iface individual_name inet manual
.trim()
);
}
+
+ #[test]
+ fn test_vlan_parse_vlan_id_from_name() {
+ assert_eq!(parse_vlan_id_from_name("vlan100"), Some(100));
+ assert_eq!(parse_vlan_id_from_name("vlan"), None);
+ assert_eq!(parse_vlan_id_from_name("arbitrary"), None);
+ assert_eq!(parse_vlan_id_from_name("vmbr0.100"), Some(100));
+ assert_eq!(parse_vlan_id_from_name("vmbr0"), None);
+ // assert_eq!(parse_vlan_id_from_name("vmbr0.1.400"), Some(400)); // NOTE ifupdown2 does actually support this
+ }
+
+ #[test]
+ fn test_vlan_parse_vlan_raw_device_from_name() {
+ assert_eq!(parse_vlan_raw_device_from_name("vlan100"), None);
+ assert_eq!(parse_vlan_raw_device_from_name("arbitrary"), None);
+ assert_eq!(parse_vlan_raw_device_from_name("vmbr0"), None);
+ assert_eq!(parse_vlan_raw_device_from_name("vmbr0.200"), Some("vmbr0"));
+ }
}
diff --git a/pbs-config/src/network/parser.rs b/pbs-config/src/network/parser.rs
index e409c94c..2158a04f 100644
--- a/pbs-config/src/network/parser.rs
+++ b/pbs-config/src/network/parser.rs
@@ -1,3 +1,5 @@
+use crate::network::VLAN_INTERFACE_REGEX;
+
use std::collections::{HashMap, HashSet};
use std::io::BufRead;
use std::iter::{Iterator, Peekable};
@@ -536,7 +538,6 @@ impl<R: BufRead> NetworkParser<R> {
lazy_static! {
static ref INTERFACE_ALIAS_REGEX: Regex = Regex::new(r"^\S+:\d+$").unwrap();
- static ref VLAN_INTERFACE_REGEX: Regex = Regex::new(r"^\S+\.\d+|vlan\d+$").unwrap();
}
if let Some(existing_interfaces) = existing_interfaces {
diff --git a/src/api2/node/network.rs b/src/api2/node/network.rs
index 187b27a0..92297421 100644
--- a/src/api2/node/network.rs
+++ b/src/api2/node/network.rs
@@ -12,7 +12,9 @@ use pbs_api_types::{
NETWORK_INTERFACE_ARRAY_SCHEMA, NETWORK_INTERFACE_LIST_SCHEMA, NETWORK_INTERFACE_NAME_SCHEMA,
NODE_SCHEMA, PRIV_SYS_AUDIT, PRIV_SYS_MODIFY, PROXMOX_CONFIG_DIGEST_SCHEMA,
};
-use pbs_config::network::{self, NetworkConfig};
+use pbs_config::network::{
+ self, parse_vlan_id_from_name, parse_vlan_raw_device_from_name, NetworkConfig,
+};
use proxmox_rest_server::WorkerTask;
@@ -231,6 +233,15 @@ pub fn read_interface(iface: String) -> Result<Value, Error> {
type: bool,
optional: true,
},
+ "vlan-id": {
+ description: "VLAN ID.",
+ type: u16,
+ optional: true,
+ },
+ "vlan-raw-device": {
+ schema: NETWORK_INTERFACE_NAME_SCHEMA,
+ optional: true,
+ },
bond_mode: {
type: LinuxBondMode,
optional: true,
@@ -269,6 +280,8 @@ pub fn create_interface(
mtu: Option<u64>,
bridge_ports: Option<String>,
bridge_vlan_aware: Option<bool>,
+ vlan_id: Option<u16>,
+ vlan_raw_device: Option<String>,
bond_mode: Option<LinuxBondMode>,
bond_primary: Option<String>,
bond_xmit_hash_policy: Option<BondXmitHashPolicy>,
@@ -373,6 +386,24 @@ pub fn create_interface(
set_bond_slaves(&mut interface, slaves)?;
}
}
+ NetworkInterfaceType::Vlan => {
+ if vlan_id.is_none() && parse_vlan_id_from_name(&iface).is_none() {
+ bail!("vlan-id must be set");
+ }
+ interface.vlan_id = vlan_id;
+
+ if let Some(dev) = vlan_raw_device
+ .as_deref()
+ .or_else(|| parse_vlan_raw_device_from_name(&iface))
+ {
+ if !config.interfaces.contains_key(dev) {
+ bail!("vlan-raw-device {dev} does not exist");
+ }
+ } else {
+ bail!("vlan-raw-device must be set");
+ }
+ interface.vlan_raw_device = vlan_raw_device;
+ }
_ => bail!(
"creating network interface type '{:?}' is not supported",
interface_type
@@ -507,6 +538,15 @@ pub enum DeletableProperty {
type: bool,
optional: true,
},
+ "vlan-id": {
+ description: "VLAN ID.",
+ type: u16,
+ optional: true,
+ },
+ "vlan-raw-device": {
+ schema: NETWORK_INTERFACE_NAME_SCHEMA,
+ optional: true,
+ },
bond_mode: {
type: LinuxBondMode,
optional: true,
@@ -557,6 +597,8 @@ pub fn update_interface(
mtu: Option<u64>,
bridge_ports: Option<String>,
bridge_vlan_aware: Option<bool>,
+ vlan_id: Option<u16>,
+ vlan_raw_device: Option<String>,
bond_mode: Option<LinuxBondMode>,
bond_primary: Option<String>,
bond_xmit_hash_policy: Option<BondXmitHashPolicy>,
@@ -581,6 +623,15 @@ pub fn update_interface(
check_duplicate_gateway_v6(&config, &iface)?;
}
+ if let Some(dev) = vlan_raw_device
+ .as_deref()
+ .or_else(|| parse_vlan_raw_device_from_name(&iface))
+ {
+ if !config.interfaces.contains_key(dev) {
+ bail!("vlan-raw-device {dev} does not exist");
+ }
+ }
+
let interface = config.lookup_mut(&iface)?;
if let Some(interface_type) = param.get("type") {
@@ -734,6 +785,13 @@ pub fn update_interface(
interface.method6 = Some(NetworkConfigMethod::Manual);
}
+ if vlan_id.is_some() {
+ interface.vlan_id = vlan_id;
+ }
+ if vlan_raw_device.is_some() {
+ interface.vlan_raw_device = vlan_raw_device;
+ }
+
network::save_config(&config)?;
Ok(())
--
2.44.0
^ permalink raw reply [flat|nested] 13+ messages in thread
* [pbs-devel] [PATCH proxmox-backup v3 9/9] ui: enable vlan widget
2024-04-04 10:00 [pbs-devel] [PATCH widget-toolkit/proxmox-backup v3 0/9] Fix #3115: VLAN Network Interface Configuration Stefan Lendl
` (7 preceding siblings ...)
2024-04-04 10:00 ` [pbs-devel] [PATCH proxmox-backup v3 8/9] api: create and update vlan interfaces Stefan Lendl
@ 2024-04-04 10:00 ` Stefan Lendl
2024-04-18 9:43 ` [pbs-devel] [PATCH widget-toolkit/proxmox-backup v3 0/9] Fix #3115: VLAN Network Interface Configuration Folke Gleumes
2024-04-24 19:53 ` [pbs-devel] applied-series: " Thomas Lamprecht
10 siblings, 0 replies; 13+ messages in thread
From: Stefan Lendl @ 2024-04-04 10:00 UTC (permalink / raw)
To: pbs-devel
* Enabled the "Linux VLAN" option when creating a new interface.
* This requires the updated widget-toolkit to contain vlan field widget.
Signed-off-by: Stefan Lendl <s.lendl@proxmox.com>
Tested-by: Lukas Wagner <l.wagner@proxmox.com>
Reviewed-by: Lukas Wagner <l.wagner@proxmox.com>
---
www/SystemConfiguration.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/www/SystemConfiguration.js b/www/SystemConfiguration.js
index e94fe7ca..23330b6a 100644
--- a/www/SystemConfiguration.js
+++ b/www/SystemConfiguration.js
@@ -41,7 +41,7 @@ Ext.define('PBS.SystemConfiguration', {
flex: 1,
minHeight: 200,
showApplyBtn: true,
- types: ['bond', 'bridge'],
+ types: ['bond', 'bridge', 'vlan'],
nodename: 'localhost',
},
],
--
2.44.0
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [pbs-devel] [PATCH widget-toolkit/proxmox-backup v3 0/9] Fix #3115: VLAN Network Interface Configuration
2024-04-04 10:00 [pbs-devel] [PATCH widget-toolkit/proxmox-backup v3 0/9] Fix #3115: VLAN Network Interface Configuration Stefan Lendl
` (8 preceding siblings ...)
2024-04-04 10:00 ` [pbs-devel] [PATCH proxmox-backup v3 9/9] ui: enable vlan widget Stefan Lendl
@ 2024-04-18 9:43 ` Folke Gleumes
2024-04-18 10:04 ` Folke Gleumes
2024-04-24 19:53 ` [pbs-devel] applied-series: " Thomas Lamprecht
10 siblings, 1 reply; 13+ messages in thread
From: Folke Gleumes @ 2024-04-18 9:43 UTC (permalink / raw)
To: Proxmox Backup Server development discussion
Found a small ui bug in the vlan dialog: When the advanced checkbox is
not active, the first few pixel rows of the upper left input box are
cut off.
When the ui is fixed, you can consider this:
Tested-by: Folke Gleumes <f.gleumes@proxmox.com>
On Thu, 2024-04-04 at 12:00 +0200, Stefan Lendl wrote:
> This patch series allows configuring a VLAN network interfaces in the
> PBS GUI
>
> * Added reading and writing of VLAN network config.
> * Created and updating of VLAN network interfaces via the API.
> * Copied the VLAN field widget from PVE and enabled the Linux VLAN
> interface
> type in the GUI.
> * Unit tests for reading and writing the network config.
> * Some cleanup to leave touched functions cleaner than before.
>
> Changes v2 -> v3:
> * slightly updated commit messages and changed typo in git trailer
>
> Changes v1 -> v2:
> * Adapted parameter handling to not expect all properties to be set
> * Incorporated style suggestions
>
> widget-toolkit:
>
> Stefan Lendl (1):
> form: include vlan field widget from PVE
>
> src/Makefile | 1 +
> src/form/VlanField.js | 40
> ++++++++++++++++++++++++++++++++++++++++
> src/node/NetworkEdit.js | 6 +++---
> 3 files changed, 44 insertions(+), 3 deletions(-)
> create mode 100644 src/form/VlanField.js
>
>
> proxmox-backup:
>
> Stefan Lendl (8):
> tests: move network tests to parser.rs
> tests: simple tests for writing the network config
> config: write vlan network interface
> config: parse vlan interface from config
> config: remove unnecessary pub in various methods in NetworkConfig
> fmt: fix intendation in api macro
> api: create and update vlan interfaces
> ui: enable vlan widget
>
> pbs-api-types/src/network.rs | 17 ++
> pbs-config/src/network/lexer.rs | 6 +
> pbs-config/src/network/mod.rs | 300 +++++++++++++++++------------
> --
> pbs-config/src/network/parser.rs | 249 ++++++++++++++++++++++++-
> src/api2/node/network.rs | 72 +++++++-
> www/SystemConfiguration.js | 2 +-
> 6 files changed, 504 insertions(+), 142 deletions(-)
>
>
> Summary over all repositories:
> 9 files changed, 548 insertions(+), 0 deletions(-)
>
_______________________________________________
pbs-devel mailing list
pbs-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pbs-devel
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [pbs-devel] [PATCH widget-toolkit/proxmox-backup v3 0/9] Fix #3115: VLAN Network Interface Configuration
2024-04-18 9:43 ` [pbs-devel] [PATCH widget-toolkit/proxmox-backup v3 0/9] Fix #3115: VLAN Network Interface Configuration Folke Gleumes
@ 2024-04-18 10:04 ` Folke Gleumes
0 siblings, 0 replies; 13+ messages in thread
From: Folke Gleumes @ 2024-04-18 10:04 UTC (permalink / raw)
To: Proxmox Backup Server development discussion
As I just discovered that this bug is also present in PVE and its just
a small visual inconsistency, I don't think its a blocker.
On Thu, 2024-04-18 at 11:43 +0200, Folke Gleumes wrote:
> Found a small ui bug in the vlan dialog: When the advanced checkbox
> is
> not active, the first few pixel rows of the upper left input box are
> cut off.
>
> When the ui is fixed, you can consider this:
>
> Tested-by: Folke Gleumes <f.gleumes@proxmox.com>
>
> On Thu, 2024-04-04 at 12:00 +0200, Stefan Lendl wrote:
> > This patch series allows configuring a VLAN network interfaces in
> > the
> > PBS GUI
> >
> > * Added reading and writing of VLAN network config.
> > * Created and updating of VLAN network interfaces via the API.
> > * Copied the VLAN field widget from PVE and enabled the Linux VLAN
> > interface
> > type in the GUI.
> > * Unit tests for reading and writing the network config.
> > * Some cleanup to leave touched functions cleaner than before.
> >
> > Changes v2 -> v3:
> > * slightly updated commit messages and changed typo in git trailer
> >
> > Changes v1 -> v2:
> > * Adapted parameter handling to not expect all properties to be set
> > * Incorporated style suggestions
> >
> > widget-toolkit:
> >
> > Stefan Lendl (1):
> > form: include vlan field widget from PVE
> >
> > src/Makefile | 1 +
> > src/form/VlanField.js | 40
> > ++++++++++++++++++++++++++++++++++++++++
> > src/node/NetworkEdit.js | 6 +++---
> > 3 files changed, 44 insertions(+), 3 deletions(-)
> > create mode 100644 src/form/VlanField.js
> >
> >
> > proxmox-backup:
> >
> > Stefan Lendl (8):
> > tests: move network tests to parser.rs
> > tests: simple tests for writing the network config
> > config: write vlan network interface
> > config: parse vlan interface from config
> > config: remove unnecessary pub in various methods in
> > NetworkConfig
> > fmt: fix intendation in api macro
> > api: create and update vlan interfaces
> > ui: enable vlan widget
> >
> > pbs-api-types/src/network.rs | 17 ++
> > pbs-config/src/network/lexer.rs | 6 +
> > pbs-config/src/network/mod.rs | 300 +++++++++++++++++----------
> > --
> > --
> > pbs-config/src/network/parser.rs | 249 ++++++++++++++++++++++++-
> > src/api2/node/network.rs | 72 +++++++-
> > www/SystemConfiguration.js | 2 +-
> > 6 files changed, 504 insertions(+), 142 deletions(-)
> >
> >
> > Summary over all repositories:
> > 9 files changed, 548 insertions(+), 0 deletions(-)
> >
>
>
>
> _______________________________________________
> pbs-devel mailing list
> pbs-devel@lists.proxmox.com
> https://lists.proxmox.com/cgi-bin/mailman/listinfo/pbs-devel
_______________________________________________
pbs-devel mailing list
pbs-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pbs-devel
^ permalink raw reply [flat|nested] 13+ messages in thread
* [pbs-devel] applied-series: [PATCH widget-toolkit/proxmox-backup v3 0/9] Fix #3115: VLAN Network Interface Configuration
2024-04-04 10:00 [pbs-devel] [PATCH widget-toolkit/proxmox-backup v3 0/9] Fix #3115: VLAN Network Interface Configuration Stefan Lendl
` (9 preceding siblings ...)
2024-04-18 9:43 ` [pbs-devel] [PATCH widget-toolkit/proxmox-backup v3 0/9] Fix #3115: VLAN Network Interface Configuration Folke Gleumes
@ 2024-04-24 19:53 ` Thomas Lamprecht
10 siblings, 0 replies; 13+ messages in thread
From: Thomas Lamprecht @ 2024-04-24 19:53 UTC (permalink / raw)
To: Proxmox Backup Server development discussion
Am 04/04/2024 um 12:00 schrieb Stefan Lendl:
> This patch series allows configuring a VLAN network interfaces in the PBS GUI
>
> * Added reading and writing of VLAN network config.
> * Created and updating of VLAN network interfaces via the API.
> * Copied the VLAN field widget from PVE and enabled the Linux VLAN interface
> type in the GUI.
> * Unit tests for reading and writing the network config.
> * Some cleanup to leave touched functions cleaner than before.
>
> Changes v2 -> v3:
> * slightly updated commit messages and changed typo in git trailer
>
> Changes v1 -> v2:
> * Adapted parameter handling to not expect all properties to be set
> * Incorporated style suggestions
>
> widget-toolkit:
>
> Stefan Lendl (1):
> form: include vlan field widget from PVE
>
> src/Makefile | 1 +
> src/form/VlanField.js | 40 ++++++++++++++++++++++++++++++++++++++++
> src/node/NetworkEdit.js | 6 +++---
> 3 files changed, 44 insertions(+), 3 deletions(-)
> create mode 100644 src/form/VlanField.js
>
>
> proxmox-backup:
>
> Stefan Lendl (8):
> tests: move network tests to parser.rs
> tests: simple tests for writing the network config
> config: write vlan network interface
> config: parse vlan interface from config
> config: remove unnecessary pub in various methods in NetworkConfig
> fmt: fix intendation in api macro
> api: create and update vlan interfaces
> ui: enable vlan widget
>
> pbs-api-types/src/network.rs | 17 ++
> pbs-config/src/network/lexer.rs | 6 +
> pbs-config/src/network/mod.rs | 300 +++++++++++++++++--------------
> pbs-config/src/network/parser.rs | 249 ++++++++++++++++++++++++-
> src/api2/node/network.rs | 72 +++++++-
> www/SystemConfiguration.js | 2 +-
> 6 files changed, 504 insertions(+), 142 deletions(-)
>
>
> Summary over all repositories:
> 9 files changed, 548 insertions(+), 0 deletions(-)
>
applied series with Folke's T-b added, thanks!
_______________________________________________
pbs-devel mailing list
pbs-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pbs-devel
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2024-04-24 19:53 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-04-04 10:00 [pbs-devel] [PATCH widget-toolkit/proxmox-backup v3 0/9] Fix #3115: VLAN Network Interface Configuration Stefan Lendl
2024-04-04 10:00 ` [pbs-devel] [PATCH widget-toolkit v3 1/9] form: include vlan field widget from PVE Stefan Lendl
2024-04-04 10:00 ` [pbs-devel] [PATCH proxmox-backup v3 2/9] tests: move network tests to parser.rs Stefan Lendl
2024-04-04 10:00 ` [pbs-devel] [PATCH proxmox-backup v3 3/9] tests: simple tests for writing the network config Stefan Lendl
2024-04-04 10:00 ` [pbs-devel] [PATCH proxmox-backup v3 4/9] config: write vlan network interface Stefan Lendl
2024-04-04 10:00 ` [pbs-devel] [PATCH proxmox-backup v3 5/9] config: parse vlan interface from config Stefan Lendl
2024-04-04 10:00 ` [pbs-devel] [PATCH proxmox-backup v3 6/9] config: remove unnecessary pub in various methods in NetworkConfig Stefan Lendl
2024-04-04 10:00 ` [pbs-devel] [PATCH proxmox-backup v3 7/9] fmt: fix intendation in api macro Stefan Lendl
2024-04-04 10:00 ` [pbs-devel] [PATCH proxmox-backup v3 8/9] api: create and update vlan interfaces Stefan Lendl
2024-04-04 10:00 ` [pbs-devel] [PATCH proxmox-backup v3 9/9] ui: enable vlan widget Stefan Lendl
2024-04-18 9:43 ` [pbs-devel] [PATCH widget-toolkit/proxmox-backup v3 0/9] Fix #3115: VLAN Network Interface Configuration Folke Gleumes
2024-04-18 10:04 ` Folke Gleumes
2024-04-24 19:53 ` [pbs-devel] applied-series: " Thomas Lamprecht
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal