Skip to content

Commit

Permalink
runtime: Adds RemoveManifestLists and (*ManifestList) Remove
Browse files Browse the repository at this point in the history
Adding `Remove` to *ManifestLists and RemoveManifestLists which takes
list of manifests and remove them in an iterative manner.

Signed-off-by: Aditya Rajan <[email protected]>
  • Loading branch information
flouthoc committed Sep 1, 2021
1 parent 08184df commit b2ae05a
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 0 deletions.
Binary file added libimage/.image.go.swp
Binary file not shown.
5 changes: 5 additions & 0 deletions libimage/manifest_list.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,11 @@ func (i *Image) ToManifestList() (*ManifestList, error) {
return &ManifestList{image: i, list: list}, nil
}

// Remove the current manifest list.
func (m *ManifestList) Remove(ctx context.Context, rmMap map[string]*RemoveImageReport, ref string) ([]string, error) {
return m.image.remove(ctx, rmMap, ref, &RemoveImagesOptions{Force: true})
}

// LookupInstance looks up an instance of the manifest list matching the
// specified platform. The local machine's platform is used if left empty.
func (m *ManifestList) LookupInstance(ctx context.Context, architecture, os, variant string) (*Image, error) {
Expand Down
83 changes: 83 additions & 0 deletions libimage/runtime.go
Original file line number Diff line number Diff line change
Expand Up @@ -676,3 +676,86 @@ func (r *Runtime) RemoveImages(ctx context.Context, names []string, options *Rem

return reports, rmErrors
}

// Takes list of names as argument and removes one or more manifest lists.
func (r *Runtime) RemoveManifestLists(ctx context.Context, names []string) (reports []*RemoveImageReport, rmErrors []error) {
type deleteMe struct {
manifestList *ManifestList
manifestTagName string
manifestID string
}

appendError := func(err error) {
rmErrors = append(rmErrors, err)
}

deleteMap := make(map[string]*deleteMe) // ID -> deleteMe
toDelete := []string{}

if len(names) > 0 {
// Look up the manifest list one-by-one. That allows for removing
// manifest lists that have been looked up successfully while reporting
// lookup errors at the end.
for _, name := range names {
m, err := r.LookupManifestList(name)
if err != nil {
appendError(err)
continue
}
dm, exists := deleteMap[name]
if !exists {
// empty ref if name does not matches any tag
// if ref empty all the manifest list with same id will be removed
manifestName := ""
toDelete = append(toDelete, name)
for _, manifestTag := range m.image.Names() {
if strings.Contains(manifestTag, name) || manifestTag == name {
manifestName = manifestTag
}
}
dm = &deleteMe{manifestList: m, manifestTagName: manifestName, manifestID: m.image.ID()}
deleteMap[name] = dm
}
}

}

// Return early if there's no manifest lists to delete.
if len(deleteMap) == 0 {
return nil, rmErrors
}

// Now remove the manifest lists in the given order.
rmMap := make(map[string]*RemoveImageReport)
orderedIDs := []string{}
visitedIDs := make(map[string]bool)
for _, name := range toDelete {
del, exists := deleteMap[name]
if !exists {
appendError(errors.Errorf("internal error: ID %s not in found in image-deletion map", del.manifestID))
continue
}
processedIDs, err := del.manifestList.Remove(ctx, rmMap, del.manifestTagName)
if err != nil {
appendError(err)
}
// NOTE: make sure to add given ID only once to orderedIDs.
for _, id := range processedIDs {
if visited := visitedIDs[id]; visited {
continue
}
orderedIDs = append(orderedIDs, id)
visitedIDs[id] = true
}
}

// Finally, we can assemble the reports slice.
for _, id := range orderedIDs {
report, exists := rmMap[id]
if exists {
reports = append(reports, report)
}
}

return reports, rmErrors
}

0 comments on commit b2ae05a

Please sign in to comment.