1use anyhow::{Context, Result};
2use kelpdot_macros::*;
3use serde::{Deserialize, Serialize};
4use std::path::Path;
5#[derive(Debug, Serialize, Deserialize, Clone)]
6pub struct Os {
7 pub name: String,
9 pub file: String,
11 pub priority: i16,
18 pub prettyname: String,
20 pub submatches: Vec<String>,
22}
23pub fn build_os_list() -> Result<Vec<Os>> {
25 let mut osyaml: Vec<Os> = vec![];
26 let search_paths = vec!["/etc/kelpdot/os.yaml", "/etc/kelpdot/os.yml"];
27 for path in search_paths {
28 if Path::new(path).exists() {
29 debug_print!("Reading OS file {}", path);
30 let content = std::fs::read_to_string(path)
31 .with_context(|| red!("Unable to read OS file {}", path))?;
32 let yaml: Vec<Os> = serde_yaml::from_str(&content)
33 .with_context(|| red!("Failed to parse OS file {}", path))?;
34 for os in yaml {
35 osyaml.push(os);
36 }
37 }
38 }
39 debug_print!("Reading bundled OS file...");
40 let bundled = include_str!("../../config/oses.yaml");
41 let oses: Vec<Os> = serde_yaml::from_str(&bundled).with_context(|| {
42 red!("Unable to parse bundled OS list file (please report this with a GitHub issue)")
43 })?;
44 for os in oses {
45 osyaml.push(os);
46 }
47 Ok(osyaml)
48}
49pub fn get_host_os() -> anyhow::Result<Os> {
51 let oses = build_os_list()?;
53 let mut validoses: Vec<Os> = vec![];
54 for system in oses {
55 if Path::new(&system.file).exists() && system.name != "generic" {
56 validoses.push(system);
57 }
58 }
59 let mut sys: Os = Os {
60 name: String::from("generic"),
61 file: String::from("/"),
62 priority: 0,
63 prettyname: String::from("Generic GNU/Linux OS"),
64 submatches: vec![],
65 };
66 for system in validoses {
67 if sys.priority < system.priority {
68 sys = system;
69 }
70 }
71 Ok(sys)
72}
73
74pub fn is_os(name: &str) -> Result<bool> {
75 let os = get_host_os()?;
76 if os.submatches.iter().any(|x| x == name) || os.name == name {
77 return Ok(true);
78 }
79 Ok(false)
80}