Cleanup all other resources when deleting an image
This commit is contained in:
parent
82774a4931
commit
3d70301c54
|
@ -132,13 +132,27 @@ pub async fn delete_manifest(path: web::Path<(String, String)>, req: HttpRequest
|
||||||
let _authorization = headers.get("Authorization").unwrap(); // TODO:
|
let _authorization = headers.get("Authorization").unwrap(); // TODO:
|
||||||
|
|
||||||
let database = &state.database;
|
let database = &state.database;
|
||||||
|
let digest = match Digest::is_digest(&reference) {
|
||||||
|
true => {
|
||||||
|
// Check if the manifest exists
|
||||||
|
if database.get_manifest(&name, &reference).await.unwrap().is_none() {
|
||||||
|
return HttpResponse::NotFound()
|
||||||
|
.finish();
|
||||||
|
}
|
||||||
|
|
||||||
// If `reference` is a digest, then we're deleting a manifest, else a tag
|
reference.clone()
|
||||||
if Digest::is_digest(&reference) {
|
},
|
||||||
database.delete_manifest(&name, &reference).await.unwrap();
|
false => {
|
||||||
} else {
|
if let Some(tag) = database.get_tag(&name, &reference).await.unwrap() {
|
||||||
database.delete_tag(&name, &reference).await.unwrap();
|
tag.manifest_digest
|
||||||
}
|
} else {
|
||||||
|
return HttpResponse::NotFound()
|
||||||
|
.finish();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
database.delete_manifest(&name, &digest).await.unwrap();
|
||||||
|
|
||||||
HttpResponse::Accepted()
|
HttpResponse::Accepted()
|
||||||
.append_header(("Content-Length", "None"))
|
.append_header(("Content-Length", "None"))
|
||||||
|
|
|
@ -27,7 +27,7 @@ pub trait Database {
|
||||||
/// Replace the uuid with a digest
|
/// Replace the uuid with a digest
|
||||||
async fn replace_digest(&self, uuid: &str, new_digest: &str) -> sqlx::Result<()>;
|
async fn replace_digest(&self, uuid: &str, new_digest: &str) -> sqlx::Result<()>;
|
||||||
async fn link_manifest_layer(&self, manifest_digest: &str, layer_digest: &str) -> sqlx::Result<()>;
|
async fn link_manifest_layer(&self, manifest_digest: &str, layer_digest: &str) -> sqlx::Result<()>;
|
||||||
async fn unlink_manifest_layer(&self, repository: &str, layer_digest: &str) -> sqlx::Result<()>;
|
async fn unlink_manifest_layer(&self, manifest_digest: &str, layer_digest: &str) -> sqlx::Result<()>;
|
||||||
|
|
||||||
// Tag related functions
|
// Tag related functions
|
||||||
|
|
||||||
|
@ -147,13 +147,13 @@ impl Database for Pool<Sqlite> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn unlink_manifest_layer(&self, repository: &str, layer_digest: &str) -> sqlx::Result<()> {
|
async fn unlink_manifest_layer(&self, manifest_digest: &str, layer_digest: &str) -> sqlx::Result<()> {
|
||||||
sqlx::query("DELETE FROM manifest_layers WHERE layer_digest = ? AND manifest IN (SELECT digest FROM image_manifests WHERE repository = ?) RETURNING manifest, layer_digest")
|
sqlx::query("DELETE FROM manifest_layers WHERE manifest = ? AND layer_digest = ?")
|
||||||
|
.bind(manifest_digest)
|
||||||
.bind(layer_digest)
|
.bind(layer_digest)
|
||||||
.bind(repository)
|
|
||||||
.execute(self).await?;
|
.execute(self).await?;
|
||||||
|
|
||||||
debug!("Removed link of layer {} from manifest in {} repository", layer_digest, repository);
|
debug!("Removed link between manifest {} and layer {}", manifest_digest, layer_digest);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -275,6 +275,28 @@ impl Database for Pool<Sqlite> {
|
||||||
.bind(repository)
|
.bind(repository)
|
||||||
.execute(self).await?;
|
.execute(self).await?;
|
||||||
|
|
||||||
|
debug!("Deleted manifest {} in repository {}", digest, repository);
|
||||||
|
|
||||||
|
let rows: Vec<(String, )> = sqlx::query_as("DELETE FROM manifest_layers WHERE manifest = ? RETURNING layer_digest")
|
||||||
|
.bind(digest)
|
||||||
|
.fetch_all(self).await?;
|
||||||
|
|
||||||
|
debug!("Unlinked manifest {} from all linked layers", digest);
|
||||||
|
|
||||||
|
for row in rows.into_iter() {
|
||||||
|
let layer_digest = row.0;
|
||||||
|
|
||||||
|
self.delete_digest(&layer_digest).await?;
|
||||||
|
}
|
||||||
|
|
||||||
|
debug!("Deleted all digests for manifest {}", digest);
|
||||||
|
|
||||||
|
sqlx::query("DELETE FROM image_tags where image_manifest = ?")
|
||||||
|
.bind(digest)
|
||||||
|
.execute(self).await?;
|
||||||
|
|
||||||
|
debug!("Deleted all image tags for manifest {}", digest);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -55,7 +55,7 @@ async fn main() -> std::io::Result<()> {
|
||||||
.service(api::manifests::upload_manifest)
|
.service(api::manifests::upload_manifest)
|
||||||
.service(api::manifests::pull_manifest)
|
.service(api::manifests::pull_manifest)
|
||||||
.service(api::manifests::manifest_exists)
|
.service(api::manifests::manifest_exists)
|
||||||
.service(api::manifests::delete_manifest)
|
.service(api::manifests::delete_manifest) // delete image
|
||||||
)
|
)
|
||||||
.service(
|
.service(
|
||||||
web::scope("/blobs")
|
web::scope("/blobs")
|
||||||
|
|
Loading…
Reference in New Issue