use crate::config::Config;
use actix_web::dev::Server;
use actix_web::middleware::{Logger, TrailingSlash};
use actix_web::web::{Data, JsonConfig, scope};
use actix_web::{App, HttpServer, middleware};
use in_toto::crypto::PrivateKey;
use rebuilderd_common::errors::*;
use std::net::SocketAddr;
use std::sync::{Arc, RwLock};
pub mod api;
pub mod attestation;
pub mod code_migrations;
pub mod config;
pub mod db;
pub mod models;
pub mod schema;
pub mod web;
pub fn build_server(
pool: db::Pool,
config: Config,
privkey: PrivateKey,
) -> Result<(Server, SocketAddr)> {
let bind_addr = config.bind_addr.clone();
let privkey = Arc::new(privkey);
let server = HttpServer::new(move || {
let json_config = JsonConfig::default().limit(config.post_body_size_limit);
let v0_dashboard_cache = Arc::new(RwLock::new(api::v0::DashboardState::new()));
App::new()
.wrap(Logger::default())
.wrap(middleware::Compress::default())
.wrap(middleware::NormalizePath::new(TrailingSlash::Trim))
.app_data(json_config)
.app_data(Data::new(pool.clone()))
.app_data(Data::new(config.clone()))
.app_data(Data::new(privkey.clone()))
.app_data(Data::new(v0_dashboard_cache.clone()))
.service(
scope("/api")
.service(
scope("/v0")
.service(api::v0::list_workers)
.service(api::v0::sync_work)
.service(api::v0::list_pkgs)
.service(api::v0::list_queue)
.service(api::v0::push_queue)
.service(api::v0::pop_queue)
.service(api::v0::drop_from_queue)
.service(api::v0::requeue_pkgbase)
.service(api::v0::ping_build)
.service(api::v0::report_build)
.service(api::v0::get_build_log)
.service(api::v0::get_attestation)
.service(api::v0::get_diffoscope)
.service(api::v0::get_dashboard)
.service(api::v0::get_public_key),
)
.service(
scope("/v1")
.service(
scope("/builds")
.service(api::v1::get_builds)
.service(api::v1::submit_rebuild_report)
.service(api::v1::get_build)
.service(api::v1::get_build_log)
.service(api::v1::get_build_artifacts)
.service(api::v1::get_build_artifact)
.service(api::v1::get_build_artifact_diffoscope)
.service(api::v1::get_build_artifact_attestation),
)
.service(scope("/dashboard").service(api::v1::get_dashboard))
.service(
scope("/meta")
.service(api::v1::get_distributions)
.service(api::v1::get_distribution_releases)
.service(api::v1::get_distribution_architectures)
.service(api::v1::get_distribution_release_architectures)
.service(api::v1::get_public_key),
)
.service(
scope("/packages")
.service(api::v1::submit_package_report)
.service(api::v1::get_source_packages)
.service(api::v1::get_source_package)
.service(api::v1::get_binary_packages)
.service(api::v1::get_binary_package),
)
.service(
scope("/queue")
.service(api::v1::get_queued_jobs)
.service(api::v1::request_rebuild)
.service(api::v1::get_queued_job)
.service(api::v1::drop_queued_job)
.service(api::v1::drop_queued_jobs)
.service(api::v1::ping_job)
.service(api::v1::request_work),
)
.service(
scope("/workers")
.service(api::v1::get_workers)
.service(api::v1::register_worker)
.service(api::v1::get_worker)
.service(api::v1::unregister_worker),
),
),
)
})
.bind(&bind_addr)?;
let address = server
.addrs()
.first()
.copied()
.context("Failed to determine bind address")?;
Ok((server.run(), address))
}
pub async fn run_config(pool: db::Pool, config: Config, privkey: PrivateKey) -> Result<()> {
let (server, _) = build_server(pool, config, privkey)?;
server.await?;
Ok(())
}