rebuilderd/
lib.rs

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}