staxman-old/src/stack/mod.rs

91 lines
2.2 KiB
Rust

use anyhow::Result;
use futures_util::future::join_all;
use serde::Serialize;
use std::{collections::HashMap, path::Path};
use tokio::fs;
use crate::node::{container::ContainerInfo, error::StackError};
pub mod arion;
pub mod compose;
pub mod list;
pub mod operation;
mod utils;
#[derive(Serialize)]
pub struct ServiceInfo {
name: String,
container: Option<String>,
running: bool,
}
#[derive(Serialize)]
pub struct NodeInfo {
pub stacks: Vec<StackInfo>,
pub containers: Vec<ContainerInfo>,
}
#[derive(Serialize)]
pub struct StackInfo {
pub folder: String,
pub name: String,
pub active: bool,
pub services: Vec<ServiceInfo>,
}
pub const COMPOSE_FILE: &str = "arion-compose.nix";
pub const PACKAGE_FILE: &str = "arion-pkgs.nix";
const PACKAGE_CONTENTS: &str = r#"import <nixpkgs> { system = "x86_64-linux"; }
"#;
pub type FileList = HashMap<String, String>;
pub async fn get(base_dir: &Path, stack_name: &str) -> Result<FileList> {
let dir = base_dir.join(stack_name);
if !utils::is_stack(&dir).await? {
return Err(StackError::NotFound.into());
}
let mut files = vec![];
let mut dirs = fs::read_dir(&dir).await?;
while let Some(entry) = dirs.next_entry().await? {
let meta = entry.metadata().await?;
if meta.is_dir() {
continue;
};
let path = dir.join(entry.path());
files.push(tokio::spawn(async move {
fs::read_to_string(path)
.await
.map(|content| (entry.file_name().to_string_lossy().into_owned(), content))
}));
}
Ok(join_all(files)
.await
.into_iter()
.collect::<Result<Result<_, _>, _>>()??)
}
pub async fn write(base_dir: &Path, stack_name: &str, files: &FileList) -> Result<()> {
let dir = base_dir.join(stack_name);
if !utils::is_stack(&dir).await? {
return Err(StackError::NotFound.into());
}
join_all(
files
.iter()
.map(|(name, content)| (dir.join(name), content))
.map(|(path, content)| async move { fs::write(path, content).await }),
)
.await
.into_iter()
.collect::<Result<Vec<_>, _>>()?;
Ok(())
}