From bcab4948e3798da2cb5bd830ce0ad70496e6021f Mon Sep 17 00:00:00 2001 From: Jef Roosens Date: Sun, 16 Jul 2023 19:59:47 +0200 Subject: [PATCH] feat(server): add routes for deleting repo and arch-repo --- Cargo.lock | 13 ++++++++++ server/Cargo.toml | 1 + server/src/error.rs | 6 +++++ server/src/main.rs | 2 +- server/src/repo/manager.rs | 8 +++--- server/src/repo/mod.rs | 53 ++++++++++++++++++++++++++++---------- server/src/repo/package.rs | 3 ++- 7 files changed, 68 insertions(+), 18 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a21623e..678793c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -718,6 +718,7 @@ dependencies = [ "tokio-util", "tower", "tower-http", + "tracing", "tracing-subscriber", "uuid", ] @@ -983,9 +984,21 @@ dependencies = [ "cfg-if", "log", "pin-project-lite", + "tracing-attributes", "tracing-core", ] +[[package]] +name = "tracing-attributes" +version = "0.1.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "tracing-core" version = "0.1.31" diff --git a/server/Cargo.toml b/server/Cargo.toml index 053bd93..2500d62 100644 --- a/server/Cargo.toml +++ b/server/Cargo.toml @@ -14,5 +14,6 @@ tokio = { version = "1.29.1", features = ["full"] } tokio-util = { version = "0.7.8", features = ["io"] } tower = { version = "0.4.13", features = ["make"] } tower-http = { version = "0.4.1", features = ["fs", "trace"] } +tracing = "0.1.37" tracing-subscriber = { version = "0.3.17", features = ["env-filter"] } uuid = { version = "1.4.0", features = ["v4"] } diff --git a/server/src/error.rs b/server/src/error.rs index 8993dec..fa58962 100644 --- a/server/src/error.rs +++ b/server/src/error.rs @@ -43,3 +43,9 @@ impl From for ServerError { ServerError::Axum(err) } } + +impl From for ServerError { + fn from(err: tokio::task::JoinError) -> Self { + ServerError::IO(err.into()) + } +} diff --git a/server/src/main.rs b/server/src/main.rs index 3f15f16..0d841d8 100644 --- a/server/src/main.rs +++ b/server/src/main.rs @@ -34,7 +34,7 @@ impl FromRef for Arc> { async fn main() { tracing_subscriber::registry() .with(tracing_subscriber::EnvFilter::new( - std::env::var("RUST_LOG").unwrap_or_else(|_| "tower_http=debug".into()), + std::env::var("RUST_LOG").unwrap_or_else(|_| "tower_http=debug,rieterd=debug".into()), )) .with(tracing_subscriber::fmt::layer()) .init(); diff --git a/server/src/repo/manager.rs b/server/src/repo/manager.rs index e3e7c5a..d300f4c 100644 --- a/server/src/repo/manager.rs +++ b/server/src/repo/manager.rs @@ -150,7 +150,8 @@ impl RepoGroupManager { if !repo_dir.exists() { Ok(false) } else { - fs::remove_dir_all(&repo_dir).and(fs::remove_dir_all(self.pkg_dir.join(repo)))?; + fs::remove_dir_all(&repo_dir) + .and_then(|_| fs::remove_dir_all(self.pkg_dir.join(repo)))?; Ok(true) } @@ -158,12 +159,13 @@ impl RepoGroupManager { pub fn remove_arch_repo(&mut self, repo: &str, arch: &str) -> io::Result { let sub_path = PathBuf::from(repo).join(arch); - let repo_dir = self.repo_dir.join(&repo).join(&sub_path); + let repo_dir = self.repo_dir.join(&sub_path); if !repo_dir.exists() { Ok(false) } else { - fs::remove_dir_all(&repo_dir).and(fs::remove_dir_all(self.pkg_dir.join(sub_path)))?; + fs::remove_dir_all(&repo_dir) + .and_then(|_| fs::remove_dir_all(self.pkg_dir.join(sub_path)))?; Ok(true) } diff --git a/server/src/repo/mod.rs b/server/src/repo/mod.rs index 265f677..4f5c573 100644 --- a/server/src/repo/mod.rs +++ b/server/src/repo/mod.rs @@ -5,15 +5,11 @@ pub use manager::RepoGroupManager; use axum::extract::{BodyStream, Path, State}; use axum::http::StatusCode; -use axum::response::IntoResponse; -use axum::routing::{get_service, post}; +use axum::routing::{delete, get_service, post}; use axum::Router; use futures::StreamExt; -use futures::TryFutureExt; -use futures::TryStreamExt; -use std::io::Read; use std::sync::Arc; -use tokio::{fs, io, io::AsyncWriteExt}; +use tokio::{fs, io::AsyncWriteExt}; use tower_http::services::ServeDir; use uuid::Uuid; @@ -25,8 +21,11 @@ pub fn router(global: &crate::Global) -> Router { Router::new() .route( "/:repo", - post(post_package_archive).get(serve_repos.clone()), + post(post_package_archive) + .delete(delete_repo) + .get(serve_repos.clone()), ) + .route("/:repo/:arch", delete(delete_arch_repo)) .fallback(serve_repos) .with_state(global.clone()) } @@ -36,10 +35,6 @@ async fn post_package_archive( Path(repo): Path, mut body: BodyStream, ) -> crate::Result<()> { - // let mut body_reader = tokio_util::io::StreamReader::new( - // body.map_err(|err| io::Error::new(io::ErrorKind::Other, err)), - // ); - // We first stream the uploaded file to disk let uuid: uuid::fmt::Simple = Uuid::new_v4().into(); let path = global.config.pkg_dir.join(uuid.to_string()); @@ -51,8 +46,40 @@ async fn post_package_archive( let clone = Arc::clone(&global.repo_manager); tokio::task::spawn_blocking(move || clone.write().unwrap().add_pkg_from_path(&repo, &path)) - .await - .map_err(io::Error::from)??; + .await??; Ok(()) } + +async fn delete_repo( + State(global): State, + Path(repo): Path, +) -> crate::Result { + let clone = Arc::clone(&global.repo_manager); + + let repo_removed = + tokio::task::spawn_blocking(move || clone.write().unwrap().remove_repo(&repo)).await??; + + if repo_removed { + Ok(StatusCode::OK) + } else { + Ok(StatusCode::NOT_FOUND) + } +} + +async fn delete_arch_repo( + State(global): State, + Path((repo, arch)): Path<(String, String)>, +) -> crate::Result { + let clone = Arc::clone(&global.repo_manager); + + let repo_removed = + tokio::task::spawn_blocking(move || clone.write().unwrap().remove_arch_repo(&repo, &arch)) + .await??; + + if repo_removed { + Ok(StatusCode::OK) + } else { + Ok(StatusCode::NOT_FOUND) + } +} diff --git a/server/src/repo/package.rs b/server/src/repo/package.rs index dd90c09..4ff9433 100644 --- a/server/src/repo/package.rs +++ b/server/src/repo/package.rs @@ -122,7 +122,6 @@ impl PkgInfo { impl Package { pub fn open>(path: P) -> io::Result { let mut builder = Builder::new(); - builder.support_format(libarchive::ReadFormat::Tar)?; // There are chosen kind of arbitrarily, most likely only zstd, gzip and xz will ever be // used @@ -132,6 +131,8 @@ impl Package { builder.support_filter(libarchive::ReadFilter::Bzip2)?; builder.support_filter(libarchive::ReadFilter::Lzma)?; + builder.support_format(libarchive::ReadFormat::Tar)?; + let mut ar = builder.open_file(path.as_ref())?; let compression = ar.filter(0).ok_or(io::Error::new(