From b9e789fbb5aa3302b91be80a1a8b43b1bfa18fc0 Mon Sep 17 00:00:00 2001 From: Knut Anderssen Date: Fri, 17 Nov 2023 23:31:04 +0000 Subject: [PATCH] Bond schema and settings --- .../src/network/dbus/interfaces.rs | 36 ++++++++++++++++--- rust/agama-lib/share/examples/profile.jsonnet | 8 +++++ rust/agama-lib/share/profile.schema.json | 18 ++++++++++ rust/agama-lib/src/network/client.rs | 27 ++++++++++++-- rust/agama-lib/src/network/proxies.rs | 4 +-- 5 files changed, 84 insertions(+), 9 deletions(-) diff --git a/rust/agama-dbus-server/src/network/dbus/interfaces.rs b/rust/agama-dbus-server/src/network/dbus/interfaces.rs index 454a7ee5a1..304a5c5167 100644 --- a/rust/agama-dbus-server/src/network/dbus/interfaces.rs +++ b/rust/agama-dbus-server/src/network/dbus/interfaces.rs @@ -2,6 +2,8 @@ //! //! This module contains the set of D-Bus interfaces that are exposed by [D-Bus network //! service](crate::NetworkService). +use std::collections::HashMap; + use super::ObjectsRegistry; use crate::network::{ action::Action, @@ -318,14 +320,14 @@ impl Bond { async fn update_controller_connection<'a>( &self, connection: MappedMutexGuard<'a, NetworkConnection, BondConnection>, - ports: Vec, + settings: HashMap, ) -> zbus::fdo::Result<()> { let actions = self.actions.lock().await; let connection = NetworkConnection::Bond(connection.clone()); actions .send(Action::UpdateControllerConnection( connection.clone(), - ports.clone(), + settings, )) .await .unwrap(); @@ -333,8 +335,33 @@ impl Bond { } } +enum BondSettings { + Ports(Vec), + Options(String), +} + #[dbus_interface(name = "org.opensuse.Agama1.Network.Connection.Bond")] impl Bond { + /// List of bond ports. + #[dbus_interface(property)] + pub async fn options(&self) -> String { + let connection = self.get_bond().await; + let mut opts = vec![]; + for (key, value) in &connection.bond.options { + opts.push(format!("{key}={value}")); + } + + opts.join(" ") + } + + #[dbus_interface(property)] + pub async fn set_options(&self, opts: String) -> zbus::fdo::Result<()> { + let connection = self.get_bond().await; + + self.update_controller_connection(connection, HashMap::from(["options", opts.clone()])) + .await + } + /// List of bond ports. #[dbus_interface(property)] pub async fn ports(&self) -> Vec { @@ -350,7 +377,7 @@ impl Bond { #[dbus_interface(property)] pub async fn set_ports(&mut self, ports: Vec) -> zbus::fdo::Result<()> { let connection = self.get_bond().await; - self.update_controller_connection(connection, ports.clone()) + self.update_controller_connection(connection, HashMap::from(["ports", ports.clone()])) .await } } @@ -536,7 +563,6 @@ impl Wireless { connection.wireless.security = security .try_into() .map_err(|_| NetworkStateError::InvalidSecurityProtocol(security.to_string()))?; - self.update_connection(connection).await?; - Ok(()) + self.update_connection(connection).await } } diff --git a/rust/agama-lib/share/examples/profile.jsonnet b/rust/agama-lib/share/examples/profile.jsonnet index cd6b63f5bf..e5ae5d01aa 100644 --- a/rust/agama-lib/share/examples/profile.jsonnet +++ b/rust/agama-lib/share/examples/profile.jsonnet @@ -63,6 +63,14 @@ local findBiggestDisk(disks) = match: { path: ["pci-0000:00:19.0"] } + }, + { + id: 'bond0', + bond: { + ports: ['eth0', 'eth1'], + options: "mode=active-backup primary=eth1" + + } } ] } diff --git a/rust/agama-lib/share/profile.schema.json b/rust/agama-lib/share/profile.schema.json index 2d9cb33b0a..fa24143bdf 100644 --- a/rust/agama-lib/share/profile.schema.json +++ b/rust/agama-lib/share/profile.schema.json @@ -105,6 +105,24 @@ } } }, + "bond": { + "type": "object", + "description": "Bonding configuration", + "additionalProperties": false, + "properties": { + "options": { + "type": "string" + }, + "ports": { + "type": "array", + "items": { + "description": "A list of the ports to be bonded", + "type": "string", + "additionalProperties": false + } + } + } + }, "match": { "type": "object", "description": "Match settings", diff --git a/rust/agama-lib/src/network/client.rs b/rust/agama-lib/src/network/client.rs index 660d97d824..837fe7e02f 100644 --- a/rust/agama-lib/src/network/client.rs +++ b/rust/agama-lib/src/network/client.rs @@ -1,8 +1,8 @@ use super::proxies::{ - ConnectionProxy, ConnectionsProxy, DeviceProxy, DevicesProxy, IPProxy, MatchProxy, + BondProxy, ConnectionProxy, ConnectionsProxy, DeviceProxy, DevicesProxy, IPProxy, MatchProxy, WirelessProxy, }; -use super::settings::{MatchSettings, NetworkConnection, WirelessSettings}; +use super::settings::{BondSettings, MatchSettings, NetworkConnection, WirelessSettings}; use super::types::{Device, DeviceType, SSID}; use crate::error::ServiceError; use tokio_stream::StreamExt; @@ -226,6 +226,10 @@ impl<'a> NetworkClient<'a> { self.update_ip_settings(path, conn).await?; + if let Some(ref bond) = conn.bond { + self.update_bond_settings(path, bond).await?; + } + if let Some(ref wireless) = conn.wireless { self.update_wireless_settings(path, wireless).await?; } @@ -276,6 +280,25 @@ impl<'a> NetworkClient<'a> { Ok(()) } + /// Updates the bond settings for network connection. + /// + /// * `path`: connection D-Bus path. + /// * `bond`: bond settings of the network connection. + async fn update_bond_settings( + &self, + path: &OwnedObjectPath, + bond: &BondSettings, + ) -> Result<(), ServiceError> { + let proxy = BondProxy::builder(&self.connection) + .path(path)? + .build() + .await?; + + let ports: Vec<_> = bond.ports.iter().map(String::as_ref).collect(); + proxy.set_ports(ports.as_slice()).await?; + proxy.set_options(bond.options.to_string().as_str()).await?; + Ok(()) + } /// Updates the wireless settings for network connection. /// /// * `path`: connection D-Bus path. diff --git a/rust/agama-lib/src/network/proxies.rs b/rust/agama-lib/src/network/proxies.rs index 207a45dfa5..84335b6996 100644 --- a/rust/agama-lib/src/network/proxies.rs +++ b/rust/agama-lib/src/network/proxies.rs @@ -193,9 +193,9 @@ trait Bond { /// ports property #[dbus_proxy(property)] - fn options(&self) -> zbus::Result>; + fn options(&self) -> zbus::Result; #[dbus_proxy(property)] - fn set_options(&self, value: &[&str]) -> zbus::Result<()>; + fn set_options(&self, value: &str) -> zbus::Result<()>; /// ports property #[dbus_proxy(property)]