1use crate::config::Config;
2use actix_web::dev::Server;
3use actix_web::middleware::{Logger, TrailingSlash};
4use actix_web::web::{Data, JsonConfig, scope};
5use actix_web::{App, HttpServer, middleware};
6use in_toto::crypto::PrivateKey;
7use rebuilderd_common::errors::*;
8use std::net::SocketAddr;
9use std::sync::{Arc, RwLock};
10
11pub mod api;
12pub mod attestation;
13pub mod code_migrations;
14pub mod config;
15pub mod db;
16pub mod models;
17pub mod schema;
18pub mod web;
19
20pub fn build_server(
21 pool: db::Pool,
22 config: Config,
23 privkey: PrivateKey,
24) -> Result<(Server, SocketAddr)> {
25 let bind_addr = config.bind_addr.clone();
26
27 let privkey = Arc::new(privkey);
28
29 let server = HttpServer::new(move || {
30 let json_config = JsonConfig::default().limit(config.post_body_size_limit);
31
32 let v0_dashboard_cache = Arc::new(RwLock::new(api::v0::DashboardState::new()));
33
34 App::new()
35 .wrap(Logger::default())
36 .wrap(middleware::Compress::default())
37 .wrap(middleware::NormalizePath::new(TrailingSlash::Trim))
38 .app_data(json_config)
39 .app_data(Data::new(pool.clone()))
40 .app_data(Data::new(config.clone()))
41 .app_data(Data::new(privkey.clone()))
42 .app_data(Data::new(v0_dashboard_cache.clone()))
43 .service(
44 scope("/api")
45 .service(
46 scope("/v0")
47 .service(api::v0::list_workers)
48 .service(api::v0::sync_work)
49 .service(api::v0::list_pkgs)
50 .service(api::v0::list_queue)
51 .service(api::v0::push_queue)
52 .service(api::v0::pop_queue)
53 .service(api::v0::drop_from_queue)
54 .service(api::v0::requeue_pkgbase)
55 .service(api::v0::ping_build)
56 .service(api::v0::report_build)
57 .service(api::v0::get_build_log)
58 .service(api::v0::get_attestation)
59 .service(api::v0::get_diffoscope)
60 .service(api::v0::get_dashboard)
61 .service(api::v0::get_public_key),
62 )
63 .service(
64 scope("/v1")
65 .service(
66 scope("/builds")
67 .service(api::v1::get_builds)
68 .service(api::v1::submit_rebuild_report)
69 .service(api::v1::get_build)
70 .service(api::v1::get_build_log)
71 .service(api::v1::get_build_artifacts)
72 .service(api::v1::get_build_artifact)
73 .service(api::v1::get_build_artifact_diffoscope)
74 .service(api::v1::get_build_artifact_attestation),
75 )
76 .service(scope("/dashboard").service(api::v1::get_dashboard))
77 .service(
78 scope("/meta")
79 .service(api::v1::get_distributions)
80 .service(api::v1::get_distribution_releases)
81 .service(api::v1::get_distribution_architectures)
82 .service(api::v1::get_distribution_release_architectures)
83 .service(api::v1::get_public_key),
84 )
85 .service(
86 scope("/packages")
87 .service(api::v1::submit_package_report)
88 .service(api::v1::get_source_packages)
89 .service(api::v1::get_source_package)
90 .service(api::v1::get_binary_packages)
91 .service(api::v1::get_binary_package),
92 )
93 .service(
94 scope("/queue")
95 .service(api::v1::get_queued_jobs)
96 .service(api::v1::request_rebuild)
97 .service(api::v1::get_queued_job)
98 .service(api::v1::drop_queued_job)
99 .service(api::v1::drop_queued_jobs)
100 .service(api::v1::ping_job)
101 .service(api::v1::request_work),
102 )
103 .service(
104 scope("/workers")
105 .service(api::v1::get_workers)
106 .service(api::v1::register_worker)
107 .service(api::v1::get_worker)
108 .service(api::v1::unregister_worker),
109 ),
110 ),
111 )
112 })
113 .bind(&bind_addr)?;
114
115 let address = server
116 .addrs()
117 .first()
118 .copied()
119 .context("Failed to determine bind address")?;
120 Ok((server.run(), address))
121}
122
123pub async fn run_config(pool: db::Pool, config: Config, privkey: PrivateKey) -> Result<()> {
124 let (server, _) = build_server(pool, config, privkey)?;
125
126 server.await?;
127 Ok(())
128}