create home

This commit is contained in:
Asger Juul Brunshøj 2025-01-22 00:14:22 +01:00
parent 47df995ed1
commit e925895eab
3 changed files with 24 additions and 17 deletions

View File

@ -103,8 +103,8 @@ pub async fn main() {
} }
Command::ResetState => { Command::ResetState => {
let s = PersistentState::default(); let s = PersistentState::default();
let p = camino::Utf8Path::new(STATE_FILE); let p = Path::new(STATE_FILE);
tracing::info!("Resetting state to default: {p}"); tracing::info!("Resetting state to default: {}", p.display());
Persistent::persist(p, &s).await.unwrap_or_report(); Persistent::persist(p, &s).await.unwrap_or_report();
} }
} }

View File

@ -1,19 +1,20 @@
use camino::Utf8Path;
use camino::Utf8PathBuf; use camino::Utf8PathBuf;
use serde::Serialize; use serde::Serialize;
use serde::de::DeserializeOwned; use serde::de::DeserializeOwned;
use std::path::Path;
use std::path::PathBuf;
use std::sync::Arc; use std::sync::Arc;
use tokio::sync::Mutex; use tokio::sync::Mutex;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct Persistent<T> { pub struct Persistent<T> {
state: Arc<Mutex<T>>, state: Arc<Mutex<T>>,
file_path: Utf8PathBuf, file_path: PathBuf,
} }
impl<T> Persistent<T> { impl<T> Persistent<T> {
#[tracing::instrument(skip(state))] #[tracing::instrument(skip(state))]
pub fn new(state: T, file_path: Utf8PathBuf) -> Self { pub fn new(state: T, file_path: PathBuf) -> Self {
Self { Self {
state: Arc::new(Mutex::new(state)), state: Arc::new(Mutex::new(state)),
file_path, file_path,
@ -26,13 +27,18 @@ impl<T> Persistent<T> {
where where
T: DeserializeOwned, T: DeserializeOwned,
{ {
let file_path = file_path.canonicalize().map_err(|source| Error::BadPath {
path: file_path.clone(),
source,
})?;
let content = tokio::fs::read_to_string(&file_path).await.map_err(|source| Error::Read { let content = tokio::fs::read_to_string(&file_path).await.map_err(|source| Error::Read {
file_path: file_path.to_owned(), file_path: file_path.clone(),
source, source,
})?; })?;
let t = ron::from_str(&content).map_err(|source| Error::Deserialize { let t = ron::from_str(&content).map_err(|source| Error::Deserialize {
file_path: file_path.to_owned(), file_path: file_path.clone(),
source, source,
})?; })?;
@ -93,7 +99,7 @@ impl<T> Persistent<T> {
/// ///
/// Implicitly called by `set` and `update`. /// Implicitly called by `set` and `update`.
#[tracing::instrument(skip_all, err)] #[tracing::instrument(skip_all, err)]
pub async fn persist(file_path: &Utf8Path, state: &T) -> Result<(), Error> pub async fn persist(file_path: &Path, state: &T) -> Result<(), Error>
where where
T: Serialize, T: Serialize,
{ {
@ -110,18 +116,18 @@ impl<T> Persistent<T> {
#[derive(Debug, derive_more::Error, derive_more::Display)] #[derive(Debug, derive_more::Error, derive_more::Display)]
#[display("Persistent state error: {_variant}")] #[display("Persistent state error: {_variant}")]
pub enum Error { pub enum Error {
#[display("Failed to read file: {file_path}")] #[display("Failed to operate on path: {path}")]
Read { file_path: Utf8PathBuf, source: std::io::Error }, BadPath { path: Utf8PathBuf, source: std::io::Error },
#[display("Failed to deserialize state from file: {file_path}")] #[display("Failed to read file: {}", file_path.display())]
Deserialize { Read { file_path: PathBuf, source: std::io::Error },
file_path: Utf8PathBuf,
source: ron::error::SpannedError, #[display("Failed to deserialize state from file: {}", file_path.display())]
}, Deserialize { file_path: PathBuf, source: ron::error::SpannedError },
#[display("Failed to serialize state")] #[display("Failed to serialize state")]
Serialize { source: ron::Error }, Serialize { source: ron::Error },
#[display("Failed to write file: {file_path}")] #[display("Failed to write file: {}", file_path.display())]
Write { file_path: Utf8PathBuf, source: std::io::Error }, Write { file_path: PathBuf, source: std::io::Error },
} }

View File

@ -96,6 +96,7 @@
home = "/home/ascend"; home = "/home/ascend";
group = "ascend"; group = "ascend";
description = "Ascend service user"; description = "Ascend service user";
createHome = true;
}; };
users.groups.ascend = { }; users.groups.ascend = { };
systemd.services.ascend = { systemd.services.ascend = {