Skip to content

Commit

Permalink
Merge pull request #3822 from haytok/nerdctl_issue_3806
Browse files Browse the repository at this point in the history
fix: save multiple images for the same image id to a tar archive
  • Loading branch information
fahedouch authored Jan 19, 2025
2 parents 343a122 + 9a6426d commit b792f1f
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 3 deletions.
57 changes: 57 additions & 0 deletions cmd/nerdctl/image/image_save_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,3 +138,60 @@ func TestSave(t *testing.T) {

testCase.Run(t)
}

// TestSaveMultipleImagesWithSameIDAndLoad tests https://github.com/containerd/nerdctl/issues/3806
func TestSaveMultipleImagesWithSameIDAndLoad(t *testing.T) {
testCase := nerdtest.Setup()

// This test relies on the fact that we can remove the common image, which definitely conflicts with others,
// hence the private mode.
// Further note though, that this will hide the fact this the save command could fail if some layers are missing.
// See https://github.com/containerd/nerdctl/issues/3425 and others for details.
testCase.Require = nerdtest.Private

if runtime.GOOS == "windows" {
testCase.Require = nerdtest.IsFlaky("https://github.com/containerd/nerdctl/issues/3524")
}

testCase.SubTests = []*test.Case{
{
Description: "Issue #3568 - Save multiple container images with the same image ID but different image names",
NoParallel: true,
Cleanup: func(data test.Data, helpers test.Helpers) {
if data.Get("id") != "" {
helpers.Anyhow("rmi", "-f", data.Get("id"))
}
},
Setup: func(data test.Data, helpers test.Helpers) {
helpers.Ensure("pull", "--quiet", testutil.CommonImage)
img := nerdtest.InspectImage(helpers, testutil.CommonImage)
var id string
if nerdtest.IsDocker() {
id = img.ID
} else {
id = strings.Split(img.RepoDigests[0], ":")[1]
}
helpers.Ensure("tag", testutil.CommonImage, data.Identifier())
tarPath := filepath.Join(data.TempDir(), "out.tar")
helpers.Ensure("save", "-o", tarPath, testutil.CommonImage, data.Identifier())
helpers.Ensure("rmi", "-f", id)
helpers.Ensure("load", "-i", tarPath)
data.Set("id", id)
},
Command: func(data test.Data, helpers test.Helpers) test.TestableCommand {
return helpers.Command("images", "--no-trunc")
},
Expected: func(data test.Data, helpers test.Helpers) *test.Expected {
return &test.Expected{
ExitCode: 0,
Errors: []error{},
Output: func(stdout string, info string, t *testing.T) {
assert.Equal(t, strings.Count(stdout, data.Get("id")), 2)
},
}
},
},
}

testCase.Run(t)
}
5 changes: 2 additions & 3 deletions pkg/cmd/image/save.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,8 @@ func Save(ctx context.Context, client *containerd.Client, images []string, optio
}

imgName := found.Image.Name
imgDigest := found.Image.Target.Digest.String()
if _, ok := savedImages[imgDigest]; !ok {
savedImages[imgDigest] = struct{}{}
if _, ok := savedImages[imgName]; !ok {
savedImages[imgName] = struct{}{}
exportOpts = append(exportOpts, archive.WithImage(imageStore, imgName))
}
return nil
Expand Down

0 comments on commit b792f1f

Please sign in to comment.