main.rs
1 #![forbid(unsafe_code)] 2 3 use std::str::FromStr; 4 5 use api::container_spec::AuthFailure; 6 use config::Config; 7 use rocket::{fs::FileServer, Request}; 8 use rocket_dyn_templates::Template; 9 use sqlx::{ 10 postgres::{PgConnectOptions, PgPoolOptions}, 11 ConnectOptions, 12 }; 13 14 #[macro_use] 15 extern crate rocket; 16 17 pub mod api; 18 pub mod config; 19 pub mod db; 20 pub mod debug_headers; 21 pub mod models; 22 pub mod registry_error; 23 pub mod services; 24 pub mod types; 25 26 #[launch] 27 async fn rocket() -> _ { 28 let config = Config::new().expect("Failed to load config"); 29 30 // Setup DB 31 let mut pg_options = 32 PgConnectOptions::from_str(&config.database_url).expect("Invalid database url provided"); 33 34 if !config.log_db_statements { 35 pg_options = pg_options.disable_statement_logging(); 36 } 37 38 let db_pool = PgPoolOptions::new() 39 .max_connections(5) 40 .connect_with(pg_options) 41 .await 42 .expect("Failed to connect to DB"); 43 44 sqlx::migrate!("./migrations") 45 .run(&db_pool) 46 .await 47 .expect("Failed to run migrations"); 48 49 // TODO: avoid hardcoded URL 50 // let docker = docker_api::Docker::new(config.docker_socket_url.clone()) 51 // .expect("Failed to connect to docker"); 52 53 rocket::build() 54 .mount( 55 "/", 56 routes![ 57 api::container_spec::blobs::read_blob::get_blob, 58 api::container_spec::get_spec_compliance, 59 api::container_spec::blobs::create_session::post_create_session, 60 api::container_spec::blobs::finalize_blob_upload::put_upload_blob, 61 api::container_spec::blobs::upload_blob_section::patch_upload_blob, 62 api::container_spec::blobs::upload_blob_monolithic::post_monolithic_upload, 63 api::container_spec::blobs::read_session::get_upload_session, 64 api::container_spec::blobs::delete_blob::delete_blob, 65 api::container_spec::manifests::delete_manifest, 66 api::container_spec::manifests::put_manifest, 67 api::container_spec::manifests::get_manifest, 68 api::container_spec::tags::get_tags, 69 ], 70 ) 71 .mount( 72 "/api", 73 routes![ 74 api::frontend::repositories::get_all_repositories, 75 api::frontend::repositories::get_repository 76 ], 77 ) 78 // TODO: Auth 79 // .mount( 80 // "/api", 81 // routes![ 82 // api::images::get_images, 83 // api::images::run_image, 84 // api::images::get_container_status 85 // ], 86 // ) 87 .mount("/public", FileServer::from("static/public")) 88 .register("/", catchers![unauthorized_catcher]) 89 .manage(db_pool) 90 .manage(config) 91 // .manage(docker) 92 .attach(Template::fairing()) 93 } 94 95 #[catch(401)] 96 fn unauthorized_catcher(req: &Request) -> AuthFailure { 97 let auth_failure_response: &AuthFailure = req.local_cache(|| { 98 error!("Got unauthorized without a failure having been set to local cache!"); 99 AuthFailure::InternalServerError("Internal error".to_string()) 100 }); 101 102 auth_failure_response.clone() 103 }