flowey_lib_common/
system_info.rs1use flowey::node::prelude::*;
7use std::collections::BTreeMap;
8
9new_simple_flow_node!(struct Node);
10
11flowey_request! {
12 pub struct Request {
13 pub done: WriteVar<SideEffect>,
14 }
15}
16
17impl SimpleFlowNode for Node {
18 type Request = Request;
19
20 fn imports(_dep: &mut ImportCtx<'_>) {
21 }
23
24 fn process_request(request: Self::Request, ctx: &mut NodeCtx<'_>) -> anyhow::Result<()> {
25 ctx.emit_rust_step("print system info", |ctx| {
26 request.done.claim(ctx);
27 |rt| {
28 print_system_info(rt);
29 Ok(())
30 }
31 });
32
33 Ok(())
34 }
35}
36
37fn bytes_to_gibibytes(bytes: u64) -> f64 {
38 bytes as f64 / (1024 * 1024 * 1024) as f64
39}
40
41fn print_system_info(rt: &mut RustRuntimeServices<'_>) {
42 use sysinfo::{Disks, Networks, System};
43 let sys = System::new_all();
44
45 log::info!(
46 "Memory: {:.1} GB / {:.1} GB",
47 bytes_to_gibibytes(sys.used_memory()),
48 bytes_to_gibibytes(sys.total_memory())
49 );
50
51 let cpu_list = sys
52 .cpus()
53 .iter()
54 .map(|cpu| (cpu.vendor_id(), cpu.brand(), cpu.frequency()))
55 .collect::<Vec<_>>();
56
57 let mut cpus = BTreeMap::new();
58 for key in cpu_list {
59 let count = cpus.entry(key).or_insert(0u64);
60 *count += 1;
61 }
62
63 for ((vendor, brand, freq), count) in cpus {
64 log::info!("CPU: {vendor} [{brand}] @ {freq} MHz × {count}");
65 }
66
67 let os_info = [
68 System::name(),
69 System::os_version(),
70 System::kernel_version(),
71 ]
72 .into_iter()
73 .flatten()
74 .collect::<Vec<_>>()
75 .join(" ");
76 log::info!("OS: {}", os_info);
77 log::info!("Hostname: {}", System::host_name().unwrap_or_default());
78
79 let disks = Disks::new_with_refreshed_list();
80 for disk in &disks {
81 let used_space = disk.total_space() - disk.available_space();
82 log::info!(
83 "Disk: {} {:.1} GB / {:.1} GB",
84 disk.mount_point().display(),
85 bytes_to_gibibytes(used_space),
86 bytes_to_gibibytes(disk.total_space())
87 );
88 }
89
90 let networks = Networks::new_with_refreshed_list();
91 for (interface_name, data) in &networks {
92 let ip_addresses = data
93 .ip_networks()
94 .iter()
95 .map(|ip| ip.to_string())
96 .collect::<Vec<_>>()
97 .join(" ");
98 log::info!("Network: {interface_name} {ip_addresses}");
99 }
100
101 let is_uefi = match rt.platform() {
102 FlowPlatform::Windows => std::process::Command::new("bcdedit")
103 .output()
104 .ok()
105 .and_then(|o| o.status.success().then(|| String::from_utf8(o.stdout).ok()))
106 .flatten()
107 .map(|o| o.to_lowercase().contains(".efi")),
108 FlowPlatform::Linux(_) => Path::new("/sys/firmware/efi").try_exists().ok(),
109 _ => None,
110 };
111
112 match is_uefi {
113 Some(true) => log::info!("Using UEFI firmware"),
114 Some(false) => log::info!("Not using UEFI firmware"),
115 None => log::info!("Unknown firmware"),
116 }
117}