From a5749a5d8d38b0db2ce5548473f8a61b674578a6 Mon Sep 17 00:00:00 2001 From: namilsk Date: Sat, 31 Jan 2026 21:26:26 +0300 Subject: Started writing service-utils and adding docstrings --- init/src/services/unit_parser.rs | 159 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 155 insertions(+), 4 deletions(-) (limited to 'init/src/services/unit_parser.rs') diff --git a/init/src/services/unit_parser.rs b/init/src/services/unit_parser.rs index a9898c1..1e2bcc7 100644 --- a/init/src/services/unit_parser.rs +++ b/init/src/services/unit_parser.rs @@ -1,4 +1,4 @@ -// This module defines unit settings parsing logig +// This module defines unit settings parsing logig // // NOTE: ON UNIT PARSING LOGIC // when parsing a unit in /etc/vigil/units/ we shoul ignore @@ -6,10 +6,161 @@ // without "crashing" logic. // // NOTE: ON GENERAL SERVICE LOGGING -// when vigil starts service, it should send out logs to vigil? -// or logs in such init systems are just taking the stdout+stderr +// when vigil starts service, it should send out logs to vigil? +// or logs in such init systems are just taking the stdout+stderr // of service and showing its output? idk 4 now, look into how its supposed to be -use toml::display; +use crate::{log_warning, RUNLEVEL_STATE}; +use serde::Deserialize; +use std::fs::{read_dir, read_to_string}; +/* + [info] + name = "name" + description = "description" + version = "version" + [config] + exec = "path to exec" + runlevel = + restart=always|never + +*/ + +#[derive(Deserialize)] +enum Restart { + #[serde(alias = "always")] + Always, + #[serde(alias = "never")] + Never, +} + +#[derive(Deserialize, PartialEq, Eq)] +pub enum Runlevel { + /// The system is shutting down, runlevel int: 0 + Shutdown, + /// One-user system debug-mode, runlevel int: 1 + OneUser, + /// Multi-user CLI (TTY) with no network, runlevel int: 2 + MultiNoNetwork, + /// Multi-user CLI with network, runlevel int: 3 + MultiNetwork, + /// Multi-user mode with GUI, runlevel int: 5 + MultiUserGUINetwork, + /// Runlevel is not critical for running the service, runlevel int: 4 + Undefined, + /// System going too reboot, runlevel int: 6 + Reboot, +} + +#[allow(dead_code)] +#[derive(Deserialize)] +pub struct ServiceInfo { + /// Service name + name: String, + /// Service description + description: String, + /// Service version + version: String, +} + +#[allow(dead_code)] +#[derive(Deserialize)] +pub struct ServiceConfig { + /// Execution command, like ExecStart in sysd + exec: String, + /// Runlevel, like after=*.target + runlevel: Runlevel, + /// Restart service: Always|Never + restart: Restart, +} + +/// Main Unit-file struct +#[allow(dead_code)] +#[derive(Deserialize)] +pub struct Unit { + info: ServiceInfo, + config: ServiceConfig, +} + +#[allow(dead_code)] +impl Restart { + pub fn as_str(&self) -> &'static str { + match self { + Restart::Always => "always", + Restart::Never => "never", + } + } +} + +/// Function which starting services declared in `/etc/vigil/units/` +/// Based on the global runlevel variable, should be runned as second thread +pub fn execute_services() -> Result<(), Box> { + let unit_list = parse_all_units()?; + + loop { + match *RUNLEVEL_STATE.try_lock()? { + Runlevel::Undefined => { + for unit in &unit_list { + if unit.config.runlevel == Runlevel::Undefined { + std::process::Command::new(unit.config.exec.clone()); + } else { + continue; + } + } + } + Runlevel::Reboot => { + todo!(); + } + + Runlevel::Shutdown => { + todo!(); + } + + Runlevel::OneUser => { + todo!(); + } + + Runlevel::MultiNoNetwork => { + todo!(); + } + + Runlevel::MultiNetwork => { + todo!(); + } + + Runlevel::MultiUserGUINetwork => { + todo!(); + } + } + } +} + +#[allow(dead_code)] +fn parse_all_units() -> Result, Box> { + let mut units: Vec = Vec::new(); + + for unit in read_dir("/etc/vigil/units")? { + let unit_path = unit?.path(); + let unit_str: String = match read_to_string(unit_path) { + Ok(content) => content, + Err(e) => { + log_warning(&format!("Error while reading unit: {}", e)); + continue; + } + }; + + let deserialized: Result = toml::from_str(&unit_str); + match deserialized { + Ok(unit) => { + units.push(unit); + } + Err(e) => { + log_warning(&format!("Error while parsing unit: {}", e)); + continue; + } + }; + } + + Ok(units) +} -- cgit v1.2.3