From 096d44ae5920e05c50403024a0792f1fb95f99e4 Mon Sep 17 00:00:00 2001 From: Hamcha Date: Sat, 25 Nov 2023 01:38:56 +0100 Subject: [PATCH] add remove --- src/node/git.rs | 46 +++++++++------ src/node/stack.rs | 21 +++++++ src/route/stack.rs | 30 +++++++++- templates/container/get-one.html | 98 ++------------------------------ templates/home.html | 10 ++-- templates/stack/delete-one.html | 25 ++++++++ templates/stack/get-one.html | 22 ++----- 7 files changed, 120 insertions(+), 132 deletions(-) create mode 100644 templates/stack/delete-one.html diff --git a/src/node/git.rs b/src/node/git.rs index 19e18be..51eaab8 100644 --- a/src/node/git.rs +++ b/src/node/git.rs @@ -1,5 +1,5 @@ use anyhow::{anyhow, Result}; -use git2::{ErrorCode, IndexAddOption, Repository, Signature}; +use git2::{ErrorCode, Index, IndexAddOption, Oid, Repository, Signature}; use std::path::{Path, PathBuf}; use tracing::info; @@ -40,9 +40,6 @@ impl ThreadSafeRepository { index.add_all(["*/*.nix"].iter(), IndexAddOption::DEFAULT, None)?; let oid = index.write_tree()?; let tree = repo.find_tree(oid)?; - - // This prevents a nasty condition where the index goes all wack, - // but it's probably a mistake somewhere else index.write()?; let signature = Signature::now(&config.author_name, &config.author_email)?; @@ -71,24 +68,15 @@ impl ThreadSafeRepository { Repository::open(&self.path) } - pub fn commit_files(&self, paths: &[&Path], message: &str) -> Result<()> { - let repository = self.repository()?; + fn commit(&self, repository: Repository, mut index: Index, message: &str) -> Result { + index.write()?; - // Commit file - let mut index = repository.index()?; - for path in paths { - index.add_path(path)?; - } let oid = index.write_tree()?; let tree = repository.find_tree(oid)?; let head = repository.head()?; - // This prevents a nasty condition where the index goes all wack, - // but it's probably a mistake somewhere else - index.write()?; - let signature = Signature::now(&self.config.author_name, &self.config.author_email)?; - repository.commit( + let oid = repository.commit( Some("HEAD"), &signature, &signature, @@ -98,6 +86,32 @@ impl ThreadSafeRepository { )?; drop(tree); + Ok(oid) + } + + pub fn commit_files(&self, paths: &[&Path], message: &str) -> Result<()> { + let repository = self.repository()?; + + // Commit file + let mut index = repository.index()?; + for path in paths { + index.add_path(path)?; + } + + self.commit(repository, index, message)?; + + Ok(()) + } + + pub fn remove_folder(&self, path: &Path, message: &str) -> Result<()> { + let repository = self.repository()?; + + // Commit file + let mut index = repository.index()?; + index.remove_dir(path, 0)?; + + self.commit(repository, index, message)?; + Ok(()) } } diff --git a/src/node/stack.rs b/src/node/stack.rs index d6bea7c..241a617 100644 --- a/src/node/stack.rs +++ b/src/node/stack.rs @@ -186,6 +186,27 @@ pub async fn create_new( Ok(()) } +pub async fn remove( + base_dir: &Path, + arion_bin: &Path, + repository: ThreadSafeRepository, + stack_name: &str, +) -> Result<()> { + // Remove all containers and resources + command(base_dir, stack_name, arion_bin, StackCommand::Down).await?; + + // Remove from repository + repository.remove_folder( + &PathBuf::from(stack_name), + format!("Removed stack {}", stack_name).as_str(), + )?; + + // Remove from disk + fs::remove_dir_all(repository.path.join(stack_name)).await?; + + Ok(()) +} + pub async fn check_compose(arion_bin: &Path, source: &str) -> Result<()> { // Check that it's a valid nix tree rnix::Root::parse(source) diff --git a/src/route/stack.rs b/src/route/stack.rs index 29315de..44733e3 100644 --- a/src/route/stack.rs +++ b/src/route/stack.rs @@ -7,7 +7,7 @@ use crate::{ container::ContainerInfo, stack::{ check_compose, command, commit_compose, create_new, get_compose, get_containers, - write_compose, StackCommand, + remove, write_compose, StackCommand, }, }, AppState, @@ -37,6 +37,12 @@ struct GetOneTemplate { #[template(path = "stack/new-form.html")] struct CreateTemplate {} +#[derive(Template)] +#[template(path = "stack/delete-one.html")] +struct ConfirmDeleteTemplate { + stack_name: String, +} + async fn get_one(Path(stack_name): Path, State(state): State) -> HandlerResponse { let (file_contents_res, containers_res) = join!( get_compose(&state.stack_dir, &stack_name), @@ -139,6 +145,24 @@ async fn check_stack_file( Ok(StatusCode::NO_CONTENT) } +async fn confirm_deletion_page(Path(stack_name): Path) -> impl IntoResponse { + ConfirmDeleteTemplate { stack_name } +} + +async fn delete_stack( + Path(stack_name): Path, + State(state): State, +) -> Result { + remove( + &state.stack_dir, + &state.arion_bin, + state.repository, + &stack_name, + ) + .await?; + Ok(Redirect::to("/")) +} + macro_rules! stack_command { ($cmd: expr) => { move |Path(stack_name): Path, State(state): State| async move { @@ -167,4 +191,8 @@ pub(super) fn router() -> Router { .route("/:stack/stop", post(stack_command!(StackCommand::Stop))) .route("/:stack/down", post(stack_command!(StackCommand::Down))) .route("/:stack/edit", post(edit_stack)) + .route( + "/:stack/delete", + get(confirm_deletion_page).post(delete_stack), + ) } diff --git a/templates/container/get-one.html b/templates/container/get-one.html index 165f534..4f5fd39 100644 --- a/templates/container/get-one.html +++ b/templates/container/get-one.html @@ -71,6 +71,7 @@ +