Files
mstore/app/imageoper/delman.go
T

135 lines
3.3 KiB
Go

/*
* Copyright 2026 Oleg Borodin <onborodin@gmail.com>
*/
package imageoper
import (
"context"
"fmt"
"net/http"
"mstore/pkg/descr"
ocidigest "github.com/opencontainers/go-digest"
)
type DeleteManifestParams struct {
Name string
Reference string
}
type DeleteManifestResult struct{}
func (oper *Operator) DeleteManifest(ctx context.Context, params *DeleteManifestParams) (*DeleteManifestResult, int, error) {
var err error
res := &DeleteManifestResult{}
if params.Name == "" {
err = fmt.Errorf("Empty name")
return res, http.StatusBadRequest, err
}
if params.Reference == "" {
err = fmt.Errorf("Empty reference")
return res, http.StatusBadRequest, err
}
resName := params.Name
oper.iLock.WaitAndLock(resName)
defer oper.iLock.Done(resName)
var exists bool
var reference string
mandescr := descr.Manifest{}
// Check manifest by digest as name
digobj, err := ocidigest.Parse(params.Reference)
if err == nil {
exists, mandescr, err = oper.mdb.GetManifestByDigest(ctx, params.Name, digobj.String())
if err != nil {
return res, http.StatusInternalServerError, err
}
if !exists {
return res, http.StatusNotFound, err
}
reference = mandescr.Reference
err = oper.deleteManifestObjects(ctx, params.Name, reference)
if err != nil {
return res, http.StatusInternalServerError, err
}
} else {
/*
// Check manifest by name and reference
exists, mandescrs, err := oper.mdb.GetManifestsByReference(ctx, params.Name, params.Reference)
if err != nil {
return res, http.StatusInternalServerError, err
}
if !exists {
return res, http.StatusNotFound, err
}
reference = params.Reference
for _, mandescr := range mandescrs {
reference = mandescr.Reference
err = oper.deleteManifestObjects(ctx, params.Name, reference)
if err != nil {
return res, http.StatusInternalServerError, err
}
}
*/
// Check manifest by name and reference
exists, mandescr, err := oper.mdb.GetManifestByReference(ctx, params.Name, params.Reference)
if err != nil {
return res, http.StatusInternalServerError, err
}
if !exists {
return res, http.StatusNotFound, err
}
err = oper.deleteManifestObjects(ctx, mandescr.Name, mandescr.Reference)
if err != nil {
return res, http.StatusInternalServerError, err
}
}
// Get blobs associated with the name
return res, http.StatusAccepted, err
}
func (oper *Operator) deleteManifestObjects(ctx context.Context, name, reference string) error {
var err error
// Get blobs associated with the name
layers, err := oper.mdb.GetBlobsByReferense(ctx, name, reference)
if err != nil {
return err
}
for _, blob := range layers {
// Delete descr record
err = oper.mdb.DeleteBlobByNameDigest(ctx, blob.Name, blob.Digest)
if err != nil {
return err
}
// Check blob file
exists, _, err := oper.store.BlobExists(name, blob.Digest)
if err != nil {
return err
}
if exists {
// Check blob usage
blobUsage, err := oper.mdb.GetBlobUsage(ctx, blob.Name, blob.Digest)
if err != nil {
return err
}
// Delete if blob useless
if blobUsage == 0 {
err = oper.store.DeleteBlob(name, blob.Digest)
if err != nil {
return err
}
}
}
}
err = oper.mdb.DeleteManifest(ctx, name, reference)
if err != nil {
return err
}
return err
}