diff --git a/rust/agama-software/src/model/state.rs b/rust/agama-software/src/model/state.rs index dde87294ea..291bf79a34 100644 --- a/rust/agama-software/src/model/state.rs +++ b/rust/agama-software/src/model/state.rs @@ -179,6 +179,16 @@ impl<'a> SoftwareStateBuilder<'a> { ResolvableType::Package, ResolvableSelection::AutoSelected { optional: false }, ); + + // FIPS enabled, so add fips pattern + if self.kernel_cmdline.get_last("fips") == Some("1".to_string()) { + tracing::info!("fips detected, adding fips pattern"); + state.resolvables.add_or_replace( + "fips", + ResolvableType::Pattern, + ResolvableSelection::AutoSelected { optional: false }, + ); + } } /// Adds the elements from the user configuration. diff --git a/rust/agama-utils/src/kernel_cmdline.rs b/rust/agama-utils/src/kernel_cmdline.rs index 229769d530..b301bf7c07 100644 --- a/rust/agama-utils/src/kernel_cmdline.rs +++ b/rust/agama-utils/src/kernel_cmdline.rs @@ -20,21 +20,28 @@ use std::{collections::HashMap, path::Path}; -const CMDLINE_FILE: &str = "/run/agama/cmdline.d/agama.conf"; +const AGAMA_CMDLINE_FILE: &str = "/run/agama/cmdline.d/agama.conf"; +const KERNEL_CMDLINE_FILE: &str = "/run/agama/cmdline.d/kernel.conf"; /// Implements a mechanism to read the kernel's command-line arguments. /// -/// It supports multiple values for a single key. +/// It supports multiple values for a single key. Keys are case-insensitive. #[derive(Default)] pub struct KernelCmdline(HashMap>); impl KernelCmdline { /// Parses the command-line. /// - /// The content of the command-line is stored, by default, in the {CMDLINE_FILE}. + /// The content of the command-line is stored, by default it is combination of agama and kernel cmdline args. pub fn parse() -> std::io::Result { - Self::parse_file(CMDLINE_FILE) - .inspect_err(|e| tracing::warn!("Could not parse the kernel command-line: {e}")) + let agama = Self::parse_file(AGAMA_CMDLINE_FILE).inspect_err(|e| { + tracing::warn!("Could not parse the agama kernel command-line: {e}") + })?; + let kernel = Self::parse_file(KERNEL_CMDLINE_FILE).inspect_err(|e| { + tracing::warn!("Could not parse the filtered kernel command-line: {e}") + })?; + + Ok(agama.merge(kernel)) } /// Builds an instance from the given file. @@ -57,23 +64,35 @@ impl KernelCmdline { .map(|(k, v)| (k, v)) .unwrap_or_else(|| (param, "1")); - args.entry(key.to_string()) + args.entry(key.to_lowercase()) .and_modify(|v| v.push(value.to_string())) .or_insert(vec![value.to_string()]); } Self(args) } + pub fn merge(self, other: Self) -> Self { + let mut args = self.0; + for (key, value) in other.0 { + args.entry(key) + // this modify is just for theoretical correctness as in reality we are merging kernel and agama + // args and they are exclusive + .and_modify(|v| v.extend(value.clone())) + .or_insert(value); + } + Self(args) + } + /// Returns the values for the argument. /// /// * `name`: argument name. pub fn get(&self, name: &str) -> Vec { - self.0.get(name).cloned().unwrap_or(vec![]) + self.0.get(&name.to_lowercase()).cloned().unwrap_or(vec![]) } /// Returns the last value for the argument pub fn get_last(&self, name: &str) -> Option { - let values = self.0.get(name)?; + let values = self.0.get(&name.to_lowercase())?; values.last().cloned() } } @@ -102,4 +121,35 @@ mod tests { assert_eq!(args.get_last("inst.auto_insecure"), Some("0".to_string())); } + + #[test] + fn test_cmdline_args_case_insensitive() { + let args_str = r"Inst.Auto=file:///profile.json RD.NEEDNET"; + let args = KernelCmdline::parse_str(args_str); + + assert_eq!( + args.get_last("inst.auto"), + Some("file:///profile.json".to_string()) + ); + assert_eq!( + args.get_last("INST.AUTO"), + Some("file:///profile.json".to_string()) + ); + assert_eq!(args.get("rd.neednet"), vec!["1".to_string()]); + } + + #[test] + fn test_merge() { + let cmdline1 = KernelCmdline::parse_str("key1=val1 key2=val2"); + let cmdline2 = KernelCmdline::parse_str("key2=val3 key3=val4"); + + let merged = cmdline1.merge(cmdline2); + + assert_eq!(merged.get("key1"), vec!["val1".to_string()]); + assert_eq!( + merged.get("key2"), + vec!["val2".to_string(), "val3".to_string()] + ); + assert_eq!(merged.get("key3"), vec!["val4".to_string()]); + } } diff --git a/rust/package/agama.changes b/rust/package/agama.changes index b83b60288e..76ef5fd77b 100644 --- a/rust/package/agama.changes +++ b/rust/package/agama.changes @@ -1,3 +1,9 @@ +------------------------------------------------------------------- +Fri Feb 20 09:35:01 UTC 2026 - Josef Reidinger + +- Properly mark fips pattern for installation when fips kernel + parameter is used (bsc#1258306) + ------------------------------------------------------------------- Thu Feb 19 16:42:12 UTC 2026 - Imobach Gonzalez Sosa