Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package agama for openSUSE:Factory checked 
in at 2025-06-11 16:24:07
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/agama (Old)
 and      /work/SRC/openSUSE:Factory/.agama.new.19631 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "agama"

Wed Jun 11 16:24:07 2025 rev:21 rq:1284539 version:0

Changes:
--------
--- /work/SRC/openSUSE:Factory/agama/agama.changes      2025-05-27 
18:43:16.415286509 +0200
+++ /work/SRC/openSUSE:Factory/.agama.new.19631/agama.changes   2025-06-11 
16:25:58.163079938 +0200
@@ -1,0 +2,12 @@
+Tue Jun  3 08:35:58 UTC 2025 - Knut Anderssen <kanders...@suse.com>
+
+- Added support for moving the connections from memory only to disk
+  (gh#agama-project/agama#2402).
+
+-------------------------------------------------------------------
+Wed May 28 09:00:00 UTC 2025 - Clemens Famulla-Conrad <cfamullacon...@suse.com>
+
+- Fix bridge port config (bridge-port.priority and 
+  brdige-port.path_cost)
+
+-------------------------------------------------------------------

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ agama.obscpio ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/agama/agama-network/src/model.rs 
new/agama/agama-network/src/model.rs
--- old/agama/agama-network/src/model.rs        2025-05-27 09:55:53.000000000 
+0200
+++ new/agama/agama-network/src/model.rs        2025-06-03 17:34:25.000000000 
+0200
@@ -463,6 +463,7 @@
 pub struct GeneralState {
     pub hostname: String,
     pub connectivity: bool,
+    pub copy_network: bool,
     pub wireless_enabled: bool,
     pub networking_enabled: bool, // pub network_state: NMSTATE
 }
@@ -520,6 +521,9 @@
     pub ieee_8021x_config: Option<IEEE8021XConfig>,
     pub autoconnect: bool,
     pub state: ConnectionState,
+    pub keep: bool,
+    pub filename: String,
+    pub flags: u32,
 }
 
 impl Connection {
@@ -552,10 +556,19 @@
         self.status == Status::Up
     }
 
+    pub fn is_down(&self) -> bool {
+        self.status == Status::Down
+    }
+
     pub fn set_up(&mut self) {
         self.status = Status::Up
     }
 
+    pub fn set_keep(&mut self, keep: bool) {
+        self.keep = keep;
+        self.status = Status::Keep
+    }
+
     pub fn set_down(&mut self) {
         self.status = Status::Down
     }
@@ -593,6 +606,9 @@
             ieee_8021x_config: Default::default(),
             autoconnect: true,
             state: Default::default(),
+            keep: true,
+            filename: Default::default(),
+            flags: Default::default(),
         }
     }
 }
@@ -648,6 +664,7 @@
         connection.interface = conn.interface;
         connection.mtu = conn.mtu;
         connection.autoconnect = conn.autoconnect;
+        connection.keep = conn.keep;
 
         Ok(connection)
     }
@@ -675,6 +692,8 @@
             .ieee_8021x_config
             .and_then(|x| IEEE8021XSettings::try_from(x).ok());
         let autoconnect = conn.autoconnect;
+        let keep = conn.keep;
+        let filename = Some(conn.filename);
 
         let mut connection = NetworkConnection {
             id,
@@ -692,6 +711,8 @@
             mtu,
             ieee_8021x,
             autoconnect,
+            keep,
+            filename,
             ..Default::default()
         };
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/agama/agama-network/src/nm/adapter.rs 
new/agama/agama-network/src/nm/adapter.rs
--- old/agama/agama-network/src/nm/adapter.rs   2025-05-27 09:55:53.000000000 
+0200
+++ new/agama/agama-network/src/nm/adapter.rs   2025-06-03 17:34:25.000000000 
+0200
@@ -111,7 +111,6 @@
             .map_err(|e| NetworkAdapterError::Checkpoint(anyhow!(e)))?;
 
         tracing::info!("Updating the general state {:?}", 
&network.general_state);
-
         let result = self
             .client
             .update_general_state(&network.general_state)
