feat(server): log errors; configurable database

repo-db
Jef Roosens 2023-08-01 15:30:38 +02:00
parent 7c6f485ea6
commit afe73d5314
Signed by: Jef Roosens
GPG Key ID: B75D4F293C7052DB
3 changed files with 42 additions and 19 deletions

View File

@ -4,14 +4,25 @@ use crate::{Config, Global};
use axum::extract::FromRef; use axum::extract::FromRef;
use axum::Router; use axum::Router;
use clap::Parser; use clap::Parser;
use std::io;
use std::path::PathBuf; use std::path::PathBuf;
use std::sync::{Arc, RwLock}; use std::sync::{Arc, RwLock};
use tower_http::trace::TraceLayer; use tower_http::trace::TraceLayer;
use tracing::debug;
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt}; use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
#[derive(Parser)] #[derive(Parser)]
#[command(author, version, about, long_about = None)] #[command(author, version, about, long_about = None)]
pub struct Cli { pub struct Cli {
/// Directory where package archives will be stored
pub pkg_dir: PathBuf,
/// Directory where repository metadata & SQLite database is stored
pub data_dir: PathBuf,
/// Database connection URL; either sqlite:// or postgres://. Defaults to rieter.sqlite in the
/// data directory
#[arg(short, long)]
pub database_url: Option<String>,
/// Port the server will listen on /// Port the server will listen on
#[arg(short, long, value_name = "PORT", default_value_t = 8000)] #[arg(short, long, value_name = "PORT", default_value_t = 8000)]
pub port: u16, pub port: u16,
@ -22,10 +33,6 @@ pub struct Cli {
default_value = "tower_http=debug,rieterd=debug" default_value = "tower_http=debug,rieterd=debug"
)] )]
pub log: String, pub log: String,
/// Directory where package archives will be stored
pub pkg_dir: PathBuf,
/// Directory where repository metadata is stored
pub repo_dir: PathBuf,
} }
impl FromRef<Global> for Arc<RwLock<RepoGroupManager>> { impl FromRef<Global> for Arc<RwLock<RepoGroupManager>> {
@ -42,19 +49,31 @@ impl Cli {
.init(); .init();
} }
pub async fn run(&self) { pub async fn run(&self) -> crate::Result<()> {
self.init_tracing(); self.init_tracing();
let db = crate::db::init("sqlite://test.db").await.unwrap(); let db_url = if let Some(url) = &self.database_url {
url.clone()
} else {
format!(
"sqlite://{}",
self.data_dir.join("rieter.sqlite").to_string_lossy()
)
};
debug!("Connecting to database with URL {}", db_url);
let db = crate::db::init(db_url).await?;
// let db = crate::db::init("postgres://rieter:rieter@localhost:5432/rieter") // let db = crate::db::init("postgres://rieter:rieter@localhost:5432/rieter")
// .await // .await
// .unwrap(); // .unwrap();
let config = Config { let config = Config {
repo_dir: self.repo_dir.clone(), data_dir: self.data_dir.clone(),
repo_dir: self.data_dir.join("repos"),
pkg_dir: self.pkg_dir.clone(), pkg_dir: self.pkg_dir.clone(),
}; };
let repo_manager = RepoGroupManager::new(&self.repo_dir, &self.pkg_dir); let repo_manager = RepoGroupManager::new(&config.repo_dir, &self.pkg_dir);
let global = Global { let global = Global {
config, config,
@ -70,9 +89,11 @@ impl Cli {
.layer(TraceLayer::new_for_http()); .layer(TraceLayer::new_for_http());
// run it with hyper on localhost:3000 // run it with hyper on localhost:3000
Ok(
axum::Server::bind(&format!("0.0.0.0:{}", self.port).parse().unwrap()) axum::Server::bind(&format!("0.0.0.0:{}", self.port).parse().unwrap())
.serve(app.into_make_service()) .serve(app.into_make_service())
.await .await
.unwrap(); .map_err(|err| io::Error::new(io::ErrorKind::Other, err))?,
)
} }
} }

View File

@ -13,6 +13,7 @@ use std::sync::{Arc, RwLock};
#[derive(Clone)] #[derive(Clone)]
pub struct Config { pub struct Config {
data_dir: PathBuf,
repo_dir: PathBuf, repo_dir: PathBuf,
pkg_dir: PathBuf, pkg_dir: PathBuf,
} }
@ -25,7 +26,7 @@ pub struct Global {
} }
#[tokio::main] #[tokio::main]
async fn main() { async fn main() -> crate::Result<()> {
let cli = cli::Cli::parse(); let cli = cli::Cli::parse();
cli.run().await; cli.run().await
} }

View File

@ -45,16 +45,17 @@ async fn post_package_archive(
let clone = Arc::clone(&global.repo_manager); let clone = Arc::clone(&global.repo_manager);
let path_clone = path.clone(); let path_clone = path.clone();
let repo_clone = repo.clone();
let res = tokio::task::spawn_blocking(move || { let res = tokio::task::spawn_blocking(move || {
clone.write().unwrap().add_pkg_from_path(&repo, &path_clone) clone.write().unwrap().add_pkg_from_path(&repo_clone, &path_clone)
}) })
.await?; .await?;
// Remove the downloaded file if the adding failed // Remove the downloaded file if the adding failed
if res.is_err() { if let Err(err) = res {
let _ = tokio::fs::remove_file(path).await; let _ = tokio::fs::remove_file(path).await;
return res; return Err(err.into());
} }
let pkg = res.unwrap(); let pkg = res.unwrap();