Skip to content

Commit 9def055

Browse files
authored
bsc#1259890: Enable SELinux in unattended installation (#3311)
## Problem * https://bugzilla.suse.com/show_bug.cgi?id=1259890 ## Solution Remove the dependency of the software service on the bootloader, breaking the circular dependency between them. The logic to decide whether to enable SELinux lives now in the manager, although it could be moved to agama-security in the future. ## Testing - Tested manually
2 parents 3f9da8e + 0caa52c commit 9def055

File tree

8 files changed

+87
-47
lines changed

8 files changed

+87
-47
lines changed

rust/Cargo.lock

Lines changed: 0 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

rust/agama-manager/src/actions.rs

Lines changed: 44 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,18 @@ impl SetConfigAction {
301301

302302
match &product {
303303
Some(product) => {
304+
self.progress
305+
.call(progress::message::Next::new(Scope::Manager))
306+
.await?;
307+
self.software
308+
.call(software::message::SetConfig::new(
309+
Arc::clone(product),
310+
config.software.clone(),
311+
))
312+
.await?;
313+
314+
self.set_selinux().await?;
315+
304316
self.progress
305317
.call(progress::message::Next::new(Scope::Manager))
306318
.await?;
@@ -322,16 +334,6 @@ impl SetConfigAction {
322334
config.bootloader.clone(),
323335
))
324336
.await?;
325-
326-
self.progress
327-
.call(progress::message::Next::new(Scope::Manager))
328-
.await?;
329-
self.software
330-
.call(software::message::SetConfig::new(
331-
Arc::clone(product),
332-
config.software.clone(),
333-
))
334-
.await?;
335337
}
336338

337339
None => {
@@ -356,6 +358,38 @@ impl SetConfigAction {
356358

357359
Ok(())
358360
}
361+
362+
// Enables/Disables SELinux in the installed system.
363+
//
364+
// If the "selinux" pattern is selected, set the "security=selinux" boot
365+
// kernel parameter.
366+
//
367+
// NOTE: this logic should live in another place, like "agama-security".
368+
// It is temporarily here to fix bsc#1259890.
369+
async fn set_selinux(&self) -> Result<(), service::Error> {
370+
let selinux_selected = self
371+
.software
372+
.call(software::message::IsPatternSelected::new(
373+
"selinux".to_string(),
374+
))
375+
.await?;
376+
377+
let value = if selinux_selected {
378+
"security=selinux"
379+
} else {
380+
"security="
381+
};
382+
let message = agama_bootloader::message::SetKernelArg {
383+
id: "selinux".to_string(),
384+
value: value.to_string(),
385+
};
386+
387+
if let Err(error) = self.bootloader.cast(message) {
388+
tracing::warn!("Failed to send to bootloader new selinux state: {error:?}");
389+
}
390+
391+
Ok(())
392+
}
359393
}
360394

361395
/// Implements the finish action.

rust/agama-manager/src/service.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,6 @@ impl Starter {
281281
progress.clone(),
282282
self.questions.clone(),
283283
security.clone(),
284-
bootloader.clone(),
285284
)
286285
.start()
287286
.await?

rust/agama-software/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ rust-version.workspace = true
55
edition.workspace = true
66

77
[dependencies]
8-
agama-bootloader = { path = "../agama-bootloader" }
98
agama-l10n = { path = "../agama-l10n" }
109
agama-utils = { path = "../agama-utils" }
1110
agama-security = { path = "../agama-security" }

rust/agama-software/src/message.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,3 +133,18 @@ impl SetLocale {
133133
impl Message for SetLocale {
134134
type Reply = ();
135135
}
136+
137+
#[derive(Clone)]
138+
pub struct IsPatternSelected {
139+
pub name: String,
140+
}
141+
142+
impl Message for IsPatternSelected {
143+
type Reply = bool;
144+
}
145+
146+
impl IsPatternSelected {
147+
pub fn new(name: String) -> Self {
148+
Self { name }
149+
}
150+
}

rust/agama-software/src/service.rs

Lines changed: 21 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ use crate::{
2626
zypp_server::{self, SoftwareAction, ZyppServer},
2727
Model, ResolvableType,
2828
};
29-
use agama_bootloader;
3029
use agama_security as security;
3130
use agama_utils::{
3231
actor::{self, Actor, Handler, MessageHandler},
@@ -92,7 +91,6 @@ pub struct Starter {
9291
progress: Handler<progress::Service>,
9392
questions: Handler<question::Service>,
9493
security: Handler<security::Service>,
95-
bootloader: Handler<agama_bootloader::Service>,
9694
}
9795

9896
impl Starter {
@@ -102,7 +100,6 @@ impl Starter {
102100
progress: Handler<progress::Service>,
103101
questions: Handler<question::Service>,
104102
security: Handler<security::Service>,
105-
bootloader: Handler<agama_bootloader::Service>,
106103
) -> Self {
107104
Self {
108105
model: None,
@@ -111,7 +108,6 @@ impl Starter {
111108
progress,
112109
questions,
113110
security,
114-
bootloader,
115111
}
116112
}
117113

@@ -158,7 +154,6 @@ impl Starter {
158154
progress: self.progress,
159155
product: None,
160156
kernel_cmdline,
161-
bootloader: self.bootloader,
162157
};
163158
service.setup().await?;
164159
Ok(actor::spawn(service))
@@ -181,7 +176,6 @@ pub struct Service {
181176
product: Option<Arc<RwLock<ProductSpec>>>,
182177
selection: SoftwareSelection,
183178
kernel_cmdline: KernelCmdline,
184-
bootloader: Handler<agama_bootloader::Service>,
185179
}
186180

187181
#[derive(Default)]
@@ -199,9 +193,8 @@ impl Service {
199193
progress: Handler<progress::Service>,
200194
questions: Handler<question::Service>,
201195
security: Handler<security::Service>,
202-
bootloader: Handler<agama_bootloader::Service>,
203196
) -> Starter {
204-
Starter::new(events, issues, progress, questions, security, bootloader)
197+
Starter::new(events, issues, progress, questions, security)
205198
}
206199

207200
pub async fn setup(&mut self) -> Result<(), Error> {
@@ -217,26 +210,6 @@ impl Service {
217210
Ok(())
218211
}
219212

220-
fn update_selinux(&self, state: &SoftwareState) {
221-
let selinux_selected = state.resolvables.to_vec().iter().any(|(name, typ, state)| {
222-
typ == &ResolvableType::Pattern && name == "selinux" && state.selected()
223-
});
224-
225-
let value = if selinux_selected {
226-
"security=selinux"
227-
} else {
228-
"security="
229-
};
230-
let message = agama_bootloader::message::SetKernelArg {
231-
id: "selinux".to_string(),
232-
value: value.to_string(),
233-
};
234-
let res = self.bootloader.cast(message);
235-
if res.is_err() {
236-
tracing::warn!("Failed to send to bootloader new selinux state: {:?}", res);
237-
}
238-
}
239-
240213
/// Updates the proposal and the service state.
241214
///
242215
/// This function performs the following actions:
@@ -258,8 +231,6 @@ impl Service {
258231
SoftwareState::build_from(&product, &state.config, &state.system, &self.selection)
259232
};
260233

261-
self.update_selinux(&new_state);
262-
263234
tracing::info!("Wanted software state: {new_state:?}");
264235
{
265236
let mut state = self.state.write().await;
@@ -513,6 +484,26 @@ impl MessageHandler<message::SetLocale> for Service {
513484
}
514485
}
515486

487+
#[async_trait]
488+
impl MessageHandler<message::IsPatternSelected> for Service {
489+
async fn handle(&mut self, message: message::IsPatternSelected) -> Result<bool, Error> {
490+
let state = self.state.read().await;
491+
let Some(software_state) = &state.state else {
492+
return Ok(false);
493+
};
494+
495+
let selected = software_state
496+
.resolvables
497+
.to_vec()
498+
.iter()
499+
.any(|(name, typ, state)| {
500+
typ == &ResolvableType::Pattern && name == &message.name && state.selected()
501+
});
502+
503+
Ok(selected)
504+
}
505+
}
506+
516507
const LIVE_REPO_DIR: &str = "run/initramfs/live/install";
517508
const DUD_REPO_DIR: &str = "var/lib/agama/dud/repo";
518509

rust/agama-software/src/test_utils.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ use agama_utils::{
2727
},
2828
issue,
2929
products::ProductSpec,
30-
progress, question, test,
30+
progress, question,
3131
};
3232
use async_trait::async_trait;
3333

@@ -90,9 +90,7 @@ pub async fn start_service(
9090
questions: Handler<question::Service>,
9191
) -> Handler<Service> {
9292
let security = start_security_service(questions.clone()).await;
93-
let dbus = test::dbus::connection().await.unwrap();
94-
let bootloader = agama_bootloader::test_utils::start_service(issues.clone(), dbus).await;
95-
Service::starter(events, issues, progress, questions, security, bootloader)
93+
Service::starter(events, issues, progress, questions, security)
9694
.with_model(TestModel {})
9795
.start()
9896
.await

rust/package/agama.changes

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
-------------------------------------------------------------------
2+
Fri Mar 20 13:55:22 UTC 2026 - Imobach Gonzalez Sosa <igonzalezsosa@suse.com>
3+
4+
- Enable SELinux if needed in unattended installations (bsc#1259890).
5+
16
-------------------------------------------------------------------
27
Fri Mar 20 08:46:19 UTC 2026 - Knut Anderssen <kanderssen@suse.com>
38

0 commit comments

Comments
 (0)