/ backend / src / main.rs
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  }