feat: re-enable most repo functionality

agents
Jef Roosens 2024-06-26 21:10:04 +02:00
parent 9237add869
commit 042f1ecbd3
Signed by: Jef Roosens
GPG Key ID: B75D4F293C7052DB
3 changed files with 107 additions and 58 deletions

View File

@ -27,6 +27,8 @@ use uuid::Uuid;
pub enum RepoCommand {
ParsePkg(i32, PathBuf),
SyncRepo(i32),
Clean,
}
pub struct RepoSharedState {
@ -98,6 +100,12 @@ impl RepoActor {
let _ = self.sync_repo(repo);
}
}
RepoCommand::SyncRepo(repo) => {
let _ = self.sync_repo(repo);
}
RepoCommand::Clean => {
let _ = self.clean();
}
}
}
}
@ -223,4 +231,8 @@ impl RepoActor {
Ok(())
}
fn clean(&self) -> crate::Result<()> {
todo!()
}
}

View File

@ -14,6 +14,7 @@ use sea_orm::{
ActiveModelTrait, ColumnTrait, Condition, ConnectionTrait, DbConn, EntityTrait, JoinType,
ModelTrait, NotSet, QueryFilter, QuerySelect, Related, RelationTrait, Set, TransactionTrait,
};
use sea_query::{Alias, Expr, Query};
use tokio::{
runtime,
sync::mpsc::{unbounded_channel, UnboundedSender},
@ -117,6 +118,50 @@ impl Handle {
Ok(repo_id)
}
pub async fn get_repo(&self, distro: &str, repo: &str) -> crate::Result<Option<i32>> {
Ok(db::Repo::find()
.find_also_related(db::Distro)
.filter(
Condition::all()
.add(db::repo::Column::Name.eq(repo))
.add(db::distro::Column::Name.eq(distro)),
)
.one(&self.state.conn)
.await
.map(|res| res.map(|(repo, _)| repo.id))?)
}
pub async fn remove_repo(&self, repo: i32) -> crate::Result<()> {
self.state.repos.write().await.remove(&repo);
db::Repo::delete_by_id(repo).exec(&self.state.conn).await?;
let _ = tokio::fs::remove_dir_all(self.state.repos_dir.join(repo.to_string())).await;
Ok(())
}
/// Remove all packages in the repository that have a given arch. This method marks all
/// packages with the given architecture as "pending deletion", before performing a manual sync
/// & removal of stale packages.
pub async fn remove_repo_arch(&self, repo: i32, arch: &str) -> crate::Result<()> {
db::Package::update_many()
.col_expr(
db::package::Column::State,
Expr::value(db::PackageState::PendingDeletion),
)
.filter(
Condition::all()
.add(db::package::Column::RepoId.eq(repo))
.add(db::package::Column::Arch.eq(arch)),
)
.exec(&self.state.conn)
.await?;
self.queue_sync(repo).await;
self.queue_clean().await;
Ok(())
}
pub async fn queue_pkg(&self, repo: i32, path: PathBuf) {
self.state
.tx
@ -126,4 +171,12 @@ impl Handle {
n.0.fetch_add(1, Ordering::SeqCst);
});
}
async fn queue_sync(&self, repo: i32) {
self.state.tx.send(RepoCommand::SyncRepo(repo)).unwrap();
}
async fn queue_clean(&self) {
self.state.tx.send(RepoCommand::Clean).unwrap();
}
}

View File

@ -51,31 +51,30 @@ async fn get_file(
Path((distro, repo, arch, file_name)): Path<(String, String, String, String)>,
req: Request<Body>,
) -> crate::Result<impl IntoResponse> {
Ok(StatusCode::NOT_FOUND)
//if let Some(repo_id) = global.mgr.get_repo(&distro, &repo).await? {
// match global.config.fs {
// FsConfig::Local { data_dir } => {
// let repo_dir = data_dir.join("repos").join(repo_id.to_string());
//
// let file_name = if file_name == format!("{}.db", repo)
// || file_name == format!("{}.db.tar.gz", repo)
// {
// format!("{}.db.tar.gz", arch)
// } else if file_name == format!("{}.files", repo)
// || file_name == format!("{}.files.tar.gz", repo)
// {
// format!("{}.files.tar.gz", arch)
// } else {
// file_name
// };
//
// let path = repo_dir.join(file_name);
// Ok(ServeFile::new(path).oneshot(req).await)
// }
// }
//} else {
// Err(StatusCode::NOT_FOUND.into())
//}
if let Some(repo_id) = global.repo.get_repo(&distro, &repo).await? {
match global.config.fs {
FsConfig::Local { data_dir } => {
let repo_dir = data_dir.join("repos").join(repo_id.to_string());
let file_name = if file_name == format!("{}.db", repo)
|| file_name == format!("{}.db.tar.gz", repo)
{
format!("{}.db.tar.gz", arch)
} else if file_name == format!("{}.files", repo)
|| file_name == format!("{}.files.tar.gz", repo)
{
format!("{}.files.tar.gz", arch)
} else {
file_name
};
let path = repo_dir.join(file_name);
Ok(ServeFile::new(path).oneshot(req).await)
}
}
} else {
Err(StatusCode::NOT_FOUND.into())
}
}
async fn post_package_archive(
@ -99,45 +98,30 @@ async fn delete_repo(
State(global): State<crate::Global>,
Path((distro, repo)): Path<(String, String)>,
) -> crate::Result<StatusCode> {
Ok(StatusCode::NOT_FOUND)
//if let Some(repo) = global.mgr.get_repo(&distro, &repo).await? {
// global.mgr.remove_repo(repo).await?;
//
// tracing::info!("Removed repository {repo}");
//
// Ok(StatusCode::OK)
//} else {
// Ok(StatusCode::NOT_FOUND)
//}
if let Some(repo) = global.repo.get_repo(&distro, &repo).await? {
global.repo.remove_repo(repo).await?;
tracing::info!("Removed repository {repo}");
Ok(StatusCode::OK)
} else {
Ok(StatusCode::NOT_FOUND)
}
}
async fn delete_arch_repo(
State(global): State<crate::Global>,
Path((distro, repo, arch)): Path<(String, String, String)>,
) -> crate::Result<StatusCode> {
Ok(StatusCode::NOT_FOUND)
//if let Some(repo) = global.mgr.get_repo(&distro, &repo).await? {
// global.mgr.remove_repo_arch(repo, &arch).await?;
//
// tracing::info!("Removed architecture '{arch}' from repository {repo}");
//
// Ok(StatusCode::OK)
//} else {
// Ok(StatusCode::NOT_FOUND)
//}
//if let Some(mgr) = global.mgr.get_mgr(&distro).await {
// let repo_removed = mgr.remove_repo_arch(&repo, &arch).await?;
//
// if repo_removed {
// tracing::info!("Removed arch '{}' from repository '{}'", arch, repo);
//
// Ok(StatusCode::OK)
// } else {
// Ok(StatusCode::NOT_FOUND)
// }
//} else {
// Ok(StatusCode::NOT_FOUND)
//}
if let Some(repo) = global.repo.get_repo(&distro, &repo).await? {
global.repo.remove_repo_arch(repo, &arch).await?;
tracing::info!("Removed architecture '{arch}' from repository {repo}");
Ok(StatusCode::OK)
} else {
Ok(StatusCode::NOT_FOUND)
}
}
async fn delete_package(