A focused Docker Compose management web application.
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat: comopse view/edit

Brooke 24f175c4 c425f755

+87 -4
+39
packages/node/src/api/compose.rs
··· 1 + //! Manages retrieving and updating project compose files. 2 + 3 + use std::str::from_utf8; 4 + 5 + use eyre::Context; 6 + use salvo::Request; 7 + use salvo::Writer; 8 + use salvo::{ 9 + Depot, Router, 10 + oapi::{endpoint, extract::PathParam}, 11 + }; 12 + 13 + use crate::{api::response::LuminaryResponse, core::LuminaryEngine, obtain}; 14 + 15 + /// Returns the router for compose related endpoints. 16 + pub fn router() -> Router { 17 + return Router::with_path("compose").get(get_compose).put(put_compose); 18 + } 19 + 20 + /// Retrieves the compose file for a given project. 21 + #[endpoint] 22 + async fn get_compose(project: PathParam<String>, depot: &mut Depot) -> LuminaryResponse<String> { 23 + let engine = obtain!(depot, LuminaryEngine); 24 + return Ok(engine.get_compose(&project.into_inner()).await?.into()); 25 + } 26 + 27 + /// Updates the compose file for a given project. 28 + #[endpoint] 29 + async fn put_compose( 30 + project: PathParam<String>, 31 + req: &mut Request, 32 + depot: &mut Depot, 33 + ) -> LuminaryResponse<()> { 34 + let engine = obtain!(depot, LuminaryEngine); 35 + let bytes = req.payload().await.wrap_err("Failed to read request body")?; 36 + let compose = from_utf8(bytes).wrap_err("Failed to decode error")?; 37 + engine.put_compose(&project.into_inner(), compose).await?; 38 + return Ok(().into()); 39 + }
+3 -1
packages/node/src/api/mod.rs
··· 16 16 17 17 mod action; 18 18 mod auth; 19 - pub mod realtime; 19 + mod compose; 20 + mod realtime; 20 21 mod response; 21 22 22 23 /// Sets up the app router and all dependencies. ··· 72 73 .push(Router::with_path("realtime").get(app_subscribe)) 73 74 .push( 74 75 Router::with_path("/project/{project}") 76 + .push(compose::router()) 75 77 .push(Router::with_path("logs").get(logs_subscribe)) 76 78 .push(Router::with_path("restart").post(action::restart_project)) 77 79 .push(Router::with_path("start").post(action::start_project))
+41
packages/node/src/core/compose.rs
··· 1 + use std::path::{Path, PathBuf}; 2 + 3 + use eyre::{Context, Ok, Result}; 4 + use luminary_macros::wrap_err; 5 + use tokio::fs::read_to_string; 6 + 7 + use crate::core::{COMPOSE_FILENAME, LuminaryEngine}; 8 + 9 + impl LuminaryEngine { 10 + fn compose_path(&self, project: &str) -> Result<PathBuf> { 11 + let path = Path::new(&self.configuration.project_directory) 12 + .join(project) 13 + .join(COMPOSE_FILENAME); 14 + 15 + if !path.exists() { 16 + eyre::bail!("Project '{}' does not exist", project); 17 + } 18 + 19 + return Ok(path); 20 + } 21 + 22 + /// Retrieves the docker compose file for a given project. 23 + #[wrap_err("Failed to retrieve compose file")] 24 + pub async fn get_compose(&self, project: &str) -> Result<String> { 25 + let path = self.compose_path(project)?; 26 + 27 + return Ok(read_to_string(path).await.wrap_err("Failed to read file")?); 28 + } 29 + 30 + /// Updates the docker compose file for a given project. 31 + #[wrap_err("Failed to update compose file")] 32 + pub async fn put_compose(&self, project: &str, compose: &str) -> Result<()> { 33 + let path = self.compose_path(project)?; 34 + 35 + tokio::fs::write(path, compose) 36 + .await 37 + .wrap_err("Failed to write file")?; 38 + 39 + return Ok(()); 40 + } 41 + }
+3
packages/node/src/core/mod.rs
··· 1 1 //! The core library for Luminary, containing all logic related to managing projects and interacting with the Docker engine. 2 2 3 + pub const COMPOSE_FILENAME: &str = "compose.yml"; 4 + 3 5 mod action; 6 + mod compose; 4 7 mod configuration; 5 8 mod engine; 6 9 mod logs;
+1 -3
packages/node/src/core/state.rs
··· 14 14 use tokio::fs::{self, File}; 15 15 16 16 use crate::core::{ 17 - LuminaryAction, LuminaryEngine, LuminaryIdentifier, LuminaryServiceList, 17 + COMPOSE_FILENAME, LuminaryAction, LuminaryEngine, LuminaryIdentifier, LuminaryServiceList, 18 18 model::{LuminaryProject, LuminaryService, LuminaryStateList, LuminaryStatus}, 19 19 }; 20 20 21 21 const COMPOSE_PROJECT_DIR_LABEL: &str = "com.docker.compose.project.working_dir"; 22 22 const COMPOSE_PROJECT_LABEL: &str = "com.docker.compose.project"; 23 23 const COMPOSE_SERVICE_LABEL: &str = "com.docker.compose.service"; 24 - 25 - const COMPOSE_FILENAME: &str = "compose.yml"; 26 24 27 25 impl LuminaryEngine { 28 26 pub async fn state_subscribe<'a>(&'_ self) -> BoxStream<'a, LuminaryStateList> {