api2/network: add bond-primary parameter
needed for 'active-backup' bond mode Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
This commit is contained in:
		
				
					committed by
					
						 Dietmar Maurer
						Dietmar Maurer
					
				
			
			
				
	
			
			
			
						parent
						
							36700a0a87
						
					
				
				
					commit
					85959a99ea
				
			| @ -198,6 +198,10 @@ pub fn read_interface(iface: String) -> Result<Value, Error> { | ||||
|                 type: LinuxBondMode, | ||||
|                 optional: true, | ||||
|             }, | ||||
|             "bond-primary": { | ||||
|                 schema: NETWORK_INTERFACE_NAME_SCHEMA, | ||||
|                 optional: true, | ||||
|             }, | ||||
|             slaves: { | ||||
|                 schema: NETWORK_INTERFACE_LIST_SCHEMA, | ||||
|                 optional: true, | ||||
| @ -224,6 +228,7 @@ pub fn create_interface( | ||||
|     bridge_ports: Option<String>, | ||||
|     bridge_vlan_aware: Option<bool>, | ||||
|     bond_mode: Option<LinuxBondMode>, | ||||
|     bond_primary: Option<String>, | ||||
|     slaves: Option<String>, | ||||
|     param: Value, | ||||
| ) -> Result<(), Error> { | ||||
| @ -284,7 +289,15 @@ pub fn create_interface( | ||||
|             if bridge_vlan_aware.is_some() { interface.bridge_vlan_aware = bridge_vlan_aware; } | ||||
|         } | ||||
|         NetworkInterfaceType::Bond => { | ||||
|             if bond_mode.is_some() { interface.bond_mode = bond_mode; } | ||||
|             if let Some(mode) = bond_mode { | ||||
|                 interface.bond_mode = bond_mode; | ||||
|                 if bond_primary.is_some() { | ||||
|                     if mode != LinuxBondMode::active_backup { | ||||
|                         bail!("bond-primary is only valid with Active/Backup mode"); | ||||
|                     } | ||||
|                     interface.bond_primary = bond_primary; | ||||
|                 } | ||||
|             } | ||||
|             if let Some(slaves) = slaves { | ||||
|                 let slaves = split_interface_list(&slaves)?; | ||||
|                 interface.set_bond_slaves(slaves)?; | ||||
| @ -343,6 +356,9 @@ pub enum DeletableProperty { | ||||
|     bridge_vlan_aware, | ||||
|     /// Delete bond-slaves (set to 'none') | ||||
|     slaves, | ||||
|     /// Delete bond-primary | ||||
|     #[serde(rename = "bond-primary")] | ||||
|     bond_primary, | ||||
| } | ||||
|  | ||||
|  | ||||
| @ -420,6 +436,10 @@ pub enum DeletableProperty { | ||||
|                 type: LinuxBondMode, | ||||
|                 optional: true, | ||||
|             }, | ||||
|             "bond-primary": { | ||||
|                 schema: NETWORK_INTERFACE_NAME_SCHEMA, | ||||
|                 optional: true, | ||||
|             }, | ||||
|             slaves: { | ||||
|                 schema: NETWORK_INTERFACE_LIST_SCHEMA, | ||||
|                 optional: true, | ||||
| @ -458,6 +478,7 @@ pub fn update_interface( | ||||
|     bridge_ports: Option<String>, | ||||
|     bridge_vlan_aware: Option<bool>, | ||||
|     bond_mode: Option<LinuxBondMode>, | ||||
|     bond_primary: Option<String>, | ||||
|     slaves: Option<String>, | ||||
|     delete: Option<Vec<DeletableProperty>>, | ||||
|     digest: Option<String>, | ||||
| @ -501,6 +522,7 @@ pub fn update_interface( | ||||
|                 DeletableProperty::bridge_ports => { interface.set_bridge_ports(Vec::new())?; } | ||||
|                 DeletableProperty::bridge_vlan_aware => { interface.bridge_vlan_aware = None; } | ||||
|                 DeletableProperty::slaves => { interface.set_bond_slaves(Vec::new())?; } | ||||
|                 DeletableProperty::bond_primary => { interface.bond_primary = None; } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| @ -518,7 +540,15 @@ pub fn update_interface( | ||||
|         let slaves = split_interface_list(&slaves)?; | ||||
|         interface.set_bond_slaves(slaves)?; | ||||
|     } | ||||
|     if bond_mode.is_some() { interface.bond_mode = bond_mode; } | ||||
|     if let Some(mode) = bond_mode { | ||||
|         interface.bond_mode = bond_mode; | ||||
|         if bond_primary.is_some() { | ||||
|             if mode != LinuxBondMode::active_backup { | ||||
|                 bail!("bond-primary is only valid with Active/Backup mode"); | ||||
|             } | ||||
|             interface.bond_primary = bond_primary; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     if let Some(cidr) = cidr { | ||||
|         let (_, _, is_v6) = network::parse_cidr(&cidr)?; | ||||
|  | ||||
| @ -812,7 +812,11 @@ pub const NETWORK_INTERFACE_LIST_SCHEMA: Schema = StringSchema::new( | ||||
|         bond_mode: { | ||||
|             type: LinuxBondMode, | ||||
|             optional: true, | ||||
|         } | ||||
|         }, | ||||
|         "bond-primary": { | ||||
|             schema: NETWORK_INTERFACE_NAME_SCHEMA, | ||||
|             optional: true, | ||||
|         }, | ||||
|     } | ||||
| )] | ||||
| #[derive(Debug, Serialize, Deserialize)] | ||||
| @ -869,6 +873,9 @@ pub struct Interface { | ||||
|     pub slaves: Option<Vec<String>>, | ||||
|     #[serde(skip_serializing_if="Option::is_none")] | ||||
|     pub bond_mode: Option<LinuxBondMode>, | ||||
|     #[serde(skip_serializing_if="Option::is_none")] | ||||
|     #[serde(rename = "bond-primary")] | ||||
|     pub bond_primary: Option<String>, | ||||
| } | ||||
|  | ||||
| // Regression tests | ||||
|  | ||||
| @ -67,6 +67,7 @@ impl Interface { | ||||
|             bridge_vlan_aware: None, | ||||
|             slaves: None, | ||||
|             bond_mode: None, | ||||
|             bond_primary: None, | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @ -169,6 +170,11 @@ impl Interface { | ||||
|             NetworkInterfaceType::Bond => { | ||||
|                 let mode = self.bond_mode.unwrap_or(LinuxBondMode::balance_rr); | ||||
|                 writeln!(w, "\tbond-mode {}", bond_mode_to_str(mode))?; | ||||
|                 if let Some(primary) = &self.bond_primary { | ||||
|                     if mode == LinuxBondMode::active_backup { | ||||
|                         writeln!(w, "\tbond-primary {}", primary)?; | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
|                 let slaves = self.slaves.as_ref().unwrap_or(&EMPTY_LIST); | ||||
|                 if slaves.is_empty() { | ||||
|  | ||||
| @ -26,6 +26,7 @@ pub enum Token { | ||||
|     BridgeVlanAware, | ||||
|     BondSlaves, | ||||
|     BondMode, | ||||
|     BondPrimary, | ||||
|     EOF, | ||||
| } | ||||
|  | ||||
| @ -51,7 +52,8 @@ lazy_static! { | ||||
|         map.insert("bond-slaves", Token::BondSlaves); | ||||
|         map.insert("bond_slaves", Token::BondSlaves); | ||||
|         map.insert("bond-mode", Token::BondMode); | ||||
|         map.insert("bond_mode", Token::BondMode); | ||||
|         map.insert("bond-primary", Token::BondPrimary); | ||||
|         map.insert("bond_primary", Token::BondPrimary); | ||||
|         map | ||||
|     }; | ||||
| } | ||||
|  | ||||
| @ -243,6 +243,12 @@ impl <R: BufRead> NetworkParser<R> { | ||||
|                     interface.bond_mode = Some(bond_mode_from_str(&mode)?); | ||||
|                     self.eat(Token::Newline)?; | ||||
|                 } | ||||
|                 Token::BondPrimary => { | ||||
|                     self.eat(Token::BondPrimary)?; | ||||
|                     let primary = self.next_text()?; | ||||
|                     interface.bond_primary = Some(primary); | ||||
|                     self.eat(Token::Newline)?; | ||||
|                 } | ||||
|                 Token::Netmask => bail!("netmask is deprecated and no longer supported"), | ||||
|  | ||||
|                 _ => { // parse addon attributes | ||||
|  | ||||
		Reference in New Issue
	
	Block a user