capsula_machine_context/
lib.rs

1mod config;
2mod error;
3
4use capsula_core::captured::Captured;
5use capsula_core::context::{Context, ContextFactory, RuntimeParams};
6use capsula_core::error::CoreResult;
7use config::MachineContextFactory;
8use crate::error::MachineContextError;
9use sysinfo::{CpuRefreshKind, MemoryRefreshKind, RefreshKind, System};
10
11pub const KEY: &str = "machine";
12
13#[derive(Debug, Default)]
14pub struct MachineContext;
15
16#[derive(Debug)]
17pub struct CpuInfo {
18    name: String,
19    vender_id: String,
20    brand: String,
21    frequency_mhz: u64,
22}
23
24#[derive(Debug)]
25pub struct MachineCaptured {
26    pub os: String,
27    pub os_version: String,
28    pub kernel_version: String,
29    pub architecture: String,
30    pub cpus: Vec<CpuInfo>,
31    // pub cpu_cores: usize,
32    pub total_memory: usize,
33    // pub user: String,
34    pub hostname: String,
35}
36
37impl Context for MachineContext {
38    type Output = MachineCaptured;
39
40    fn run(&self, _params: &RuntimeParams) -> CoreResult<Self::Output> {
41        let os = System::name().ok_or(MachineContextError::OsInfoError)?;
42        let os_version = System::os_version().ok_or(MachineContextError::OsInfoError)?;
43        let kernel_version = System::kernel_version().ok_or(MachineContextError::OsInfoError)?;
44        let architecture = std::env::consts::ARCH.to_string();
45
46        let system = System::new_with_specifics(
47            RefreshKind::nothing()
48                .with_cpu(CpuRefreshKind::nothing().with_frequency())
49                .with_memory(MemoryRefreshKind::nothing().with_ram()),
50        );
51        let cpus = system
52            .cpus()
53            .iter()
54            .map(|cpu| CpuInfo {
55                name: cpu.name().to_string(),
56                vender_id: cpu.vendor_id().to_string(),
57                brand: cpu.brand().to_string(),
58                frequency_mhz: cpu.frequency(),
59            })
60            .collect::<Vec<_>>();
61
62        let total_memory = system.total_memory();
63        let hostname = System::host_name().ok_or(MachineContextError::HostnameError)?;
64
65        Ok(MachineCaptured {
66            os,
67            os_version,
68            kernel_version,
69            architecture,
70            cpus,
71            total_memory: total_memory as usize,
72            hostname: hostname,
73        })
74    }
75}
76
77impl Captured for MachineCaptured {
78    fn to_json(&self) -> serde_json::Value {
79        serde_json::json!({
80            "type": KEY,
81            "os": self.os,
82            "os_version": self.os_version,
83            "kernel_version": self.kernel_version,
84            "architecture": self.architecture,
85            "cpus": self.cpus.iter().map(|cpu| {
86                serde_json::json!({
87                    "name": cpu.name,
88                    "vender_id": cpu.vender_id,
89                    "brand": cpu.brand,
90                    "frequency_mhz": cpu.frequency_mhz,
91                })
92            }).collect::<Vec<_>>(),
93            "total_memory": self.total_memory,
94            "hostname": self.hostname,
95        })
96    }
97}
98
99pub fn create_factory() -> Box<dyn ContextFactory> {
100    Box::new(MachineContextFactory)
101}