diff --git a/rust/Cargo.lock b/rust/Cargo.lock index f9f5f3dcb5..87289cef7e 100644 --- a/rust/Cargo.lock +++ b/rust/Cargo.lock @@ -343,7 +343,6 @@ dependencies = [ name = "agama-software" version = "0.1.0" dependencies = [ - "agama-bootloader", "agama-l10n", "agama-security", "agama-utils", diff --git a/rust/agama-manager/src/actions.rs b/rust/agama-manager/src/actions.rs index 049591b13b..a630f06c1e 100644 --- a/rust/agama-manager/src/actions.rs +++ b/rust/agama-manager/src/actions.rs @@ -301,6 +301,18 @@ impl SetConfigAction { match &product { Some(product) => { + self.progress + .call(progress::message::Next::new(Scope::Manager)) + .await?; + self.software + .call(software::message::SetConfig::new( + Arc::clone(product), + config.software.clone(), + )) + .await?; + + self.set_selinux().await?; + self.progress .call(progress::message::Next::new(Scope::Manager)) .await?; @@ -322,16 +334,6 @@ impl SetConfigAction { config.bootloader.clone(), )) .await?; - - self.progress - .call(progress::message::Next::new(Scope::Manager)) - .await?; - self.software - .call(software::message::SetConfig::new( - Arc::clone(product), - config.software.clone(), - )) - .await?; } None => { @@ -356,6 +358,38 @@ impl SetConfigAction { Ok(()) } + + // Enables/Disables SELinux in the installed system. + // + // If the "selinux" pattern is selected, set the "security=selinux" boot + // kernel parameter. + // + // NOTE: this logic should live in another place, like "agama-security". + // It is temporarily here to fix bsc#1259890. + async fn set_selinux(&self) -> Result<(), service::Error> { + let selinux_selected = self + .software + .call(software::message::IsPatternSelected::new( + "selinux".to_string(), + )) + .await?; + + let value = if selinux_selected { + "security=selinux" + } else { + "security=" + }; + let message = agama_bootloader::message::SetKernelArg { + id: "selinux".to_string(), + value: value.to_string(), + }; + + if let Err(error) = self.bootloader.cast(message) { + tracing::warn!("Failed to send to bootloader new selinux state: {error:?}"); + } + + Ok(()) + } } /// Implements the finish action. diff --git a/rust/agama-manager/src/service.rs b/rust/agama-manager/src/service.rs index a302e85583..88163d0dca 100644 --- a/rust/agama-manager/src/service.rs +++ b/rust/agama-manager/src/service.rs @@ -281,7 +281,6 @@ impl Starter { progress.clone(), self.questions.clone(), security.clone(), - bootloader.clone(), ) .start() .await? diff --git a/rust/agama-software/Cargo.toml b/rust/agama-software/Cargo.toml index c9c55e269b..2dc796fbbf 100644 --- a/rust/agama-software/Cargo.toml +++ b/rust/agama-software/Cargo.toml @@ -5,7 +5,6 @@ rust-version.workspace = true edition.workspace = true [dependencies] -agama-bootloader = { path = "../agama-bootloader" } agama-l10n = { path = "../agama-l10n" } agama-utils = { path = "../agama-utils" } agama-security = { path = "../agama-security" } diff --git a/rust/agama-software/src/message.rs b/rust/agama-software/src/message.rs index 7eb0fb76b0..d3287c17e5 100644 --- a/rust/agama-software/src/message.rs +++ b/rust/agama-software/src/message.rs @@ -133,3 +133,18 @@ impl SetLocale { impl Message for SetLocale { type Reply = (); } + +#[derive(Clone)] +pub struct IsPatternSelected { + pub name: String, +} + +impl Message for IsPatternSelected { + type Reply = bool; +} + +impl IsPatternSelected { + pub fn new(name: String) -> Self { + Self { name } + } +} diff --git a/rust/agama-software/src/service.rs b/rust/agama-software/src/service.rs index 6ffcb4ae96..849c4b1e87 100644 --- a/rust/agama-software/src/service.rs +++ b/rust/agama-software/src/service.rs @@ -26,7 +26,6 @@ use crate::{ zypp_server::{self, SoftwareAction, ZyppServer}, Model, ResolvableType, }; -use agama_bootloader; use agama_security as security; use agama_utils::{ actor::{self, Actor, Handler, MessageHandler}, @@ -92,7 +91,6 @@ pub struct Starter { progress: Handler, questions: Handler, security: Handler, - bootloader: Handler, } impl Starter { @@ -102,7 +100,6 @@ impl Starter { progress: Handler, questions: Handler, security: Handler, - bootloader: Handler, ) -> Self { Self { model: None, @@ -111,7 +108,6 @@ impl Starter { progress, questions, security, - bootloader, } } @@ -158,7 +154,6 @@ impl Starter { progress: self.progress, product: None, kernel_cmdline, - bootloader: self.bootloader, }; service.setup().await?; Ok(actor::spawn(service)) @@ -181,7 +176,6 @@ pub struct Service { product: Option>>, selection: SoftwareSelection, kernel_cmdline: KernelCmdline, - bootloader: Handler, } #[derive(Default)] @@ -199,9 +193,8 @@ impl Service { progress: Handler, questions: Handler, security: Handler, - bootloader: Handler, ) -> Starter { - Starter::new(events, issues, progress, questions, security, bootloader) + Starter::new(events, issues, progress, questions, security) } pub async fn setup(&mut self) -> Result<(), Error> { @@ -217,26 +210,6 @@ impl Service { Ok(()) } - fn update_selinux(&self, state: &SoftwareState) { - let selinux_selected = state.resolvables.to_vec().iter().any(|(name, typ, state)| { - typ == &ResolvableType::Pattern && name == "selinux" && state.selected() - }); - - let value = if selinux_selected { - "security=selinux" - } else { - "security=" - }; - let message = agama_bootloader::message::SetKernelArg { - id: "selinux".to_string(), - value: value.to_string(), - }; - let res = self.bootloader.cast(message); - if res.is_err() { - tracing::warn!("Failed to send to bootloader new selinux state: {:?}", res); - } - } - /// Updates the proposal and the service state. /// /// This function performs the following actions: @@ -258,8 +231,6 @@ impl Service { SoftwareState::build_from(&product, &state.config, &state.system, &self.selection) }; - self.update_selinux(&new_state); - tracing::info!("Wanted software state: {new_state:?}"); { let mut state = self.state.write().await; @@ -513,6 +484,26 @@ impl MessageHandler for Service { } } +#[async_trait] +impl MessageHandler for Service { + async fn handle(&mut self, message: message::IsPatternSelected) -> Result { + let state = self.state.read().await; + let Some(software_state) = &state.state else { + return Ok(false); + }; + + let selected = software_state + .resolvables + .to_vec() + .iter() + .any(|(name, typ, state)| { + typ == &ResolvableType::Pattern && name == &message.name && state.selected() + }); + + Ok(selected) + } +} + const LIVE_REPO_DIR: &str = "run/initramfs/live/install"; const DUD_REPO_DIR: &str = "var/lib/agama/dud/repo"; diff --git a/rust/agama-software/src/test_utils.rs b/rust/agama-software/src/test_utils.rs index ecb7469498..2256940f50 100644 --- a/rust/agama-software/src/test_utils.rs +++ b/rust/agama-software/src/test_utils.rs @@ -27,7 +27,7 @@ use agama_utils::{ }, issue, products::ProductSpec, - progress, question, test, + progress, question, }; use async_trait::async_trait; @@ -90,9 +90,7 @@ pub async fn start_service( questions: Handler, ) -> Handler { let security = start_security_service(questions.clone()).await; - let dbus = test::dbus::connection().await.unwrap(); - let bootloader = agama_bootloader::test_utils::start_service(issues.clone(), dbus).await; - Service::starter(events, issues, progress, questions, security, bootloader) + Service::starter(events, issues, progress, questions, security) .with_model(TestModel {}) .start() .await diff --git a/rust/package/agama.changes b/rust/package/agama.changes index 4dd499b505..e704a90be4 100644 --- a/rust/package/agama.changes +++ b/rust/package/agama.changes @@ -1,3 +1,8 @@ +------------------------------------------------------------------- +Fri Mar 20 13:55:22 UTC 2026 - Imobach Gonzalez Sosa + +- Enable SELinux if needed in unattended installations (bsc#1259890). + ------------------------------------------------------------------- Fri Mar 20 08:46:19 UTC 2026 - Knut Anderssen