From 6aa644c648ff66df9f35f63518ceb981c3b6d3ae Mon Sep 17 00:00:00 2001 From: apostasie Date: Wed, 18 Sep 2024 12:26:18 -0700 Subject: [PATCH] Ensure all layers are here when committing Signed-off-by: apostasie --- .../container/container_commit_linux_test.go | 15 +++++++++------ pkg/cmd/container/commit.go | 2 +- pkg/imgutil/commit/commit.go | 9 ++++++++- 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/cmd/nerdctl/container/container_commit_linux_test.go b/cmd/nerdctl/container/container_commit_linux_test.go index 24c791d4f60..2ea35c0b4cf 100644 --- a/cmd/nerdctl/container/container_commit_linux_test.go +++ b/cmd/nerdctl/container/container_commit_linux_test.go @@ -17,12 +17,14 @@ package container import ( + "fmt" "strings" "testing" "gotest.tools/v3/icmd" "github.com/containerd/nerdctl/v2/pkg/testutil" + "github.com/containerd/nerdctl/v2/pkg/testutil/testregistry" ) /* @@ -35,13 +37,14 @@ It will regularly succeed or fail, making random PR fail the Kube check. func TestKubeCommitPush(t *testing.T) { t.Parallel() - t.Skip("Test that confirm that #827 is still broken is too flaky") - base := testutil.NewBaseForKubernetes(t) tID := testutil.Identifier(t) var containerID string + // Start a registry + reg := testregistry.NewWithNoAuth(base, 0, false) + setup := func() { testutil.KubectlHelper(base, "run", "--image", testutil.CommonImage, tID, "--", "sleep", "Inf"). AssertOK() @@ -59,6 +62,7 @@ func TestKubeCommitPush(t *testing.T) { tearDown := func() { testutil.KubectlHelper(base, "delete", "pod", "-f", tID).Run() + reg.Cleanup(nil) } tearDown() @@ -70,11 +74,10 @@ func TestKubeCommitPush(t *testing.T) { "Currently, this is broken, hence the test assumes it will fail. Once the problem is fixed, we should just" + "change the expectation to 'success'.") - base.Cmd("commit", containerID, "registry.example.com/my-app:v1").AssertOK() + base.Cmd("commit", containerID, fmt.Sprintf("127.0.0.1:%d/my-app:v1", reg.Port)).AssertOK() // See note above. - base.Cmd("push", "registry.example.com/my-app:v1").Assert(icmd.Expected{ - ExitCode: 1, - Err: "failed to create a tmp single-platform image", + base.Cmd("push", fmt.Sprintf("127.0.0.1:%d/my-app:v1", reg.Port)).Assert(icmd.Expected{ + ExitCode: 0, }) }) } diff --git a/pkg/cmd/container/commit.go b/pkg/cmd/container/commit.go index 32f78d871be..45a16ac0227 100644 --- a/pkg/cmd/container/commit.go +++ b/pkg/cmd/container/commit.go @@ -57,7 +57,7 @@ func Commit(ctx context.Context, client *containerd.Client, rawRef string, req s if found.MatchCount > 1 { return fmt.Errorf("multiple IDs found with provided prefix: %s", found.Req) } - imageID, err := commit.Commit(ctx, client, found.Container, opts) + imageID, err := commit.Commit(ctx, client, found.Container, opts, options.GOptions) if err != nil { return err } diff --git a/pkg/imgutil/commit/commit.go b/pkg/imgutil/commit/commit.go index 44e582052cb..73aec32d85a 100644 --- a/pkg/imgutil/commit/commit.go +++ b/pkg/imgutil/commit/commit.go @@ -44,6 +44,7 @@ import ( "github.com/containerd/log" "github.com/containerd/platforms" + "github.com/containerd/nerdctl/v2/pkg/api/types" imgutil "github.com/containerd/nerdctl/v2/pkg/imgutil" "github.com/containerd/nerdctl/v2/pkg/labels" ) @@ -65,7 +66,7 @@ var ( emptyDigest = digest.Digest("") ) -func Commit(ctx context.Context, client *containerd.Client, container containerd.Container, opts *Opts) (digest.Digest, error) { +func Commit(ctx context.Context, client *containerd.Client, container containerd.Container, opts *Opts, options types.GlobalCommandOptions) (digest.Digest, error) { id := container.ID() info, err := container.Info(ctx) if err != nil { @@ -96,6 +97,12 @@ func Commit(ctx context.Context, client *containerd.Client, container containerd return emptyDigest, err } + // Ensure all the layers are here: https://github.com/containerd/nerdctl/issues/3425 + err = imgutil.EnsureAllContent(ctx, client, baseImg.Name(), "", options) + if err != nil { + return emptyDigest, err + } + if opts.Pause { task, err := container.Task(ctx, cio.Load) if err != nil {