Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package agama for openSUSE:Factory checked 
in at 2026-07-17 18:47:24
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/agama (Old)
 and      /work/SRC/openSUSE:Factory/.agama.new.24530 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "agama"

Fri Jul 17 18:47:24 2026 rev:50 rq:1366193 version:0

Changes:
--------
--- /work/SRC/openSUSE:Factory/agama/agama.changes      2026-07-15 
16:29:51.994467897 +0200
+++ /work/SRC/openSUSE:Factory/.agama.new.24530/agama.changes   2026-07-17 
18:47:46.869815176 +0200
@@ -1,0 +2,27 @@
+Thu Jul 16 11:26:26 UTC 2026 - Imobach Gonzalez Sosa <[email protected]>
+
+- Limit the number of Tokio worker threads to 4
+  (gh#agama-project/agama#3729, related to bsc#1265451).
+
+-------------------------------------------------------------------  
+Thu Jul 16 11:01:05 UTC 2026 - Michal Filka <[email protected]>
+
+- Fixed issues when fetching AutoYast XML profile.
+  Agama cares about YAST_SKIP_PROFILE_FETCH_ERROR now.
+  agama-autoyast doesn't end with error when no profile found.
+
+-------------------------------------------------------------------
+Wed Jul 15 10:13:10 UTC 2026 - Imobach Gonzalez Sosa <[email protected]>
+
+- Do not crash when running "lshw" fails or the output cannot be
+  parsed (bsc#1269367).
+- Fix the detection of model and CPU in s390x (bsc#1270639).
+- Fix the detection of the memory when lshw does not report a
+  node with id "memory", but "memory:0" (bsc#1271190).
+
+-------------------------------------------------------------------
+Wed Jul 15 09:16:44 UTC 2026 - Josef Reidinger <[email protected]>
+
+- Fix setting security kernel parameter (bsc#1269581)
+
+-------------------------------------------------------------------

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

Other differences:
------------------
++++++ agama.obscpio ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/agama/agama-bootloader/src/client.rs 
new/agama/agama-bootloader/src/client.rs
--- old/agama/agama-bootloader/src/client.rs    2026-07-14 10:45:10.000000000 
+0200
+++ new/agama/agama-bootloader/src/client.rs    2026-07-16 14:18:35.000000000 
+0200
@@ -50,12 +50,16 @@
     /// Retrieves the bootloader resolvables.
     async fn get_resolvables(&self) -> ClientResult<Vec<Resolvable>>;
     /// Sets the bootloader configuration.
-    async fn set_config(&self, config: &Config) -> 
ClientResult<BoxFuture<Result<(), Error>>>;
+    async fn set_config(&mut self, config: &Config) -> 
ClientResult<BoxFuture<Result<(), Error>>>;
     /// Sets the extra kernel args for given scope.
     ///
     /// * `id`: identifier of the kernel argument so it can be later changed.
     /// * `value`: plaintext value that will be appended to kernel commandline.
-    async fn set_kernel_arg(&mut self, id: String, value: String);
+    async fn set_kernel_arg(
+        &mut self,
+        id: String,
+        value: String,
+    ) -> ClientResult<BoxFuture<Result<(), Error>>>;
 }
 
 // full config used on dbus which beside public config passes
@@ -74,16 +78,30 @@
 #[derive(Clone)]
 pub struct Client {
     storage_client: Handler<storage_client::Service>,
-    kernel_args: HashMap<String, String>,
+    // full config, so we can replace only modified part
+    full_config: FullConfig,
 }
 
 impl Client {
     pub async fn new(storage_client: Handler<storage_client::Service>) -> 
ClientResult<Client> {
         Ok(Self {
             storage_client,
-            kernel_args: HashMap::new(),
+            full_config: FullConfig::default(),
         })
     }
+
+    async fn send_config(&self) -> ClientResult<BoxFuture<Result<(), Error>>> {
+        let full_config = self.full_config.clone();
+        tracing::info!("sending bootloader config {:?}", full_config);
+        // ignore return value as currently it does not fail and who knows 
what future brings
+        // but it should not be part of result and instead transformed to Issue
+        let value = serde_json::to_value(&full_config)?;
+        let rx = self
+            .storage_client
+            .call(message::bootloader::SetConfig::new(value))
+            .await?;
+        Ok(Box::pin(async move { rx.await.map_err(Error::from) }))
+    }
 }
 
 #[async_trait]
@@ -109,23 +127,17 @@
             .await?)
     }
 
-    async fn set_config(&self, config: &Config) -> 
ClientResult<BoxFuture<Result<(), Error>>> {
-        let full_config = FullConfig {
-            config: config.clone(),
-            kernel_args: self.kernel_args.clone(),
-        };
-        tracing::info!("sending bootloader config {:?}", full_config);
-        // ignore return value as currently it does not fail and who knows 
what future brings
-        // but it should not be part of result and instead transformed to Issue
-        let value = serde_json::to_value(&full_config)?;
-        let rx = self
-            .storage_client
-            .call(message::bootloader::SetConfig::new(value))
-            .await?;
-        Ok(Box::pin(async move { rx.await.map_err(Error::from) }))
+    async fn set_config(&mut self, config: &Config) -> 
ClientResult<BoxFuture<Result<(), Error>>> {
+        self.full_config.config = config.clone();
+        self.send_config().await
     }
 
-    async fn set_kernel_arg(&mut self, id: String, value: String) {
-        self.kernel_args.insert(id, value);
+    async fn set_kernel_arg(
+        &mut self,
+        id: String,
+        value: String,
+    ) -> ClientResult<BoxFuture<Result<(), Error>>> {
+        self.full_config.kernel_args.insert(id, value);
+        self.send_config().await
     }
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/agama/agama-bootloader/src/service.rs 
new/agama/agama-bootloader/src/service.rs
--- old/agama/agama-bootloader/src/service.rs   2026-07-14 10:45:10.000000000 
+0200
+++ new/agama/agama-bootloader/src/service.rs   2026-07-16 14:18:35.000000000 
+0200
@@ -132,7 +132,9 @@
 #[async_trait]
 impl MessageHandler<message::SetKernelArg> for Service {
     async fn handle(&mut self, message: message::SetKernelArg) -> Result<(), 
Error> {
-        self.client.set_kernel_arg(message.id, message.value).await;
+        if let Err(err) = self.client.set_kernel_arg(message.id, 
message.value).await {
+            tracing::error!("Failed to set kernel args {:?}", err);
+        }
         Ok(())
     }
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/agama/agama-bootloader/src/test_utils.rs 
new/agama/agama-bootloader/src/test_utils.rs
--- old/agama/agama-bootloader/src/test_utils.rs        2026-07-14 
10:45:10.000000000 +0200
+++ new/agama/agama-bootloader/src/test_utils.rs        2026-07-16 
14:18:35.000000000 +0200
@@ -91,13 +91,19 @@
         Ok(vec![])
     }
 
-    async fn set_config(&self, config: &Config) -> Result<BoxFuture<Result<(), 
Error>>, Error> {
+    async fn set_config(&mut self, config: &Config) -> 
Result<BoxFuture<Result<(), Error>>, Error> {
         let mut state = self.state.lock().await;
         state.config = config.clone();
         Ok(Box::pin(async { Ok(()) }))
     }
 
-    async fn set_kernel_arg(&mut self, _id: String, _value: String) {}
+    async fn set_kernel_arg(
+        &mut self,
+        _id: String,
+        _value: String,
+    ) -> Result<BoxFuture<Result<(), Error>>, Error> {
+        Ok(Box::pin(async { Ok(()) }))
+    }
 }
 
 /// Starts a testing storage service.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/agama/agama-manager/src/hardware.rs 
new/agama/agama-manager/src/hardware.rs
--- old/agama/agama-manager/src/hardware.rs     2026-07-14 10:45:10.000000000 
+0200
+++ new/agama/agama-manager/src/hardware.rs     2026-07-16 14:18:35.000000000 
+0200
@@ -18,7 +18,7 @@
 // To contact SUSE LLC about this file by physical or electronic mail, you may
 // find current contact information at www.suse.com.
 
-use agama_utils::api::manager::HardwareInfo;
+use agama_utils::{api::manager::HardwareInfo, arch::Arch};
 use serde::Deserialize;
 use serde_with::{formats::PreferMany, serde_as, OneOrMany};
 use std::{
@@ -68,7 +68,14 @@
 
     pub async fn read(&mut self) -> Result<(), Error> {
         match &self.source {
-            Source::System => self.read_from_system().await,
+            Source::System => {
+                self.read_from_system().await?;
+                // On s390x, enrich the system node with model info from 
read_values if needed
+                if Arch::is_s390() {
+                    self.read_s390_model().await.ok();
+                }
+                Ok(())
+            }
             Source::File(ref path) => self.read_from_file(path.clone()),
         }
     }
@@ -98,6 +105,50 @@
         Ok(())
     }
 
+    /// Enriches the s390x system node with model info from read_values 
command.
+    async fn read_s390_model(&mut self) -> Result<(), Error> {
+        let Some(ref mut root) = self.root else {
+            return Ok(());
+        };
+
+        let Some(system) = root.find_first_by_class_mut("system") else {
+            return Ok(());
+        };
+
+        let output = tokio::process::Command::new("read_values")
+            .arg("-c")
+            .output()
+            .await?;
+
+        if !output.status.success() {
+            return Ok(());
+        }
+
+        let model = String::from_utf8_lossy(&output.stdout);
+        system.vendor = Some("IBM".to_string());
+        system.version = Self::parse_s390_version(&model);
+
+        Ok(())
+    }
+
+    /// Parses the s390x model from read_values output.
+    ///
+    /// Extracts "eServer zSeries 900" from "z900    IBM eServer zSeries 900".
+    /// or "LinuxONE III LT1" from "IBM LinuxONE III LT1".
+    ///
+    /// Expected format: "8561 = IBM LinuxONE III LT1"
+    fn parse_s390_version(output: &str) -> Option<String> {
+        let line = output
+            .lines()
+            .find_map(|l| l.split_once('=').map(|(_id, model)| 
model.to_string()))?;
+
+        if let Some((_, version)) = line.split_once("IBM") {
+            Some(version.trim().to_string())
+        } else {
+            None
+        }
+    }
+
     /// Converts the information to a HardwareInfo struct.
     pub fn to_hardware_info(&self) -> HardwareInfo {
         let Some(root) = &self.root else {
@@ -191,16 +242,39 @@
             children.search_by_class(class, results);
         }
     }
+
+    /// Searches and returns the first hardware node by class (mutable 
version).
+    ///
+    /// * `class`: class to search for (e.g., "disk", "processor", etc.).
+    pub fn find_first_by_class_mut(&mut self, class: &str) -> Option<&mut 
HardwareNode> {
+        if self.class == class {
+            return Some(self);
+        }
+
+        for children in &mut self.children {
+            let result = children.find_first_by_class_mut(class);
+            if result.is_some() {
+                return result;
+            }
+        }
+
+        None
+    }
 }
 
 impl From<&HardwareNode> for HardwareInfo {
     fn from(value: &HardwareNode) -> Self {
+        // Find the first "processor" node to get the CPU. Use the "product" 
key. If not present,
+        // fallback to "vendor" (like in s390x).
         let cpu = value
             .find_by_class("processor")
             .first()
-            .and_then(|c| c.product.clone());
+            .and_then(|c| c.product.clone().or(c.vendor.clone()));
 
-        let memory = value.find_by_id("memory").and_then(|m| m.size);
+        let memory = value
+            .find_by_id("memory")
+            .or_else(|| value.find_by_id("memory:0"))
+            .and_then(|m| m.size);
 
         let model = if let Some(system) = 
value.find_by_class("system").first() {
             let model_str = format!(
@@ -323,6 +397,34 @@
         ));
     }
 
+    #[test]
+    fn test_parse_s390_version() {
+        let output = "8561 = IBM LinuxONE III LT1";
+        let model = Registry::parse_s390_version(output);
+        assert_eq!(model, Some("LinuxONE III LT1".to_string()));
+
+        let output_with_extra_spaces = "8561   =   IBM LinuxONE III LT1  ";
+        let model = Registry::parse_s390_version(output_with_extra_spaces);
+        assert_eq!(model, Some("LinuxONE III LT1".to_string()));
+
+        let multiline_output = "SomeOtherLine\n8561 = IBM LinuxONE III 
LT1\nAnotherLine";
+        let model = Registry::parse_s390_version(multiline_output);
+        assert_eq!(model, Some("LinuxONE III LT1".to_string()));
+
+        // Test format with machine type prefix before IBM
+        let output_with_prefix = "2064 = z900    IBM eServer zSeries 900";
+        let model = Registry::parse_s390_version(output_with_prefix);
+        assert_eq!(model, Some("eServer zSeries 900".to_string()));
+
+        let invalid_output = "No equals sign here";
+        let model = Registry::parse_s390_version(invalid_output);
+        assert_eq!(model, None);
+
+        let empty_output = "";
+        let model = Registry::parse_s390_version(empty_output);
+        assert_eq!(model, None);
+    }
+
     #[tokio::test]
     async fn test_to_hardware_incomplete() -> Result<(), Box<dyn Error>> {
         let fixtures = 
PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("../test/share");
@@ -334,4 +436,105 @@
         assert_eq!(node.model, None);
         Ok(())
     }
+
+    #[tokio::test]
+    async fn test_to_hardware_s390x() -> Result<(), Box<dyn Error>> {
+        let fixtures = 
PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("../test/share");
+        let mut registry = 
Registry::new_from_file(fixtures.join("lshw-s390x.json"));
+        registry.read().await?;
+        let node = registry.to_hardware_info();
+        assert_eq!(node.cpu, Some("IBM/S390".to_string()));
+        assert_eq!(node.memory, Some(8589934592));
+        // Model is not available from lshw on s390x
+        assert_eq!(node.model, None);
+        Ok(())
+    }
+
+    #[tokio::test]
+    async fn test_s390x_model_enrichment() -> Result<(), Box<dyn Error>> {
+        let fixtures = 
PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("../test/share");
+        let mut registry = 
Registry::new_from_file(fixtures.join("lshw-s390x.json"));
+        registry.read().await?;
+
+        // Simulate enriching the system node with s390 model data
+        if let Some(ref mut root) = registry.root {
+            if let Some(system) = root.find_first_by_class_mut("system") {
+                system.vendor = Some("IBM".to_string());
+                system.version = Some("LinuxONE III LT1".to_string());
+            }
+        }
+
+        let node = registry.to_hardware_info();
+        assert_eq!(node.cpu, Some("IBM/S390".to_string()));
+        assert_eq!(node.memory, Some(8589934592));
+        // Model should now be available from the enriched system node
+        assert_eq!(node.model, Some("IBM LinuxONE III LT1".to_string()));
+        Ok(())
+    }
+
+    #[tokio::test]
+    async fn test_s390x_enrich_with_different_formats() -> Result<(), Box<dyn 
Error>> {
+        let fixtures = 
PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("../test/share");
+
+        // Test "IBM LinuxONE III LT1" format - should split into vendor="IBM" 
and version="LinuxONE III LT1"
+        let mut registry = 
Registry::new_from_file(fixtures.join("lshw-s390x.json"));
+        registry.read().await?;
+        if let Some(ref mut root) = registry.root {
+            if let Some(system) = root.find_first_by_class_mut("system") {
+                system.vendor = Some("IBM".to_string());
+                system.version = Some("LinuxONE III LT1".to_string());
+            }
+        }
+        let info = registry.to_hardware_info();
+        assert_eq!(info.model, Some("IBM LinuxONE III LT1".to_string()));
+
+        // Test "IBM eServer zSeries 900" format - should split into 
vendor="IBM" and version="eServer zSeries 900"
+        let mut registry = 
Registry::new_from_file(fixtures.join("lshw-s390x.json"));
+        registry.read().await?;
+        if let Some(ref mut root) = registry.root {
+            if let Some(system) = root.find_first_by_class_mut("system") {
+                system.vendor = Some("IBM".to_string());
+                system.version = Some("eServer zSeries 900".to_string());
+            }
+        }
+        let info = registry.to_hardware_info();
+        assert_eq!(info.model, Some("IBM eServer zSeries 900".to_string()));
+
+        // Test "IBM LinuxONE Rockhopper" format - should split into 
vendor="IBM" and version="LinuxONE Rockhopper"
+        let mut registry = 
Registry::new_from_file(fixtures.join("lshw-s390x.json"));
+        registry.read().await?;
+        if let Some(ref mut root) = registry.root {
+            if let Some(system) = root.find_first_by_class_mut("system") {
+                system.vendor = Some("IBM".to_string());
+                system.version = Some("LinuxONE Rockhopper".to_string());
+            }
+        }
+        let info = registry.to_hardware_info();
+        assert_eq!(info.model, Some("IBM LinuxONE Rockhopper".to_string()));
+
+        // Test non-IBM format - everything should go to version
+        let mut registry = 
Registry::new_from_file(fixtures.join("lshw-s390x.json"));
+        registry.read().await?;
+        if let Some(ref mut root) = registry.root {
+            if let Some(system) = root.find_first_by_class_mut("system") {
+                system.version = Some("SomeOther Vendor Model".to_string());
+            }
+        }
+        let info = registry.to_hardware_info();
+        assert_eq!(info.model, Some("SomeOther Vendor Model".to_string()));
+
+        // Test "z900    IBM eServer zSeries 900" format with machine type 
prefix
+        let mut registry = 
Registry::new_from_file(fixtures.join("lshw-s390x.json"));
+        registry.read().await?;
+        if let Some(ref mut root) = registry.root {
+            if let Some(system) = root.find_first_by_class_mut("system") {
+                system.vendor = Some("IBM".to_string());
+                system.version = Some("eServer zSeries 900".to_string());
+            }
+        }
+        let info = registry.to_hardware_info();
+        assert_eq!(info.model, Some("IBM eServer zSeries 900".to_string()));
+
+        Ok(())
+    }
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/agama/agama-manager/src/service.rs 
new/agama/agama-manager/src/service.rs
--- old/agama/agama-manager/src/service.rs      2026-07-14 10:45:10.000000000 
+0200
+++ new/agama/agama-manager/src/service.rs      2026-07-16 14:18:35.000000000 
+0200
@@ -482,7 +482,9 @@
     async fn read_system_info(&mut self) -> Result<(), Error> {
         self.licenses.read()?;
         self.products.read()?;
-        self.hardware.read().await?;
+        if let Err(error) = self.hardware.read().await {
+            tracing::warn!("Failed to read hardware information: {error}");
+        }
 
         self.system.licenses = 
self.licenses.licenses().into_iter().cloned().collect();
         self.system.products = self.products.products();
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/agama/agama-utils/src/runtime.rs 
new/agama/agama-utils/src/runtime.rs
--- old/agama/agama-utils/src/runtime.rs        2026-07-14 10:45:10.000000000 
+0200
+++ new/agama/agama-utils/src/runtime.rs        2026-07-16 14:18:35.000000000 
+0200
@@ -23,7 +23,7 @@
 use std::future::Future;
 
 /// Maximum number of worker threads for the Tokio runtime.
-const MAX_WORKER_THREADS: usize = 32;
+const MAX_WORKER_THREADS: usize = 4;
 
 /// Creates a multi-threaded Tokio runtime with a capped number of worker 
threads.
 ///
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     2026-07-14 10:45:10.000000000 +0200
+++ new/agama/package/agama.changes     2026-07-16 14:18:35.000000000 +0200
@@ -1,4 +1,31 @@
 -------------------------------------------------------------------
+Thu Jul 16 11:26:26 UTC 2026 - Imobach Gonzalez Sosa <[email protected]>
+
+- Limit the number of Tokio worker threads to 4
+  (gh#agama-project/agama#3729, related to bsc#1265451).
+
+-------------------------------------------------------------------  
+Thu Jul 16 11:01:05 UTC 2026 - Michal Filka <[email protected]>
+
+- Fixed issues when fetching AutoYast XML profile.
+  Agama cares about YAST_SKIP_PROFILE_FETCH_ERROR now.
+  agama-autoyast doesn't end with error when no profile found.
+
+-------------------------------------------------------------------
+Wed Jul 15 10:13:10 UTC 2026 - Imobach Gonzalez Sosa <[email protected]>
+
+- Do not crash when running "lshw" fails or the output cannot be
+  parsed (bsc#1269367).
+- Fix the detection of model and CPU in s390x (bsc#1270639).
+- Fix the detection of the memory when lshw does not report a
+  node with id "memory", but "memory:0" (bsc#1271190).
+
+-------------------------------------------------------------------
+Wed Jul 15 09:16:44 UTC 2026 - Josef Reidinger <[email protected]>
+
+- Fix setting security kernel parameter (bsc#1269581)
+
+-------------------------------------------------------------------
 Mon Jul 13 16:17:18 UTC 2026 - José Iván López González <[email protected]>
 
 - Do not start config tasks until pre-scripts have finished
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/agama/test/share/lshw-s390x.json 
new/agama/test/share/lshw-s390x.json
--- old/agama/test/share/lshw-s390x.json        1970-01-01 01:00:00.000000000 
+0100
+++ new/agama/test/share/lshw-s390x.json        2026-07-16 14:18:35.000000000 
+0200
@@ -0,0 +1,40 @@
+{
+  "id": "s390x",
+  "class": "system",
+  "claimed": true,
+  "description": "System",
+  "children": [
+    {
+      "id": "memory",
+      "class": "memory",
+      "claimed": true,
+      "description": "System memory",
+      "physid": "0",
+      "size": 8589934592
+    },
+    {
+      "id": "cpu:0",
+      "class": "processor",
+      "claimed": true,
+      "product": "IBM/S390",
+      "physid": "1",
+      "businfo": "cpu@0",
+      "configuration": {
+        "cores": "2",
+        "enabledcores": "2"
+      }
+    },
+    {
+      "id": "cpu:1",
+      "class": "processor",
+      "claimed": true,
+      "product": "IBM/S390",
+      "physid": "2",
+      "businfo": "cpu@1",
+      "configuration": {
+        "cores": "2",
+        "enabledcores": "2"
+      }
+    }
+  ]
+}

++++++ agama.obsinfo ++++++
--- /var/tmp/diff_new_pack.pP4phw/_old  2026-07-17 18:47:49.197893669 +0200
+++ /var/tmp/diff_new_pack.pP4phw/_new  2026-07-17 18:47:49.225894613 +0200
@@ -1,5 +1,5 @@
 name: agama
-version: 22+398.d23cf880d
-mtime: 1784018710
-commit: d23cf880d8ccae5e227b611b1b1ece43b8dc3d72
+version: 22+456.ce0fb8baf
+mtime: 1784204315
+commit: ce0fb8baf906e6dc037106481ae0640cc743cee2
 

Reply via email to