1use enum_iterator::IntoEnumIterator;
3use log::warn;
4use serde::{Deserialize, Serialize};
5use std::collections::{BTreeMap, BTreeSet};
6use std::fmt::Write;
7
8use rd_util::*;
9
10const SYSREQ_DOC: &str = "\
11//
12// rd-agent system requirements report
13//
14// satisfied: List of satifised system requirements
15// missed: List of missed system requirements
16// scr_dev_model: Scratch storage device model string
17// scr_dev_fwrev: Scratch storage device firmware revision string
18// scr_dev_size: Scratch storage device size
19// swap_size: Swap size
20//
21";
22
23lazy_static::lazy_static! {
24 pub static ref ALL_SYSREQS_SET: BTreeSet<SysReq> = SysReq::into_enum_iter().collect();
25}
26
27#[derive(
28 Debug,
29 Clone,
30 Copy,
31 PartialEq,
32 Eq,
33 PartialOrd,
34 Ord,
35 Hash,
36 IntoEnumIterator,
37 Serialize,
38 Deserialize,
39)]
40pub enum SysReq {
41 Controllers,
42 Freezer,
43 MemCgRecursiveProt,
44 MemShadowInodeProt, IoCost,
46 IoCostVer,
47 NoOtherIoControllers,
48 AnonBalance,
49 Btrfs,
50 BtrfsAsyncDiscard,
51 NoCompositeStorage,
52 IoSched,
53 NoWbt,
54 SwapOnScratch,
55 Swap,
56 Oomd,
57 NoSysOomd,
58 HostCriticalServices,
59 DepsBase,
60 DepsIoCostCoefGen,
61 DepsSide,
62 DepsLinuxBuild,
63}
64
65#[derive(Clone, Debug, Default, Serialize, Deserialize)]
66pub struct MissedSysReqs {
67 #[serde(flatten)]
68 pub map: BTreeMap<SysReq, Vec<String>>,
69}
70
71impl MissedSysReqs {
72 pub fn add_quiet(&mut self, req: SysReq, msg: &str) {
73 match self.map.get_mut(&req) {
74 Some(msgs) => msgs.push(msg.to_string()),
75 None => {
76 self.map.insert(req, vec![msg.to_string()]);
77 }
78 }
79 }
80
81 pub fn add(&mut self, req: SysReq, msg: &str) {
82 self.add_quiet(req, msg);
83 warn!("cfg: {}", msg);
84 }
85
86 pub fn format<'a>(&self, out: &mut Box<dyn Write + 'a>) {
87 writeln!(
88 out,
89 "Missed sysreqs: {}",
90 &self
91 .map
92 .keys()
93 .map(|x| format!("{:?}", x))
94 .collect::<Vec<String>>()
95 .join(", ")
96 )
97 .unwrap();
98
99 for (_req, msgs) in self.map.iter() {
100 for msg in msgs.iter() {
101 writeln!(out, " * {}", msg).unwrap();
102 }
103 }
104 }
105}
106
107#[derive(Clone, Debug, Default, Serialize, Deserialize)]
108pub struct SysReqsReport {
109 pub satisfied: BTreeSet<SysReq>,
110 pub missed: MissedSysReqs,
111 pub kernel_version: String,
112 pub agent_version: String,
113 pub hashd_version: String,
114 pub nr_cpus: usize,
115 pub total_memory: usize,
116 pub total_swap: usize,
117 pub scr_dev: String,
118 pub scr_devnr: (u32, u32),
119 pub scr_dev_model: String,
120 pub scr_dev_fwrev: String,
121 pub scr_dev_size: u64,
122 pub scr_dev_iosched: String,
123 pub enforce: super::EnforceConfig,
124}
125
126impl JsonLoad for SysReqsReport {}
127
128impl JsonSave for SysReqsReport {
129 fn preamble() -> Option<String> {
130 Some(SYSREQ_DOC.to_string())
131 }
132}