Skip to content

Commit 88cc85e

Browse files
authored
Use dmidecode crate to avoid hostbin (#91)
https://docs.rs/dmidecode/latest/dmidecode/ This captures all of the bytes, but does not fully decode as many into human-readable format as the binary does. But it has the added benefit of working exactly the same way inside and outside of a container, and not requiring a host (or container) bin, or a custom impl, so on the whole I like it better as an option. I looked at possibly just slurping raw bytes from `/sys/firmware/dmi/tables/` in the the host namespace context, and then replaying the raw bytes from that against an OCI-local `dmidecode` binary - but `dmidecode` has some quirks that make that tricky, and that doesn't solve for running the naked `edera-check` binary outside of an OCI image - this does. Fixes part-of: #86
1 parent 6123a69 commit 88cc85e

4 files changed

Lines changed: 117 additions & 10 deletions

File tree

Cargo.lock

Lines changed: 24 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,4 @@ async-trait = "0.1"
3131
clap = { version = "4.6", features = ["derive"] }
3232
console = "0.16"
3333
bytesize = "2.3"
34+
dmidecode = "0.9"

src/recorders/postinstall/system.rs

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,52 @@ impl SystemRecorder {
159159
/// dmidecode
160160
/// ```
161161
pub async fn record_dmidecode(&self) -> CheckResult {
162-
self.run_tool("dmidecode").await
162+
const NAME: &str = "Captured dmidecode";
163+
164+
self.host_executor
165+
.spawn_in_host_ns(async {
166+
let ep_bytes = match std::fs::read("/sys/firmware/dmi/tables/smbios_entry_point") {
167+
Ok(b) => b,
168+
Err(e) => {
169+
return CheckResult::new(
170+
NAME,
171+
Skipped(format!("could not read smbios_entry_point: {e}")),
172+
);
173+
}
174+
};
175+
176+
let entry_point = match dmidecode::EntryPoint::search(&ep_bytes) {
177+
Ok(ep) => ep,
178+
Err(e) => {
179+
return CheckResult::new(
180+
NAME,
181+
Skipped(format!("could not parse DMI entry point: {e:?}")),
182+
);
183+
}
184+
};
185+
186+
let table_bytes = match std::fs::read("/sys/firmware/dmi/tables/DMI") {
187+
Ok(b) => b,
188+
Err(e) => {
189+
return CheckResult::new(
190+
NAME,
191+
Skipped(format!("could not read DMI table: {e}")),
192+
);
193+
}
194+
};
195+
196+
let mut output = String::new();
197+
for structure in entry_point.structures(&table_bytes) {
198+
match structure {
199+
Ok(s) => output.push_str(&format!("{s:#?}\n")),
200+
Err(e) => output.push_str(&format!("Error: {e:?}\n")),
201+
}
202+
}
203+
204+
CheckResult::new_with_output(NAME, Passed, Some(output.trim().to_string()))
205+
})
206+
.await
207+
.unwrap_or_else(|e| CheckResult::new(NAME, Skipped(e.to_string())))
163208
}
164209

165210
/// Records the Xen hypervisor console log via the protect-ctl tool.

src/recorders/preinstall/system.rs

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,52 @@ impl SystemRecorder {
149149
/// dmidecode
150150
/// ```
151151
pub async fn record_dmidecode(&self) -> CheckResult {
152-
self.run_tool("dmidecode").await
152+
const NAME: &str = "Captured dmidecode";
153+
154+
self.host_executor
155+
.spawn_in_host_ns(async {
156+
let ep_bytes = match std::fs::read("/sys/firmware/dmi/tables/smbios_entry_point") {
157+
Ok(b) => b,
158+
Err(e) => {
159+
return CheckResult::new(
160+
NAME,
161+
Skipped(format!("could not read smbios_entry_point: {e}")),
162+
);
163+
}
164+
};
165+
166+
let entry_point = match dmidecode::EntryPoint::search(&ep_bytes) {
167+
Ok(ep) => ep,
168+
Err(e) => {
169+
return CheckResult::new(
170+
NAME,
171+
Skipped(format!("could not parse DMI entry point: {e:?}")),
172+
);
173+
}
174+
};
175+
176+
let table_bytes = match std::fs::read("/sys/firmware/dmi/tables/DMI") {
177+
Ok(b) => b,
178+
Err(e) => {
179+
return CheckResult::new(
180+
NAME,
181+
Skipped(format!("could not read DMI table: {e}")),
182+
);
183+
}
184+
};
185+
186+
let mut output = String::new();
187+
for structure in entry_point.structures(&table_bytes) {
188+
match structure {
189+
Ok(s) => output.push_str(&format!("{s:#?}\n")),
190+
Err(e) => output.push_str(&format!("Error: {e:?}\n")),
191+
}
192+
}
193+
194+
CheckResult::new_with_output(NAME, Passed, Some(output.trim().to_string()))
195+
})
196+
.await
197+
.unwrap_or_else(|e| CheckResult::new(NAME, Skipped(e.to_string())))
153198
}
154199

155200
/// Records CPU hardware details and feature flags.

0 commit comments

Comments
 (0)