1extern crate diesel;
2extern crate diesel_migrations;
3
4use crate::config::Config;
5use crate::dashboard::DashboardState;
6use crate::models::Build;
7use actix_web::middleware::Logger;
8use actix_web::web::Data;
9use actix_web::{middleware, App, HttpServer};
10use diesel::SqliteConnection;
11use rebuilderd_common::errors::*;
12use std::sync::{Arc, RwLock};
13use std::thread;
14use std::time::Duration;
15
16pub mod api;
17pub mod auth;
18pub mod code_migrations;
19pub mod config;
20pub mod dashboard;
21pub mod db;
22pub mod models;
23pub mod schema;
24pub mod sync;
25pub mod util;
26pub mod web;
27
28fn db_collect_garbage(connection: &mut SqliteConnection) -> Result<()> {
29 let orphaned = Build::find_orphaned(connection)?;
30
31 if !orphaned.is_empty() {
32 info!("Deleting {} orphaned builds...", orphaned.len());
33 for ids in orphaned.chunks(500) {
34 Build::delete_multiple(ids, connection).context("Failed to delete builds")?;
35 debug!("Deleted chunk of {} builds", ids.len());
36 }
37 info!("Finished removing orphaned builds");
38 }
39
40 Ok(())
41}
42
43pub async fn run_config(config: Config) -> Result<()> {
44 let pool = db::setup_pool("rebuilderd.db")?;
45 let bind_addr = config.bind_addr.clone();
46
47 let dashboard_cache = Arc::new(RwLock::new(DashboardState::new()));
48
49 {
50 let pool = pool.clone();
51 thread::spawn(move || {
52 let mut connection = pool.get().expect("Failed to get connection from pool");
53 loop {
54 debug!("Checking for orphaned builds...");
55
56 if let Err(err) = db_collect_garbage(connection.as_mut()) {
57 error!("Failed to delete orphaned builds: {:#}", err);
58 }
59
60 debug!("Sleeping until next garbage collection cycle...");
61 thread::sleep(Duration::from_secs(24 * 3600));
62 }
63 });
64 }
65
66 HttpServer::new(move || {
67 App::new()
68 .wrap(Logger::default())
69 .wrap(middleware::Compress::default())
70 .app_data(Data::new(pool.clone()))
71 .app_data(Data::new(config.clone()))
72 .app_data(Data::new(dashboard_cache.clone()))
73 .service(api::list_workers)
74 .service(api::list_pkgs)
75 .service(api::list_queue)
76 .service(api::push_queue)
77 .service(api::pop_queue)
78 .service(api::drop_from_queue)
79 .service(api::requeue_pkgbase)
80 .service(api::ping_build)
81 .service(api::get_build_log)
82 .service(api::get_diffoscope)
83 .service(api::get_attestation)
84 .service(api::get_dashboard)
85 .service(
86 web::resource("/api/v0/build/report")
87 .app_data(web::JsonConfig::default().limit(config.post_body_size_limit))
88 .route(web::post().to(api::report_build)),
89 )
90 .service(
91 web::resource("/api/v0/pkgs/sync")
92 .app_data(web::JsonConfig::default().limit(config.post_body_size_limit))
93 .route(web::post().to(api::sync_work)),
94 )
95 })
96 .bind(&bind_addr)?
97 .run()
98 .await?;
99 Ok(())
100}