init: Introduce UnitStore
This will be necessary to store persistent information about units like if they are currently started and which process is associated with them.
This commit is contained in:
+97
-14
@@ -1,13 +1,71 @@
|
||||
use std::path::Path;
|
||||
use std::collections::BTreeMap;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::{fs, io};
|
||||
|
||||
use serde::Deserialize;
|
||||
|
||||
use crate::SwitchRoot;
|
||||
use crate::script::Script;
|
||||
use crate::service::Service;
|
||||
|
||||
pub struct UnitStore {
|
||||
pub config_dirs: Vec<PathBuf>,
|
||||
units: BTreeMap<UnitId, Unit>,
|
||||
}
|
||||
|
||||
impl UnitStore {
|
||||
pub fn new() -> Self {
|
||||
UnitStore {
|
||||
config_dirs: vec![],
|
||||
units: BTreeMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn load_units(&mut self) -> (Vec<UnitId>, Vec<String>) {
|
||||
let mut loaded_units = vec![];
|
||||
let mut errors = vec![];
|
||||
|
||||
let entries = match config::config_for_dirs(&self.config_dirs) {
|
||||
Ok(entries) => entries,
|
||||
Err(err) => {
|
||||
errors.push(format!(
|
||||
"failed to read configs from {}: {err}",
|
||||
self.config_dirs
|
||||
.iter()
|
||||
.map(|dir| dir.display().to_string())
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ")
|
||||
));
|
||||
return (loaded_units, errors);
|
||||
}
|
||||
};
|
||||
|
||||
for entry in entries {
|
||||
let (unit, new_errors) = match Unit::from_file(&entry) {
|
||||
Ok(unit) => unit,
|
||||
Err(err) => {
|
||||
errors.push(format!("{}: {err}", entry.display()));
|
||||
continue;
|
||||
}
|
||||
};
|
||||
errors.extend(new_errors);
|
||||
loaded_units.push(unit.id.clone());
|
||||
self.units.insert(unit.id.clone(), unit);
|
||||
}
|
||||
|
||||
(loaded_units, errors)
|
||||
}
|
||||
|
||||
pub fn unit_mut(&mut self, unit: &UnitId) -> &mut Unit {
|
||||
self.units.get_mut(unit).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub struct UnitId(pub String);
|
||||
|
||||
pub struct Unit {
|
||||
pub name: String,
|
||||
pub id: UnitId,
|
||||
|
||||
pub info: UnitInfo,
|
||||
pub kind: UnitKind,
|
||||
@@ -15,17 +73,17 @@ pub struct Unit {
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct UnitInfo {
|
||||
pub description: Option<String>,
|
||||
#[serde(default)]
|
||||
description: String,
|
||||
pub requires: Vec<String>,
|
||||
#[serde(default)]
|
||||
requires: Vec<String>,
|
||||
#[serde(default)]
|
||||
requires_weak: Vec<String>,
|
||||
pub requires_weak: Vec<String>,
|
||||
}
|
||||
|
||||
pub enum UnitKind {
|
||||
LegacyScript { script: Script },
|
||||
Service { service: Service },
|
||||
SwitchRoot { switchroot: SwitchRoot },
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
@@ -34,14 +92,22 @@ struct SerializedService {
|
||||
service: Service,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct SerializedSwitchRoot {
|
||||
unit: UnitInfo,
|
||||
switchroot: SwitchRoot,
|
||||
}
|
||||
|
||||
impl Unit {
|
||||
pub fn from_file(config_path: &Path) -> io::Result<(Self, Vec<String>)> {
|
||||
let name = config_path
|
||||
.file_name()
|
||||
.unwrap()
|
||||
.to_str()
|
||||
.unwrap()
|
||||
.to_owned();
|
||||
let name = UnitId(
|
||||
config_path
|
||||
.file_name()
|
||||
.unwrap()
|
||||
.to_str()
|
||||
.unwrap()
|
||||
.to_owned(),
|
||||
);
|
||||
|
||||
let config = fs::read_to_string(config_path)?;
|
||||
|
||||
@@ -50,7 +116,7 @@ impl Unit {
|
||||
let (script, warnings) = Script::from_str(&config)?;
|
||||
(
|
||||
UnitInfo {
|
||||
description: "".to_owned(),
|
||||
description: None,
|
||||
requires: vec![],
|
||||
requires_weak: vec![],
|
||||
},
|
||||
@@ -68,9 +134,26 @@ impl Unit {
|
||||
vec![],
|
||||
)
|
||||
}
|
||||
Some("switchroot") => {
|
||||
let switchroot: SerializedSwitchRoot = serde_json::from_str(&config)?;
|
||||
(
|
||||
switchroot.unit,
|
||||
UnitKind::SwitchRoot {
|
||||
switchroot: switchroot.switchroot,
|
||||
},
|
||||
vec![],
|
||||
)
|
||||
}
|
||||
Some(_) => return Err(io::Error::other("invalid file extension")),
|
||||
};
|
||||
|
||||
Ok((Unit { name, info, kind }, errors))
|
||||
Ok((
|
||||
Unit {
|
||||
id: name,
|
||||
info,
|
||||
kind,
|
||||
},
|
||||
errors,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user