From 7c6f485ea60fdebfcfe7fb8c8d3c555aa12f9bec Mon Sep 17 00:00:00 2001 From: Chewing_Bever Date: Tue, 1 Aug 2023 14:38:50 +0200 Subject: [PATCH] feat(server): update database when publishing packages --- server/src/cli.rs | 8 +++--- server/src/db/entities/package.rs | 2 +- server/src/error.rs | 7 ------ server/src/main.rs | 2 +- server/src/repo/manager.rs | 13 +++++++--- server/src/repo/mod.rs | 34 ++++++++++++++++++++++++- server/src/repo/package.rs | 41 ++++++++++++++++++++++--------- 7 files changed, 78 insertions(+), 29 deletions(-) diff --git a/server/src/cli.rs b/server/src/cli.rs index bdad1fb..144e56e 100644 --- a/server/src/cli.rs +++ b/server/src/cli.rs @@ -45,10 +45,10 @@ impl Cli { pub async fn run(&self) { self.init_tracing(); - // let db = crate::db::init("sqlite://test.db").await.unwrap(); - let db = crate::db::init("postgres://rieter:rieter@localhost:5432/rieter") - .await - .unwrap(); + let db = crate::db::init("sqlite://test.db").await.unwrap(); + // let db = crate::db::init("postgres://rieter:rieter@localhost:5432/rieter") + // .await + // .unwrap(); let config = Config { repo_dir: self.repo_dir.clone(), diff --git a/server/src/db/entities/package.rs b/server/src/db/entities/package.rs index 7920aac..86606bf 100644 --- a/server/src/db/entities/package.rs +++ b/server/src/db/entities/package.rs @@ -17,7 +17,7 @@ pub struct Model { pub c_size: i64, pub description: Option, pub url: Option, - pub build_date: Option, + pub build_date: DateTime, pub packager: Option, pub pgp_sig: Option, pub pgp_sig_size: Option, diff --git a/server/src/error.rs b/server/src/error.rs index a359572..1299d2f 100644 --- a/server/src/error.rs +++ b/server/src/error.rs @@ -10,7 +10,6 @@ pub type Result = std::result::Result; pub enum ServerError { IO(io::Error), Axum(axum::Error), - Status(StatusCode), Db(sea_orm::DbErr), Status(StatusCode), } @@ -75,9 +74,3 @@ impl From for ServerError { ServerError::Db(err) } } - -impl From for ServerError { - fn from(status: StatusCode) -> Self { - ServerError::Status(status) - } -} diff --git a/server/src/main.rs b/server/src/main.rs index a6d41b5..8217909 100644 --- a/server/src/main.rs +++ b/server/src/main.rs @@ -1,6 +1,6 @@ mod api; mod cli; -mod db; +pub mod db; mod error; mod repo; diff --git a/server/src/repo/manager.rs b/server/src/repo/manager.rs index 6b11641..f5aad8c 100644 --- a/server/src/repo/manager.rs +++ b/server/src/repo/manager.rs @@ -104,9 +104,12 @@ impl RepoGroupManager { Ok(()) } - pub fn add_pkg_from_path>(&mut self, repo: &str, path: P) -> io::Result<()> { - let mut pkg = Package::open(&path)?; - pkg.calculate_checksum()?; + pub fn add_pkg_from_path>( + &mut self, + repo: &str, + path: P, + ) -> io::Result { + let pkg = Package::open(&path)?; self.add_pkg(repo, &pkg)?; @@ -118,7 +121,9 @@ impl RepoGroupManager { .join(pkg.file_name()); fs::create_dir_all(dest_pkg_path.parent().unwrap())?; - fs::rename(&path, dest_pkg_path) + fs::rename(&path, dest_pkg_path)?; + + Ok(pkg) } /// Add a package to the given repo, returning to what architectures the package was added. diff --git a/server/src/repo/mod.rs b/server/src/repo/mod.rs index c5cb9f0..de3e74d 100644 --- a/server/src/repo/mod.rs +++ b/server/src/repo/mod.rs @@ -4,6 +4,7 @@ mod package; pub use manager::RepoGroupManager; use axum::body::Body; +use crate::db::entities::{package as db_package, repo as db_repo}; use axum::extract::{BodyStream, Path, State}; use axum::http::Request; use axum::http::StatusCode; @@ -11,6 +12,7 @@ use axum::response::IntoResponse; use axum::routing::{delete, post}; use axum::Router; use futures::StreamExt; +use sea_orm::{ActiveModelTrait, ColumnTrait, EntityTrait, QueryFilter}; use std::sync::Arc; use tokio::{fs, io::AsyncWriteExt}; use tower::util::ServiceExt; @@ -51,9 +53,39 @@ async fn post_package_archive( // Remove the downloaded file if the adding failed if res.is_err() { let _ = tokio::fs::remove_file(path).await; + + return res; } - Ok(res?) + let pkg = res.unwrap(); + + // Query the repo for its ID, or create it if it does not already exist + let repo_entity = db_repo::Entity::find() + .filter(db_repo::Column::Name.eq(&repo)) + .one(&global.db) + .await?; + + let repo_id = if let Some(repo_entity) = repo_entity { + repo_entity.id + } else { + let model = db_repo::ActiveModel { + name: sea_orm::Set(repo.clone()), + ..Default::default() + }; + + db_repo::Entity::insert(model) + .exec(&global.db) + .await? + .last_insert_id + }; + + // Insert the package's data into the database + let mut model: db_package::ActiveModel = pkg.into(); + model.repo_id = sea_orm::Set(repo_id); + + model.insert(&global.db).await?; + + Ok(()) } /// Serve the package archive files and database archives. If files are requested for an diff --git a/server/src/repo/package.rs b/server/src/repo/package.rs index 6d8070b..ddafbd9 100644 --- a/server/src/repo/package.rs +++ b/server/src/repo/package.rs @@ -1,11 +1,14 @@ use chrono::NaiveDateTime; use libarchive::read::{Archive, Builder}; use libarchive::{Entry, ReadFilter}; +use sea_orm::ActiveValue::Set; use std::fmt; use std::fs; use std::io::{self, BufRead, BufReader, BufWriter, Read, Write}; use std::path::{Path, PathBuf}; +use crate::db::entities::package; + const IGNORED_FILES: [&str; 5] = [".BUILDINFO", ".INSTALL", ".MTREE", ".PKGINFO", ".CHANGELOG"]; #[derive(Debug)] @@ -39,7 +42,7 @@ pub struct PkgInfo { pub optdepends: Vec, pub makedepends: Vec, pub checkdepends: Vec, - pub sha256sum: Option, + pub sha256sum: String, } #[derive(Debug, PartialEq, Eq)] @@ -163,6 +166,7 @@ impl Package { if let Some(mut info) = info { // I'll take my chances on a file size fitting in an i64 info.csize = fs::metadata(path.as_ref())?.len().try_into().unwrap(); + info.sha256sum = sha256::try_digest(path.as_ref())?; Ok(Package { path: path.as_ref().to_path_buf(), @@ -178,12 +182,6 @@ impl Package { } } - pub fn calculate_checksum(&mut self) -> io::Result<()> { - self.info.sha256sum = Some(sha256::try_digest(self.path.as_ref())?); - - Ok(()) - } - pub fn full_name(&self) -> String { format!( "{}-{}-{}", @@ -230,9 +228,7 @@ impl Package { write("CSIZE", &info.csize.to_string())?; write("ISIZE", &info.size.to_string())?; - if let Some(checksum) = &info.sha256sum { - write("SHA256SUM", checksum)?; - } + write("SHA256SUM", &info.sha256sum)?; if let Some(ref url) = info.url { write("URL", url)?; @@ -240,7 +236,7 @@ impl Package { write("LICENSE", &info.licenses.join("\n"))?; write("ARCH", &info.arch)?; - write("BUILDDATE", &info.build_date.to_string())?; + write("BUILDDATE", &info.build_date.timestamp().to_string())?; if let Some(ref packager) = info.packager { write("PACKAGER", packager)?; @@ -271,3 +267,26 @@ impl Package { Ok(()) } } + +impl From for package::ActiveModel { + fn from(pkg: Package) -> Self { + let info = pkg.info; + + package::ActiveModel { + base: Set(info.base), + name: Set(info.name), + version: Set(info.version), + arch: Set(info.arch), + size: Set(info.size), + c_size: Set(info.csize), + description: Set(info.description), + url: Set(info.url), + build_date: Set(info.build_date), + packager: Set(info.packager), + pgp_sig: Set(info.pgpsig), + pgp_sig_size: Set(info.pgpsigsize), + sha256_sum: Set(info.sha256sum), + ..Default::default() + } + } +}