/ backend / src / api / container_spec / blobs / upload_blob_monolithic.rs
upload_blob_monolithic.rs
 1  use rocket::{http::Header, State};
 2  use sqlx::Pool;
 3  
 4  use crate::{
 5      api::container_spec::{Auth, LOCATION_HEADER_NAME},
 6      config::Config,
 7      db::DB,
 8      header,
 9      registry_error::RegistryResult,
10      services::upload_blob_service,
11  };
12  
13  use super::utils::octet_stream::OctetStream;
14  
15  #[derive(Responder, Debug)]
16  pub struct MonolithicUploadResponseData<'a> {
17      response: &'a str,
18      location: Header<'a>,
19  }
20  
21  #[derive(Responder)]
22  pub enum MonolithicUploadResponse<'a> {
23      #[response(status = 201)]
24      Success(MonolithicUploadResponseData<'a>),
25      #[response(status = 500)]
26      Failure(&'a str),
27  }
28  
29  #[post("/v2/<name>/blobs/uploads?<digest>", data = "<blob>")]
30  pub async fn post_monolithic_upload<'a>(
31      db_pool: &State<Pool<DB>>,
32      config: &State<Config>,
33      auth: Auth,
34      name: &str,
35      blob: OctetStream,
36      digest: &str,
37  ) -> MonolithicUploadResponse<'a> {
38      if let Err(err) = upload_blob(db_pool, config, auth, name, blob, digest).await {
39          warn!("Failed to monolithicly upload blob due to error: {err:?}");
40          return MonolithicUploadResponse::Failure("Failed to upload blob");
41      };
42  
43      MonolithicUploadResponse::Success(MonolithicUploadResponseData {
44          response: "Blob upload successful",
45          location: header!(LOCATION_HEADER_NAME, format!("/v2/{name}/blobs/{digest}")),
46      })
47  }
48  
49  async fn upload_blob(
50      db_pool: &Pool<DB>,
51      config: &Config,
52      auth: Auth,
53      name: &str,
54      blob: OctetStream,
55      digest: &str,
56  ) -> RegistryResult<()> {
57      let session_id = upload_blob_service::create_session(db_pool, &auth.username, name)
58          .await
59          .map_err(|err| {
60              error!("Failed to initialize monolithic blob upload, err {err:?}");
61              err
62          })?;
63      let upload_session =
64          upload_blob_service::upload_blob(db_pool, name, session_id, config, blob.data, None)
65              .await
66              .map_err(|err| {
67                  error!("Failed to monolithicly upload blob, err: {err:?}");
68                  err
69              })?;
70      let _blob_id = upload_blob_service::finish_blob_upload(
71          db_pool,
72          config,
73          name,
74          upload_session.id.into(),
75          digest,
76      )
77      .await
78      .map_err(|err| {
79          error!("Failed to finalize monolithic blob upload, err: {err:?}");
80          err
81      })?;
82  
83      Ok(())
84  }