Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

remove-image: Add optional LookupManifest to RemoveImagesOptions. #753

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions libimage/manifest_list_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,3 +75,43 @@ func TestCreateAndTagManifestList(t *testing.T) {
// Both origin list and newly tagged list should point to same image id
require.Equal(t, image.ID(), taggedImage.ID())
}

// Following test ensure that we test Removing a manifestList
// Test tags two manifestlist and deletes one of them and
// confirms if other one is not deleted.
func TestCreateAndRemoveManifestList(t *testing.T) {

tagName := "manifestlisttagged"
listName := "manifestlist"
runtime, cleanup := testNewRuntime(t)
defer cleanup()
ctx := context.Background()

list, err := runtime.CreateManifestList(listName)
require.NoError(t, err)
require.NotNil(t, list)

manifestListOpts := &ManifestListAddOptions{All: true}
_, err = list.Add(ctx, "docker://busybox", manifestListOpts)
require.NoError(t, err)

lookupOptions := &LookupImageOptions{ManifestList: true}
image, _, err := runtime.LookupImage(listName, lookupOptions)
require.NoError(t, err)
require.NotNil(t, image)
err = image.Tag(tagName)
require.NoError(t, err, "tag should have succeeded: %s", tagName)

// Try deleting the manifestList with tag
rmReports, rmErrors := runtime.RemoveImages(ctx, []string{tagName}, &RemoveImagesOptions{Force: true, LookupManifest: true})
require.Nil(t, rmErrors)
require.Equal(t, []string{"localhost/manifestlisttagged:latest"}, rmReports[0].Untagged)

// Remove original listname as well
rmReports, rmErrors = runtime.RemoveImages(ctx, []string{listName}, &RemoveImagesOptions{Force: true, LookupManifest: true})
require.Nil(t, rmErrors)
// output should contain log of untagging the original manifestlist
require.True(t, rmReports[0].Removed)
require.Equal(t, []string{"localhost/manifestlist:latest"}, rmReports[0].Untagged)
vrothberg marked this conversation as resolved.
Show resolved Hide resolved

}
16 changes: 15 additions & 1 deletion libimage/runtime.go
Original file line number Diff line number Diff line change
Expand Up @@ -541,6 +541,11 @@ type RemoveImagesOptions struct {
// using a removed image. Use RemoveContainerFunc for a custom logic.
// If set, all child images will be removed as well.
Force bool
// LookupManifest will expect all specified names to be manifest lists (no instance look up).
// This allows for removing manifest lists.
// By default, RemoveImages will attempt to resolve to a manifest instance matching
// the local platform (i.e., os, architecture, variant).
LookupManifest bool
vrothberg marked this conversation as resolved.
Show resolved Hide resolved
// RemoveContainerFunc allows for a custom logic for removing
// containers using a specific image. By default, all containers in
// the local containers storage will be removed (if Force is set).
Expand Down Expand Up @@ -600,13 +605,22 @@ func (r *Runtime) RemoveImages(ctx context.Context, names []string, options *Rem
toDelete := []string{}
// Look up images in the local containers storage and fill out
// toDelete and the deleteMap.

switch {
case len(names) > 0:
// prepare lookupOptions
var lookupOptions *LookupImageOptions
if options.LookupManifest {
// LookupManifest configured as true make sure we only remove manifests and no referenced images.
lookupOptions = &LookupImageOptions{lookupManifest: true}
} else {
lookupOptions = &LookupImageOptions{returnManifestIfNoInstance: true}
}
// Look up the images one-by-one. That allows for removing
// images that have been looked up successfully while reporting
// lookup errors at the end.
for _, name := range names {
img, resolvedName, err := r.LookupImage(name, &LookupImageOptions{returnManifestIfNoInstance: true})
img, resolvedName, err := r.LookupImage(name, lookupOptions)
if err != nil {
appendError(err)
continue
Expand Down