sync every hour the latest version of packages with aur

display current version and if outdated in ui
display correct time in output log
This commit is contained in:
2024-01-01 23:07:52 +01:00
parent eb4ca46562
commit 80e2299dc8
17 changed files with 199 additions and 26 deletions

View File

@ -1188,8 +1188,8 @@ fi
if (( ! INFAKEROOT )); then
if (( EUID == 0 )); then
error "$(gettext "Running %s as root is not allowed as it can cause permanent,\n\
catastrophic damage to your system.")" "makepkg"
: #error "$(gettext "Running %s as root is not allowed as it can cause permanent,\n\
#catastrophic damage to your system.")" "makepkg"
#exit $E_ROOT
fi
else

View File

@ -9,9 +9,9 @@ use rocket::serde::{Deserialize, Serialize};
use rocket::{get, State};
use rocket_okapi::okapi::schemars;
use rocket_okapi::{openapi, JsonSchema};
use sea_orm::PaginatorTrait;
use sea_orm::{ColumnTrait, QueryFilter};
use sea_orm::{DatabaseConnection, EntityTrait, FromQueryResult, QuerySelect, RelationTrait};
use sea_orm::{Order, PaginatorTrait, QueryOrder};
#[derive(Serialize, JsonSchema)]
#[serde(crate = "rocket::serde")]
@ -43,8 +43,11 @@ pub async fn search(query: &str) -> Result<Json<Vec<ApiPackage>>, String> {
pub struct ListPackageModel {
id: i32,
name: String,
count: i32,
status: i32,
outofdate: bool,
latest_version: String,
latest_version_id: i32,
latest_aur_version: String,
}
#[openapi(tag = "test")]
@ -55,13 +58,15 @@ pub async fn package_list(
let db = db as &DatabaseConnection;
let all: Vec<ListPackageModel> = Packages::find()
.join_rev(JoinType::InnerJoin, versions::Relation::Packages.def())
.join_rev(JoinType::InnerJoin, versions::Relation::LatestPackage.def())
.select_only()
.column_as(versions::Column::Id.count(), "count")
.column(packages::Column::Name)
.column(packages::Column::Id)
.column(packages::Column::Status)
.group_by(packages::Column::Name)
.column_as(packages::Column::OutOfDate, "outofdate")
.column_as(packages::Column::LatestAurVersion, "latest_aur_version")
.column_as(versions::Column::Version, "latest_version")
.column_as(packages::Column::LatestVersionId, "latest_version_id")
.into_model::<ListPackageModel>()
.all(db)
.await
@ -146,6 +151,8 @@ pub struct ListBuildsModel {
pkg_name: String,
version: String,
status: i32,
start_time: Option<u32>,
end_time: Option<u32>,
}
#[openapi(tag = "test")]
@ -165,6 +172,9 @@ pub async fn list_builds(
.column(builds::Column::Status)
.column_as(packages::Column::Name, "pkg_name")
.column(versions::Column::Version)
.column(builds::Column::EndTime)
.column(builds::Column::StartTime)
.order_by(builds::Column::StartTime, Order::Desc)
.limit(limit);
let build = match pkgid {
@ -197,6 +207,8 @@ pub async fn get_build(
.column(builds::Column::Status)
.column_as(packages::Column::Name, "pkg_name")
.column(versions::Column::Version)
.column(builds::Column::EndTime)
.column(builds::Column::StartTime)
.into_model::<ListBuildsModel>()
.one(db)
.await

View File

@ -5,6 +5,7 @@ use crate::repo::repo::add_pkg;
use anyhow::anyhow;
use sea_orm::{ActiveModelTrait, DatabaseConnection, EntityTrait, Set};
use std::ops::Add;
use std::time::{SystemTime, UNIX_EPOCH};
use tokio::sync::broadcast;
use tokio::sync::broadcast::error::RecvError;
use tokio::sync::broadcast::Sender;
@ -16,12 +17,17 @@ pub async fn init(db: DatabaseConnection, tx: Sender<Action>) {
// add a package to parallel build
Action::Build(name, version, url, mut version_model) => {
let db = db.clone();
let build = builds::ActiveModel {
pkg_id: version_model.package_id.clone(),
version_id: version_model.id.clone(),
ouput: Set(None),
status: Set(Some(0)),
start_time: Set(Some(
SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_secs() as u32,
)),
..Default::default()
};
let mut new_build = build.save(&db).await.unwrap();
@ -62,6 +68,8 @@ pub async fn init(db: DatabaseConnection, tx: Sender<Action>) {
let _ = set_pkg_status(
&db,
version_model.package_id.clone().unwrap(),
version_model.id.clone().unwrap(),
Some(false),
1,
)
.await;
@ -70,18 +78,32 @@ pub async fn init(db: DatabaseConnection, tx: Sender<Action>) {
let _ = version_model.update(&db).await;
new_build.status = Set(Some(1));
new_build.end_time = Set(Some(
SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_secs() as u32,
));
let _ = new_build.update(&db).await;
}
Err(e) => {
let _ = set_pkg_status(
&db,
version_model.package_id.clone().unwrap(),
version_model.id.clone().unwrap(),
None,
2,
)
.await;
let _ = version_model.update(&db).await;
new_build.status = Set(Some(2));
new_build.end_time = Set(Some(
SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_secs() as u32,
));
let _ = new_build.update(&db).await;
println!("Error: {e}")
@ -98,6 +120,8 @@ pub async fn init(db: DatabaseConnection, tx: Sender<Action>) {
async fn set_pkg_status(
db: &DatabaseConnection,
package_id: i32,
version_id: i32,
outofdate: Option<bool>,
status: i32,
) -> anyhow::Result<()> {
let mut pkg: packages::ActiveModel = Packages::find_by_id(package_id)
@ -107,6 +131,10 @@ async fn set_pkg_status(
.into();
pkg.status = Set(status);
pkg.latest_version_id = Set(Some(version_id));
if outofdate.is_some() {
pkg.out_of_date = Set(outofdate.unwrap() as i32)
}
pkg.update(db).await?;
Ok(())
}

View File

@ -14,6 +14,8 @@ pub struct Model {
pub version_id: i32,
pub ouput: Option<String>,
pub status: Option<i32>,
pub start_time: Option<u32>,
pub end_time: Option<u32>,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]

View File

@ -19,7 +19,9 @@ create table builds
pkg_id integer not null,
version_id integer not null,
ouput TEXT,
status integer
status integer,
start_time INTEGER,
end_time integer
);
create table packages
@ -27,7 +29,12 @@ create table packages
id integer not null
primary key autoincrement,
name text not null,
status integer default 0 not null
status integer default 0 not null,
out_of_date INTEGER default 0 not null,
latest_version_id integer
constraint packages_versions_id_fk
references versions,
latest_aur_version TEXT
);
create table status

View File

@ -12,6 +12,9 @@ pub struct Model {
pub id: i32,
pub name: String,
pub status: i32,
pub out_of_date: i32,
pub latest_version_id: Option<i32>,
pub latest_aur_version: Option<String>,
}
impl ActiveModelBehavior for ActiveModel {}
@ -22,6 +25,8 @@ pub enum Relation {
Versions,
#[sea_orm(has_many = "super::builds::Entity")]
Builds,
#[sea_orm(has_one = "super::versions::Entity")]
LatestVersion,
}
impl Related<super::versions::Entity> for Entity {
@ -30,8 +35,14 @@ impl Related<super::versions::Entity> for Entity {
}
}
// impl Related<super::versions::Entity> for Entity {
// fn to() -> RelationDef {
// Relation::LatestVersion.def()
// }
// }
impl Related<super::builds::Entity> for crate::db::versions::Entity {
fn to() -> RelationDef {
crate::db::versions::Relation::Builds.def()
Relation::Builds.def()
}
}

View File

@ -23,6 +23,12 @@ pub enum Relation {
to = "super::packages::Column::Id"
)]
Packages,
#[sea_orm(
belongs_to = "super::packages::Entity",
from = "Column::Id",
to = "super::packages::Column::LatestVersionId"
)]
LatestPackage,
#[sea_orm(has_many = "super::builds::Entity")]
Builds,
}

View File

@ -4,6 +4,7 @@ mod builder;
mod db;
mod pkgbuild;
mod repo;
mod scheduler;
mod utils;
use crate::api::backend;
@ -11,6 +12,7 @@ use crate::api::backend;
use crate::api::embed::CustomHandler;
use crate::builder::types::Action;
use crate::db::migration::Migrator;
use crate::scheduler::aur_version_update::start_aur_version_checking;
use rocket::config::Config;
use rocket::fs::FileServer;
use rocket::futures::future::join_all;
@ -48,6 +50,8 @@ fn main() {
builder::builder::init(db2, tx2).await;
});
start_aur_version_checking(db.clone());
let backend_handle = tokio::spawn(async {
let mut config = Config::default();
config.address = "0.0.0.0".parse().unwrap();

View File

@ -0,0 +1,55 @@
use crate::db::packages;
use crate::db::prelude::Packages;
use anyhow::anyhow;
use aur_rs::{Package, Request};
use sea_orm::ActiveValue::Set;
use sea_orm::{ActiveModelTrait, DatabaseConnection, EntityTrait};
use std::time::Duration;
use tokio::time::sleep;
pub fn start_aur_version_checking(db: DatabaseConnection) {
tokio::spawn(async move {
sleep(Duration::from_secs(10)).await;
loop {
println!("performing aur version checks");
match aur_check_versions(db.clone()).await {
Ok(_) => {}
Err(e) => {
println!("Failed to perform aur version check: {e}")
}
}
sleep(Duration::from_secs(3600)).await;
}
});
}
async fn aur_check_versions(db: DatabaseConnection) -> anyhow::Result<()> {
let packages = Packages::find().all(&db).await?;
let names: Vec<&str> = packages.iter().map(|x| x.name.as_str()).collect();
let request = Request::default();
let response = request.search_multi_info_by_names(names.as_slice()).await;
let results: Vec<Package> = response
.map_err(|_| anyhow!("couldn't download version update"))?
.results;
if results.len() != packages.len() {
println!("Package nr in repo and aur api response has different size");
}
for package in packages {
match results.iter().find(|x1| x1.name == package.name) {
None => {
println!("Couldn't find {} in AUR response", package.name)
}
Some(result) => {
let mut package: packages::ActiveModel = package.into();
package.latest_aur_version = Set(Some(result.version.clone()));
let _ = package.update(&db).await;
}
}
}
Ok(())
}

View File

@ -0,0 +1 @@
pub mod aur_version_update;