diff options
author | Lia Lenckowski <lialenck@protonmail.com> | 2025-01-25 18:25:10 +0100 |
---|---|---|
committer | Lia Lenckowski <lialenck@protonmail.com> | 2025-01-25 18:25:10 +0100 |
commit | 5ca87020739fec5edd86b7f2e9acd3d9ee8498d5 (patch) | |
tree | 1763cb4e4754644c467e956048accc2792f5e655 | |
parent | 0c332494968515621099273bdc2c99d5a1f6df7f (diff) | |
download | statuspage-5ca87020739fec5edd86b7f2e9acd3d9ee8498d5.tar statuspage-5ca87020739fec5edd86b7f2e9acd3d9ee8498d5.tar.bz2 statuspage-5ca87020739fec5edd86b7f2e9acd3d9ee8498d5.tar.zst |
consider systemd services in 'start' or 'mounting' good; fmt
-rw-r--r-- | src/check.rs | 16 | ||||
-rw-r--r-- | src/dbus.rs | 89 | ||||
-rw-r--r-- | src/main.rs | 2 | ||||
-rw-r--r-- | src/web.rs | 19 |
4 files changed, 87 insertions, 39 deletions
diff --git a/src/check.rs b/src/check.rs index b0230e8..a96de5b 100644 --- a/src/check.rs +++ b/src/check.rs @@ -83,18 +83,10 @@ impl Check { output.status.exit_ok()?; Ok(String::from_utf8(output.stdout)?) } - Check::Systemd(name) => { - check_systemd_unit(None, name).await - } - Check::SystemdGlobal => { - check_systemd_all(None).await - } - Check::SystemdUser { user, name } => { - check_systemd_unit(Some(user), name).await - } - Check::SystemdUserGlobal(user) => { - check_systemd_all(Some(user)).await - } + Check::Systemd(name) => check_systemd_unit(None, name).await, + Check::SystemdGlobal => check_systemd_all(None).await, + Check::SystemdUser { user, name } => check_systemd_unit(Some(user), name).await, + Check::SystemdUserGlobal(user) => check_systemd_all(Some(user)).await, Check::Shell { command, output, .. } => { diff --git a/src/dbus.rs b/src/dbus.rs index d23c7b6..1bc5655 100644 --- a/src/dbus.rs +++ b/src/dbus.rs @@ -1,14 +1,24 @@ use anyhow::{anyhow, Result}; use serde::{Deserialize, Serialize}; +use std::{ + collections::{btree_map::Entry::*, BTreeMap}, + path::PathBuf, + sync::Arc, +}; +use tokio::sync::Mutex; use zbus::{ - proxy, Proxy, + address::{ + transport::{Transport, Unix, UnixSocket}, + Address, + }, + connection::Builder, + proxy, zvariant::{OwnedObjectPath, Type}, - Connection, connection::Builder, address::{Address, transport::{Unix, Transport, UnixSocket}}, + Connection, Proxy, }; -use std::{sync::Arc, collections::{BTreeMap, btree_map::Entry::*}, path::PathBuf}; -use tokio::sync::Mutex; -static CONNECTIONS: Mutex<(BTreeMap<String, Arc<Connection>>, Option<Arc<Connection>>)> = Mutex::const_new((BTreeMap::new(), None)); +static CONNECTIONS: Mutex<(BTreeMap<String, Arc<Connection>>, Option<Arc<Connection>>)> = + Mutex::const_new((BTreeMap::new(), None)); #[derive(Debug, Type, Deserialize, Serialize)] struct ServiceStatus { @@ -43,7 +53,7 @@ async fn ensure_system_conn() -> Result<Arc<Connection>> { let system_bus = Arc::new(Connection::system().await?); connections.1 = Some(system_bus.clone()); Ok(system_bus) - }, + } } } @@ -55,14 +65,19 @@ async fn ensure_user_conn(user: &str) -> Result<Arc<Connection>> { Vacant(ve) => { let mut path = PathBuf::new(); path.push("/run/user"); - path.push(format!("{}", users::get_user_by_name(user).ok_or(anyhow!("Couldn't find user"))?.uid())); + path.push(format!( + "{}", + users::get_user_by_name(user) + .ok_or(anyhow!("Couldn't find user"))? + .uid() + )); path.push("bus"); let trans = Transport::Unix(Unix::new(UnixSocket::File(path))); let conn = Builder::address(Address::new(trans))?.build().await?; Ok(ve.insert(Arc::new(conn)).clone()) - }, + } } } @@ -74,15 +89,32 @@ pub(crate) async fn check_systemd_all(user: Option<&str>) -> Result<String> { let manager = ManagerProxy::new(&conn).await?; - let (good, bad) = manager.list_units().await?.into_iter().fold((0, vec![]), |(old_good, mut old_bad), unit| { - if matches!(unit.substate.as_str(), "active" | "inactive" | "plugged" | "mounted" | "dead" | "listening" | "running" | "exited" | "waiting" | "abandoned" | "elapsed") { - (old_good + 1, old_bad) - } - else { - old_bad.push(format!("{}: {}", unit.name, unit.substate)); - (old_good, old_bad) - } - }); + let (good, bad) = manager.list_units().await?.into_iter().fold( + (0, vec![]), + |(old_good, mut old_bad), unit| { + if matches!( + unit.substate.as_str(), + "active" + | "inactive" + | "plugged" + | "mounted" + | "mounting" + | "dead" + | "listening" + | "running" + | "exited" + | "waiting" + | "abandoned" + | "elapsed" + | "start" + ) { + (old_good + 1, old_bad) + } else { + old_bad.push(format!("{}: {}", unit.name, unit.substate)); + (old_good, old_bad) + } + }, + ); if bad.is_empty() { Ok(format!("{good} good services")) @@ -104,10 +136,29 @@ pub(crate) async fn check_systemd_unit(user: Option<&str>, unit: &str) -> Result manager.get_unit(&format!("{unit}.service")).await }?; - let unit_proxy = Proxy::new(&conn, "org.freedesktop.systemd1", unit_object_path, "org.freedesktop.systemd1.Unit").await?; + let unit_proxy = Proxy::new( + &conn, + "org.freedesktop.systemd1", + unit_object_path, + "org.freedesktop.systemd1.Unit", + ) + .await?; let substate: String = unit_proxy.get_property("SubState").await?; - if matches!(substate.as_str(), "active" | "inactive" | "plugged" | "mounted" | "dead" | "listening" | "running" | "exited" | "waiting" | "abandoned" | "elapsed") { + if matches!( + substate.as_str(), + "active" + | "inactive" + | "plugged" + | "mounted" + | "dead" + | "listening" + | "running" + | "exited" + | "waiting" + | "abandoned" + | "elapsed" + ) { Ok(format!("{unit}: {substate}")) } else { Err(anyhow!("{unit}: {substate}")) diff --git a/src/main.rs b/src/main.rs index 69034b3..95ce6b7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,10 +1,10 @@ #![feature(exit_status_error)] pub mod api; pub mod check; +pub mod dbus; pub mod log; pub mod mail; pub mod web; -pub mod dbus; use ::log::error; use anyhow::{anyhow, Result}; @@ -14,11 +14,16 @@ pub async fn make_html_page(config: Arc<Config>) -> String { let css = include_str!("style.css"); #[cfg(debug_assertions)] let css = tokio::fs::read_to_string("src/style.css").await.unwrap(); - - - let total_err = status.values().map(|s|s.status.is_err() as usize).sum::<usize>(); - let total_ok = status.values().map(|s|s.status.is_ok() as usize).sum::<usize>(); - + + let total_err = status + .values() + .map(|s| s.status.is_err() as usize) + .sum::<usize>(); + let total_ok = status + .values() + .map(|s| s.status.is_ok() as usize) + .sum::<usize>(); + markup::new! { @doctype() html { @@ -44,14 +49,14 @@ pub async fn make_html_page(config: Arc<Config>) -> String { div.log { h2 { "Past Events" } ul { - @for event in log.iter() { + @for event in log.iter() { li.{if event.status.status.is_ok() { "ok" } else { "error" }} { @let service = &config.services[event.service]; b { @event.status.time.to_rfc2822() ": " } @service.title " " @if let Err(error) = &event.status.status { " failed. " @service.checks[event.check].display() " reported " @error - } else { + } else { " is working again." } } |