@@ -134,6 +133,11 @@
         for conn in ordered_connections(network) {
             if let Some(old_conn) = 
old_state.get_connection_by_uuid(conn.uuid) {
                 if old_conn == conn {
+                    tracing::info!(
+                        "No change detected for connection {} ({})",
+                        conn.id,
+                        conn.uuid
+                    );
                     continue;
                 }
             } else if conn.is_removed() {
@@ -194,8 +198,11 @@
     conns: &mut Vec<&'b Connection>,
 ) {
     if let Some(uuid) = conn.controller {
-        let controller = network.get_connection_by_uuid(uuid).unwrap();
-        add_ordered_connections(controller, network, conns);
+        if let Some(controller) = network.get_connection_by_uuid(uuid) {
+            add_ordered_connections(controller, network, conns);
+        } else {
+            tracing::error!("Could not found the controller {}", &uuid);
+        }
     }
 
     if !conns.contains(&conn) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/agama/agama-network/src/nm/client.rs 
new/agama/agama-network/src/nm/client.rs
--- old/agama/agama-network/src/nm/client.rs    2025-05-27 09:55:53.000000000 
+0200
+++ new/agama/agama-network/src/nm/client.rs    2025-06-03 17:34:25.000000000 
+0200
@@ -20,6 +20,8 @@
 
 //! NetworkManager client.
 use std::collections::HashMap;
+use std::fs::{self, OpenOptions};
+use std::path::Path;
 
 use super::builder::DeviceFromProxyBuilder;
 use super::dbus::{
@@ -70,18 +72,21 @@
         // let global_dns_configuration = 
self.nm_proxy.global_dns_configuration().await?;
         // Fixme: save as NMConnectivityState enum
         let connectivity = self.nm_proxy.connectivity().await? == 4;
+        let copy_network = !Path::new("/run/agama/not_copy_network").exists();
 
         Ok(GeneralState {
             hostname,
             wireless_enabled,
             networking_enabled,
             connectivity,
+            copy_network,
         })
     }
 
     /// Updates the general state
     pub async fn update_general_state(&self, state: &GeneralState) -> 
Result<(), NmError> {
         let wireless_enabled = self.nm_proxy.wireless_enabled().await?;
+        let copy_network = !Path::new("/run/agama/not_copy_network").exists();
 
         if wireless_enabled != state.wireless_enabled {
             self.nm_proxy
@@ -89,6 +94,19 @@
                 .await?;
         };
 
+        if copy_network != state.copy_network {
+            let path = Path::new("/run/agama/not_copy_network");
+            if state.copy_network {
+                if let Err(error) = fs::remove_file(path) {
+                    tracing::error!("Cannot remove /run/agama/not_copy_network 
file {:?}", error);
+                }
+            } else {
+                if let Err(error) = 
OpenOptions::new().create(true).write(true).open(path) {
+                    tracing::error!("Cannot write /run/agama/not_copy_network 
file {:?}", error);
+                }
+            };
+        };
+
         Ok(())
     }
 
@@ -182,7 +200,7 @@
     /// Returns the list of network connections.
     pub async fn connections(&self) -> Result<Vec<Connection>, NmError> {
         let mut controlled_by: HashMap<Uuid, String> = HashMap::new();
-        let mut uuids_map: HashMap<Uuid, String> = HashMap::new();
+        let mut uuids_map: HashMap<String, Uuid> = HashMap::new();
 
         let proxy = SettingsProxy::new(&self.connection).await?;
         let paths = proxy.list_connections().await?;
@@ -213,11 +231,15 @@
                     }
 
                     Self::add_secrets(&mut connection.config, &proxy).await?;
+                    connection.filename = proxy.filename().await?;
+                    connection.flags = flags;
+                    connection.keep = if flags != 0 { false } else { true };
+
                     if let Some(controller) = controller {
                         controlled_by.insert(connection.uuid, controller);
                     }
                     if let Some(iname) = &connection.interface {
-                        uuids_map.insert(connection.uuid, iname.to_string());
+                        uuids_map.insert(iname.to_string(), connection.uuid);
                     }
                     if self.settings_active_connection(path).await?.is_none() {
                         connection.set_down()
@@ -231,8 +253,11 @@
         }
 
         for conn in connections.iter_mut() {
-            if controlled_by.contains_key(&conn.uuid) {
-                conn.controller = Some(conn.uuid);
+            // FIXME: Is this OK?
+            if let Some(controller) = controlled_by.get(&conn.uuid) {
+                if let Some(iface) = uuids_map.get(controller) {
+                    conn.controller = Some(iface.to_owned());
+                }
             };
         }
 
@@ -266,18 +291,33 @@
         let path = if let Ok(proxy) = 
self.get_connection_proxy(conn.uuid).await {
             let original = proxy.get_settings().await?;
             let merged = merge_dbus_connections(&original, &new_conn)?;
-            proxy.update(merged).await?;
+            // 
https://networkmanager.dev/docs/api/latest/nm-dbus-types.html#NMSettingsConnectionFlags
+            // 0x1 persist to disk, 0x8 memory only
+            let persist = if conn.keep { 0x1 } else { 0x8 };
+            proxy.update2(merged, persist, Default::default()).await?;
             OwnedObjectPath::from(proxy.inner().path().to_owned())
         } else {
             let proxy = SettingsProxy::new(&self.connection).await?;
+            // 
https://networkmanager.dev/docs/api/latest/nm-dbus-types.html#NMSettingsConnectionFlags
+            // 0x1 persist to disk, 0x2 memory only
+            let persist = if conn.keep { 0x1 } else { 0x2 };
             cleanup_dbus_connection(&mut new_conn);
-            proxy.add_connection(new_conn).await?
+            let (path, _) = proxy
+                .add_connection2(new_conn, persist, Default::default())
+                .await?;
+            path
         };
 
+        // FIXME: Do not like that an activation/deactivation could not apply 
the changes because of
+        // a roolback when calling this method with an error.
         if conn.is_up() {
+            // FIXME: If it is a wireless and wireless is disabled it will 
fail, and if it is a
+            // device which is not available it will also fail.
             self.activate_connection(path).await?;
         } else {
-            self.deactivate_connection(path).await?;
+            if conn.is_down() || conn.is_removed() {
+                self.deactivate_connection(path).await?;
+            }
         }
         Ok(())
     }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/agama/agama-network/src/nm/dbus.rs 
new/agama/agama-network/src/nm/dbus.rs
--- old/agama/agama-network/src/nm/dbus.rs      2025-05-27 09:55:53.000000000 
+0200
+++ new/agama/agama-network/src/nm/dbus.rs      2025-06-03 17:34:25.000000000 
+0200
@@ -260,11 +260,11 @@
     Ok(merged)
 }
 
-fn is_bridge(conn: NestedHash) -> bool {
+fn is_bridge_port(conn: &NestedHash) -> bool {
     if let Some(connection) = conn.get("connection") {
         if let Some(port_type) = connection.get("port-type") {
-            if port_type.to_string().as_str() == "bridge" {
-                return true;
+            if let Ok(s) = TryInto::<&str>::try_into(port_type) {
+                return s == "bridge";
             }
         }
     }
@@ -284,7 +284,7 @@
 ///
 /// * `conn`: connection represented as a NestedHash.
 pub fn cleanup_dbus_connection(conn: &mut NestedHash) {
-    if !is_bridge(conn.to_owned()) {
+    if !is_bridge_port(conn) {
         conn.remove("bridge-port");
     }
 
@@ -1595,7 +1595,6 @@
 
     #[test]
     fn test_connection_from_dbus_bridge() -> anyhow::Result<()> {
-        dbg!("TESTING BRIDGE");
         let uuid = Uuid::new_v4().to_string();
         let connection_section = HashMap::from([hi("id", "br0")?, hi("uuid", 
uuid)?]);
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/agama/agama-network/src/settings.rs 
new/agama/agama-network/src/settings.rs
--- old/agama/agama-network/src/settings.rs     2025-05-27 09:55:53.000000000 
+0200
+++ new/agama/agama-network/src/settings.rs     2025-06-03 17:34:25.000000000 
+0200
@@ -262,6 +262,11 @@
     /// Specifies if the connection should automatically connect
     #[serde(default = "default_true")]
     pub autoconnect: bool,
+    /// Specifies whether the connection should be keep after the installation
+    #[serde(default = "default_true")]
+    pub keep: bool,
+    #[serde(skip_serializing_if = "Option::is_none")]
+    pub filename: Option<String>,
 }
 
 fn is_zero<T: PartialEq + From<u16>>(u: &T) -> bool {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/agama/agama-network/src/system.rs 
new/agama/agama-network/src/system.rs
--- old/agama/agama-network/src/system.rs       2025-05-27 09:55:53.000000000 
+0200
+++ new/agama/agama-network/src/system.rs       2025-06-03 17:34:25.000000000 
+0200
@@ -427,7 +427,12 @@
     /// Writes the network configuration.
     pub async fn write(&mut self) -> Result<(), NetworkAdapterError> {
         self.adapter.write(&self.state).await?;
-        self.state = self.adapter.read(StateConfig::default()).await?;
+        self.state = self
+            .adapter
+            .read(StateConfig {
+                ..Default::default()
+            })
+            .await?;
         Ok(())
     }
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/agama/agama-network/src/types.rs 
new/agama/agama-network/src/types.rs
--- old/agama/agama-network/src/types.rs        2025-05-27 09:55:53.000000000 
+0200
+++ new/agama/agama-network/src/types.rs        2025-06-03 17:34:25.000000000 
+0200
@@ -150,6 +150,8 @@
     Up,
     Down,
     Removed,
+    // Workaound for not modify the connection status
+    Keep,
 }
 
 impl fmt::Display for Status {
@@ -157,6 +159,7 @@
         let name = match &self {
             Status::Up => "up",
             Status::Down => "down",
+            Status::Keep => "keep",
             Status::Removed => "removed",
         };
         write!(f, "{}", name)
@@ -174,6 +177,7 @@
         match value {
             "up" => Ok(Status::Up),
             "down" => Ok(Status::Down),
+            "keep" => Ok(Status::Keep),
             "removed" => Ok(Status::Removed),
             _ => Err(InvalidStatus(value.to_string())),
         }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/agama/agama-server/src/network/web.rs 
new/agama/agama-server/src/network/web.rs
--- old/agama/agama-server/src/network/web.rs   2025-05-27 09:55:53.000000000 
+0200
+++ new/agama/agama-server/src/network/web.rs   2025-06-03 17:34:25.000000000 
+0200
@@ -27,7 +27,7 @@
     extract::{Path, State},
     http::StatusCode,
     response::{IntoResponse, Response},
-    routing::{delete, get, patch, post},
+    routing::{delete, get, post},
     Json, Router,
 };
 use uuid::Uuid;
@@ -121,8 +121,10 @@
                 .put(update_connection)
                 .get(connection),
         )
-        .route("/connections/:id/connect", patch(connect))
-        .route("/connections/:id/disconnect", patch(disconnect))
+        .route("/connections/:id/connect", post(connect))
+        .route("/connections/:id/disconnect", post(disconnect))
+        .route("/connections/:id/keep", post(keep))
+        .route("/connections/:id/unkeep", post(unkeep))
         .route("/devices", get(devices))
         .route("/system/apply", post(apply))
         .route("/wifi", get(wifi_networks))
@@ -214,6 +216,7 @@
 
     let network_connections = connections
         .iter()
+        .filter(|c| c.controller.is_none())
         .map(|c| {
             let state = c.state;
             let mut conn = NetworkConnection::try_from(c.clone()).unwrap();
@@ -344,12 +347,8 @@
     let bridge = conn.bridge.clone();
 
     let mut conn = Connection::try_from(conn)?;
-    if orig_conn.id != id {
-        // FIXME: why?
-        return Err(NetworkError::UnknownConnection(id));
-    } else {
-        conn.uuid = orig_conn.uuid;
-    }
+    conn.uuid = orig_conn.uuid;
+    conn.filename = orig_conn.filename;
 
     state.network.update_connection(conn.clone()).await?;
 
@@ -364,7 +363,7 @@
 }
 
 #[utoipa::path(
-    patch,
+    post,
     path = "/connections/:id/connect",
     context_path = "/api/network",
     responses(
@@ -396,7 +395,7 @@
 }
 
 #[utoipa::path(
-    patch,
+    post,
     path = "/connections/:id/disconnect",
     context_path = "/api/network",
     responses(
@@ -420,6 +419,100 @@
 
     state
         .network
+        .apply()
+        .await
+        .map_err(|_| NetworkError::CannotApplyConfig)?;
+
+    Ok(StatusCode::NO_CONTENT)
+}
+
+#[utoipa::path(
+    post,
+    path = "/connections/:id/keep",
+    context_path = "/api/network",
+    responses(
+      (status = 204, description = "Keep the given connection after the 
installation", body = String)
+    )
+)]
+async fn keep(
+    State(state): State<NetworkServiceState>,
+    Path(id): Path<String>,
+) -> Result<impl IntoResponse, NetworkError> {
+    if id == "all" {
+        let mut connections = state.network.get_connections().await?;
+
+        for conn in connections.iter_mut() {
+            conn.set_keep(true);
+
+            state
+                .network
+                .update_connection(conn.to_owned())
+                .await
+                .map_err(|_| NetworkError::CannotApplyConfig)?;
+        }
+    } else {
+        let Some(mut conn) = state.network.get_connection(&id).await? else {
+            return Err(NetworkError::UnknownConnection(id));
+        };
+
+        conn.set_keep(true);
+
+        state
+            .network
+            .update_connection(conn)
+            .await
+            .map_err(|_| NetworkError::CannotApplyConfig)?;
+    }
+
+    state
+        .network
+        .apply()
+        .await
+        .map_err(|_| NetworkError::CannotApplyConfig)?;
+
+    Ok(StatusCode::NO_CONTENT)
+}
+
+#[utoipa::path(
+    post,
+    path = "/connections/:id/unkeep",
+    context_path = "/api/network",
+    responses(
+      (status = 204, description = "Do not keep the given connection after the 
installation", body = String)
+    )
+)]
+async fn unkeep(
+    State(state): State<NetworkServiceState>,
+    Path(id): Path<String>,
+) -> Result<impl IntoResponse, NetworkError> {
+    if id == "all" {
+        let mut connections = state.network.get_connections().await?;
+
+        for conn in connections.iter_mut() {
+            conn.set_keep(false);
+
+            state
+                .network
+                .update_connection(conn.to_owned())
+                .await
+                .map_err(|_| NetworkError::CannotApplyConfig)?;
+        }
+    } else {
+        let Some(mut conn) = state.network.get_connection(&id).await? else {
+            return Err(NetworkError::UnknownConnection(id));
+        };
+
+        conn.set_keep(false);
+
+        state
+            .network
+            .update_connection(conn)
+            .await
+            .map_err(|_| NetworkError::CannotApplyConfig)?;
+    }
+
+    state
+        .network
         .apply()
         .await
         .map_err(|_| NetworkError::CannotApplyConfig)?;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/agama/agama-server/tests/network_service.rs 
new/agama/agama-server/tests/network_service.rs
--- old/agama/agama-server/tests/network_service.rs     2025-05-27 
09:55:53.000000000 +0200
+++ new/agama/agama-server/tests/network_service.rs     2025-06-03 
17:34:25.000000000 +0200
@@ -232,7 +232,6 @@
     let response = network_service.clone().oneshot(request).await?;
     assert_eq!(response.status(), StatusCode::OK);
     let body = body_to_string(response.into_body()).await;
-    assert!(body.contains(r#""id":"eth0""#));
     assert!(body.contains(r#""id":"bond0""#));
     assert!(body.contains(r#""mode":"active-backup""#));
     assert!(body.contains(r#""primary=eth0""#));
@@ -278,7 +277,6 @@
     let response = network_service.clone().oneshot(request).await?;
     assert_eq!(response.status(), StatusCode::OK);
     let body = body_to_string(response.into_body()).await;
-    assert!(body.contains(r#""id":"eth0""#));
     assert!(body.contains(r#""id":"br0""#));
     assert!(body.contains(r#""ports":["eth0"]"#));
     assert!(body.contains(r#""stp":false"#));
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/agama/package/agama.changes 
new/agama/package/agama.changes
--- old/agama/package/agama.changes     2025-05-27 09:55:53.000000000 +0200
+++ new/agama/package/agama.changes     2025-06-03 17:34:25.000000000 +0200
@@ -1,4 +1,16 @@
 -------------------------------------------------------------------
+Tue Jun  3 08:35:58 UTC 2025 - Knut Anderssen <kanders...@suse.com>
+
+- Added support for moving the connections from memory only to disk
+  (gh#agama-project/agama#2402).
+
+-------------------------------------------------------------------
+Wed May 28 09:00:00 UTC 2025 - Clemens Famulla-Conrad <cfamullacon...@suse.com>
+
+- Fix bridge port config (bridge-port.priority and 
+  brdige-port.path_cost)
+
+-------------------------------------------------------------------
 Mon May 26 19:51:52 UTC 2025 - Imobach Gonzalez Sosa <igonzalezs...@suse.com>
 
 - Version 15

++++++ agama.obsinfo ++++++
--- /var/tmp/diff_new_pack.ExBfSR/_old  2025-06-11 16:25:59.607140198 +0200
+++ /var/tmp/diff_new_pack.ExBfSR/_new  2025-06-11 16:25:59.611140365 +0200
@@ -1,5 +1,5 @@
 name: agama
-version: 15+6.b2172efdc
-mtime: 1748332553
-commit: b2172efdc433f1c573c639dcfc38102fac18fbfe
+version: 15+54.8e10affb2
+mtime: 1748964865
+commit: 8e10affb228ff198651e5338d8ad91b481a86be0
 

Reply via email to