edera_check/checkers/preinstall/
kernel.rs1use crate::helpers::{
2 CheckGroup, CheckGroupCategory, CheckGroupResult, CheckResult,
3 CheckResultValue::{Errored, Failed, Passed},
4 host_executor::HostNamespaceExecutor,
5 kernel as khelper,
6};
7
8use async_trait::async_trait;
9use futures::{FutureExt, future::join_all};
10
11const GROUP_IDENTIFIER: &str = "kernel";
12const NAME: &str = "Kernel Checks";
13const REQUIRED_MODULES: &[&str] = &["nf_tables", "msr"];
15
16pub struct KernelChecks {
17 host_executor: HostNamespaceExecutor,
18}
19
20impl KernelChecks {
21 pub fn new(host_executor: HostNamespaceExecutor) -> Self {
22 KernelChecks { host_executor }
23 }
24
25 pub async fn run_all(&self) -> CheckGroupResult {
28 let results = join_all([self.has_modules().boxed()]).await;
29
30 let mut group_result = Passed;
31 for res in results.iter() {
32 if !matches!(group_result, Errored(_)) && matches!(res.result, Failed(_)) {
34 group_result = Failed("".into());
35 }
36
37 if matches!(res.result, Errored(_)) {
38 group_result = Errored("".into());
39 }
40 }
41
42 CheckGroupResult {
43 name: NAME.to_string(),
44 result: group_result,
45 results,
46 }
47 }
48
49 pub async fn has_modules(&self) -> CheckResult {
57 let name = String::from("Host Has Necessary Modules");
58
59 let required_modules: Vec<String> =
60 REQUIRED_MODULES.iter().map(|s| s.to_string()).collect();
61
62 let remaining = match khelper::find_builtins(&self.host_executor, &required_modules).await {
64 Ok(r) => r,
65 Err(e) => {
66 return CheckResult::new(&name, Errored(format!("getting kernel builtins {e}")));
67 }
68 };
69
70 let remaining = match khelper::find_loaded(&self.host_executor, &remaining).await {
72 Ok(r) => r,
73 Err(e) => {
74 return CheckResult::new(&name, Errored(format!("getting kernel modules {e}")));
75 }
76 };
77 if !remaining.is_empty() {
78 return CheckResult::new(&name, Failed(format!("missing {:?}", remaining)));
79 }
80
81 CheckResult::new(&name, Passed)
82 }
83}
84
85#[async_trait]
86impl CheckGroup for KernelChecks {
87 fn id(&self) -> &str {
88 GROUP_IDENTIFIER
89 }
90
91 fn name(&self) -> &str {
92 NAME
93 }
94
95 fn description(&self) -> &str {
96 "Kernel requirement checks"
97 }
98
99 async fn run(&self) -> CheckGroupResult {
100 self.run_all().await
101 }
102
103 fn category(&self) -> CheckGroupCategory {
104 CheckGroupCategory::Required
105 }
106}