From 764a2aa51f17461515fdb1fe0ead5a031df0b5e1 Mon Sep 17 00:00:00 2001 From: apostasie Date: Tue, 24 Sep 2024 21:23:04 -0700 Subject: [PATCH] Fix tests and add regression tests for #3425 Signed-off-by: apostasie --- .../container/container_commit_linux_test.go | 46 ++- cmd/nerdctl/image/image_inspect_test.go | 300 ++++++++++-------- cmd/nerdctl/image/image_list_test.go | 3 +- cmd/nerdctl/issues/issues_linux_test.go | 133 ++++++++ hack/build-integration-kubernetes.sh | 19 +- hack/kind.yaml | 2 + pkg/testutil/nerdtest/test.go | 14 + 7 files changed, 374 insertions(+), 143 deletions(-) create mode 100644 cmd/nerdctl/issues/issues_linux_test.go diff --git a/cmd/nerdctl/container/container_commit_linux_test.go b/cmd/nerdctl/container/container_commit_linux_test.go index 24c791d4f60..8a4af41fdcd 100644 --- a/cmd/nerdctl/container/container_commit_linux_test.go +++ b/cmd/nerdctl/container/container_commit_linux_test.go @@ -20,8 +20,6 @@ import ( "strings" "testing" - "gotest.tools/v3/icmd" - "github.com/containerd/nerdctl/v2/pkg/testutil" ) @@ -35,12 +33,11 @@ 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 + // var registryIP string setup := func() { testutil.KubectlHelper(base, "run", "--image", testutil.CommonImage, tID, "--", "sleep", "Inf"). @@ -55,10 +52,37 @@ func TestKubeCommitPush(t *testing.T) { cmd := testutil.KubectlHelper(base, "get", "pods", tID, "-o", "jsonpath={ .status.containerStatuses[0].containerID }") cmd.Run() containerID = strings.TrimPrefix(cmd.Out(), "containerd://") + + // This below is missing configuration to allow for plain http communication + // This is left here for future work to successfully start a registry usable in the cluster + /* + // Start a registry + testutil.KubectlHelper(base, "run", "--port", "5000", "--image", testutil.RegistryImageStable, "testregistry"). + AssertOK() + + testutil.KubectlHelper(base, "wait", "pod", "testregistry", "--for=condition=ready", "--timeout=1m"). + AssertOK() + + cmd = testutil.KubectlHelper(base, "get", "pods", tID, "-o", "jsonpath={ .status.hostIPs[0].ip }") + cmd.Run() + registryIP = cmd.Out() + + cmd = testutil.KubectlHelper(base, "apply", "-f", "-", fmt.Sprintf(`apiVersion: v1 + kind: ConfigMap + metadata: + name: local-registry + namespace: nerdctl-test + data: + localRegistryHosting.v1: | + host: "%s:5000" + help: "https://kind.sigs.k8s.io/docs/user/local-registry/" + `, registryIP)) + */ + } tearDown := func() { - testutil.KubectlHelper(base, "delete", "pod", "-f", tID).Run() + testutil.KubectlHelper(base, "delete", "pod", "--all").Run() } tearDown() @@ -66,15 +90,7 @@ func TestKubeCommitPush(t *testing.T) { setup() t.Run("test commit / push on Kube (https://github.com/containerd/nerdctl/issues/827)", func(t *testing.T) { - t.Log("This test is meant to verify that we can commit / push an image from a pod." + - "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() - // 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("commit", containerID, "testcommitsave").AssertOK() + base.Cmd("save", "testcommitsave").AssertOK() }) } diff --git a/cmd/nerdctl/image/image_inspect_test.go b/cmd/nerdctl/image/image_inspect_test.go index 14fcb90caf8..95154304d1c 100644 --- a/cmd/nerdctl/image/image_inspect_test.go +++ b/cmd/nerdctl/image/image_inspect_test.go @@ -26,69 +26,52 @@ import ( "github.com/containerd/nerdctl/v2/pkg/inspecttypes/dockercompat" "github.com/containerd/nerdctl/v2/pkg/testutil" + "github.com/containerd/nerdctl/v2/pkg/testutil/nerdtest" + "github.com/containerd/nerdctl/v2/pkg/testutil/test" ) -func TestImageInspectContainsSomeStuff(t *testing.T) { - base := testutil.NewBase(t) - - base.Cmd("pull", testutil.CommonImage).AssertOK() - inspect := base.InspectImage(testutil.CommonImage) - - assert.Assert(base.T, len(inspect.RootFS.Layers) > 0) - assert.Assert(base.T, inspect.RootFS.Type != "") - assert.Assert(base.T, inspect.Architecture != "") - assert.Assert(base.T, inspect.Size > 0) -} - -func TestImageInspectWithFormat(t *testing.T) { - base := testutil.NewBase(t) - - base.Cmd("pull", testutil.CommonImage).AssertOK() - - // test RawFormat support - base.Cmd("image", "inspect", testutil.CommonImage, "--format", "{{.Id}}").AssertOK() - - // test typedFormat support - base.Cmd("image", "inspect", testutil.CommonImage, "--format", "{{.ID}}").AssertOK() -} - -func inspectImageHelper(base *testutil.Base, identifier ...string) []dockercompat.Image { - args := append([]string{"image", "inspect"}, identifier...) - cmdResult := base.Cmd(args...).Run() - assert.Equal(base.T, cmdResult.ExitCode, 0) - var dc []dockercompat.Image - if err := json.Unmarshal([]byte(cmdResult.Stdout()), &dc); err != nil { - base.T.Fatal(err) +func TestImageInspectSimpleCases(t *testing.T) { + nerdtest.Setup() + + testCase := &test.Case{ + Description: "TestImageInspect", + Setup: func(data test.Data, helpers test.Helpers) { + helpers.Ensure("pull", testutil.CommonImage) + }, + SubTests: []*test.Case{ + { + Description: "Contains some stuff", + Command: test.RunCommand("image", "inspect", testutil.CommonImage), + Expected: test.Expects(0, nil, func(stdout string, info string, t *testing.T) { + var dc []dockercompat.Image + err := json.Unmarshal([]byte(stdout), &dc) + assert.NilError(t, err, "Unable to unmarshal output\n"+info) + assert.Equal(t, 1, len(dc), "Unexpectedly got multiple results\n"+info) + assert.Assert(t, len(dc[0].RootFS.Layers) > 0, info) + assert.Assert(t, dc[0].Architecture != "", info) + assert.Assert(t, dc[0].Size > 0, info) + }), + }, + { + Description: "RawFormat support (.Id)", + Command: test.RunCommand("image", "inspect", testutil.CommonImage, "--format", "{{.Id}}"), + Expected: test.Expects(0, nil, nil), + }, + { + Description: "typedFormat support (.ID)", + Command: test.RunCommand("image", "inspect", testutil.CommonImage, "--format", "{{.ID}}"), + Expected: test.Expects(0, nil, nil), + }, + }, } - return dc + + testCase.Run(t) } func TestImageInspectDifferentValidReferencesForTheSameImage(t *testing.T) { - testutil.DockerIncompatible(t) + nerdtest.Setup() - if runtime.GOOS == "windows" { - t.Skip("Windows is not supported for this test right now") - } - - base := testutil.NewBase(t) - - // Overall, we need a clean slate before doing these lookups. - // More specifically, because we trigger https://github.com/containerd/nerdctl/issues/3016 - // we cannot do selective rmi, so, just nuke everything - ids := base.Cmd("image", "list", "-q").Out() - allIDs := strings.Split(ids, "\n") - for _, id := range allIDs { - id = strings.TrimSpace(id) - if id != "" { - base.Cmd("rmi", "-f", id).Run() - } - } - - base.Cmd("pull", "alpine", "--platform", "linux/amd64").AssertOK() - base.Cmd("pull", "busybox", "--platform", "linux/amd64").AssertOK() - base.Cmd("pull", "busybox:stable", "--platform", "linux/amd64").AssertOK() - base.Cmd("pull", "registry-1.docker.io/library/busybox", "--platform", "linux/amd64").AssertOK() - base.Cmd("pull", "registry-1.docker.io/library/busybox:stable", "--platform", "linux/amd64").AssertOK() + platform := runtime.GOOS + "/" + runtime.GOARCH tags := []string{ "", @@ -102,76 +85,141 @@ func TestImageInspectDifferentValidReferencesForTheSameImage(t *testing.T) { "registry-1.docker.io/library/busybox", } - // Build reference values for comparison - reference := inspectImageHelper(base, "busybox") - assert.Equal(base.T, 1, len(reference)) - // Extract image sha - sha := strings.TrimPrefix(reference[0].RepoDigests[0], "busybox@sha256:") - - differentReference := inspectImageHelper(base, "alpine") - assert.Equal(base.T, 1, len(differentReference)) - - // Testing all name and tags variants - for _, name := range names { - for _, tag := range tags { - t.Logf("Testing %s", name+tag) - result := inspectImageHelper(base, name+tag) - assert.Equal(base.T, 1, len(result)) - assert.Equal(base.T, reference[0].ID, result[0].ID) - } - } - - // Testing all name and tags variants, with a digest - for _, name := range names { - for _, tag := range tags { - t.Logf("Testing %s", name+tag+"@"+sha) - result := inspectImageHelper(base, name+tag+"@sha256:"+sha) - assert.Equal(base.T, 1, len(result)) - assert.Equal(base.T, reference[0].ID, result[0].ID) - } - } - - // Testing repo digest and short digest with or without prefix - for _, id := range []string{"sha256:" + sha, sha, sha[0:8], "sha256:" + sha[0:8]} { - t.Logf("Testing %s", id) - result := inspectImageHelper(base, id) - assert.Equal(base.T, 1, len(result)) - assert.Equal(base.T, reference[0].ID, result[0].ID) + testCase := &test.Case{ + Description: "TestImageInspectDifferentValidReferencesForTheSameImage", + Require: test.Require( + test.Not(nerdtest.Docker), + test.Not(test.Windows), + // We need a clean slate + nerdtest.Private, + ), + Setup: func(data test.Data, helpers test.Helpers) { + helpers.Ensure("pull", "alpine", "--platform", platform) + helpers.Ensure("pull", "busybox", "--platform", platform) + helpers.Ensure("pull", "busybox:stable", "--platform", platform) + helpers.Ensure("pull", "registry-1.docker.io/library/busybox", "--platform", platform) + helpers.Ensure("pull", "registry-1.docker.io/library/busybox:stable", "--platform", platform) + }, + SubTests: []*test.Case{ + { + Description: "name and tags +/- sha combinations", + Command: test.RunCommand("image", "inspect", "busybox"), + Expected: func(data test.Data, helpers test.Helpers) *test.Expected { + return &test.Expected{ + Output: func(stdout string, info string, t *testing.T) { + var dc []dockercompat.Image + err := json.Unmarshal([]byte(stdout), &dc) + assert.NilError(t, err, "Unable to unmarshal output\n"+info) + assert.Equal(t, 1, len(dc), "Unexpectedly got multiple results\n"+info) + reference := dc[0].ID + sha := strings.TrimPrefix(dc[0].RepoDigests[0], "busybox@sha256:") + + for _, name := range names { + for _, tag := range tags { + it := nerdtest.InspectImage(helpers, name+tag) + assert.Equal(t, it.ID, reference) + it = nerdtest.InspectImage(helpers, name+tag+"@sha256:"+sha) + assert.Equal(t, it.ID, reference) + } + } + }, + } + }, + }, + { + Description: "by digest, short or long, with or without prefix", + Command: test.RunCommand("image", "inspect", "busybox"), + Expected: func(data test.Data, helpers test.Helpers) *test.Expected { + return &test.Expected{ + Output: func(stdout string, info string, t *testing.T) { + var dc []dockercompat.Image + err := json.Unmarshal([]byte(stdout), &dc) + assert.NilError(t, err, "Unable to unmarshal output\n"+info) + assert.Equal(t, 1, len(dc), "Unexpectedly got multiple results\n"+info) + reference := dc[0].ID + sha := strings.TrimPrefix(dc[0].RepoDigests[0], "busybox@sha256:") + + for _, id := range []string{"sha256:" + sha, sha, sha[0:8], "sha256:" + sha[0:8]} { + it := nerdtest.InspectImage(helpers, id) + assert.Equal(t, it.ID, reference) + } + + // Now, tag alpine with a short id + // Build reference values for comparison + alpine := nerdtest.InspectImage(helpers, "alpine") + + // Demonstrate image name precedence over digest lookup + // Using the shortened sha should no longer get busybox, but rather the newly tagged Alpine + helpers.Ensure("tag", "alpine", sha[0:8]) + it := nerdtest.InspectImage(helpers, sha[0:8]) + assert.Equal(t, it.ID, alpine.ID, alpine.ID+" vs "+it.ID) + }, + } + }, + }, + { + Description: "prove that wrong references with correct digest do not get resolved", + Command: test.RunCommand("image", "inspect", "busybox"), + Expected: func(data test.Data, helpers test.Helpers) *test.Expected { + return &test.Expected{ + Output: func(stdout string, info string, t *testing.T) { + var dc []dockercompat.Image + err := json.Unmarshal([]byte(stdout), &dc) + assert.NilError(t, err, "Unable to unmarshal output\n"+info) + assert.Equal(t, 1, len(dc), "Unexpectedly got multiple results\n"+info) + sha := strings.TrimPrefix(dc[0].RepoDigests[0], "busybox@sha256:") + + for _, id := range []string{"doesnotexist", "doesnotexist:either", "busybox:bogustag"} { + cmd := helpers.Command("image", "inspect", id+"@sha256:"+sha) + cmd.Run(&test.Expected{ + Output: test.Equals(""), + }) + } + }, + } + }, + }, + { + Description: "prove that invalid reference return no result without crashing", + Command: test.RunCommand("image", "inspect", "busybox"), + Expected: func(data test.Data, helpers test.Helpers) *test.Expected { + return &test.Expected{ + Output: func(stdout string, info string, t *testing.T) { + var dc []dockercompat.Image + err := json.Unmarshal([]byte(stdout), &dc) + assert.NilError(t, err, "Unable to unmarshal output\n"+info) + assert.Equal(t, 1, len(dc), "Unexpectedly got multiple results\n"+info) + + for _, id := range []string{"∞∞∞∞∞∞∞∞∞∞", "busybox:∞∞∞∞∞∞∞∞∞∞"} { + cmd := helpers.Command("image", "inspect", id) + cmd.Run(&test.Expected{ + Output: test.Equals(""), + }) + } + }, + } + }, + }, + { + Description: "retrieving multiple entries at once", + Command: test.RunCommand("image", "inspect", "busybox", "busybox", "busybox:stable"), + Expected: func(data test.Data, helpers test.Helpers) *test.Expected { + return &test.Expected{ + Output: func(stdout string, info string, t *testing.T) { + var dc []dockercompat.Image + err := json.Unmarshal([]byte(stdout), &dc) + assert.NilError(t, err, "Unable to unmarshal output\n"+info) + assert.Equal(t, 3, len(dc), "Unexpectedly did not get 3 results\n"+info) + reference := nerdtest.InspectImage(helpers, "busybox") + assert.Equal(t, dc[0].ID, reference.ID) + assert.Equal(t, dc[1].ID, reference.ID) + assert.Equal(t, dc[2].ID, reference.ID) + }, + } + }, + }, + }, } - // Demonstrate image name precedence over digest lookup - // Using the shortened sha should no longer get busybox, but rather the newly tagged Alpine - t.Logf("Testing (alpine tagged) %s", sha[0:8]) - // Tag a different image with the short id - base.Cmd("tag", "alpine", sha[0:8]).AssertOK() - result := inspectImageHelper(base, sha[0:8]) - assert.Equal(base.T, 1, len(result)) - assert.Equal(base.T, differentReference[0].ID, result[0].ID) - - // Prove that wrong references with an existing digest do not get retrieved when asking by digest - for _, id := range []string{"doesnotexist", "doesnotexist:either", "busybox:bogustag"} { - t.Logf("Testing %s", id+"@"+sha) - args := append([]string{"image", "inspect"}, id+"@"+sha) - cmdResult := base.Cmd(args...).Run() - assert.Equal(base.T, cmdResult.ExitCode, 0) - assert.Equal(base.T, cmdResult.Stdout(), "") - } - - // Prove that invalid reference return no result without crashing - for _, id := range []string{"∞∞∞∞∞∞∞∞∞∞", "busybox:∞∞∞∞∞∞∞∞∞∞"} { - t.Logf("Testing %s", id) - args := append([]string{"image", "inspect"}, id) - cmdResult := base.Cmd(args...).Run() - assert.Equal(base.T, cmdResult.ExitCode, 0) - assert.Equal(base.T, cmdResult.Stdout(), "") - } - - // Retrieving multiple entries at once - t.Logf("Testing %s", "busybox busybox busybox:stable") - result = inspectImageHelper(base, "busybox", "busybox", "busybox:stable") - assert.Equal(base.T, 3, len(result)) - assert.Equal(base.T, reference[0].ID, result[0].ID) - assert.Equal(base.T, reference[0].ID, result[1].ID) - assert.Equal(base.T, reference[0].ID, result[2].ID) - + testCase.Run(t) } diff --git a/cmd/nerdctl/image/image_list_test.go b/cmd/nerdctl/image/image_list_test.go index 72e902fa62b..93cd9a7965a 100644 --- a/cmd/nerdctl/image/image_list_test.go +++ b/cmd/nerdctl/image/image_list_test.go @@ -125,7 +125,8 @@ func TestImagesFilterDangling(t *testing.T) { testutil.RequiresBuild(t) testutil.RegisterBuildCacheCleanup(t) base := testutil.NewBase(t) - base.Cmd("images", "prune", "--all").AssertOK() + base.Cmd("container", "prune", "-f").AssertOK() + base.Cmd("image", "prune", "--all", "-f").AssertOK() dockerfile := fmt.Sprintf(`FROM %s CMD ["echo", "nerdctl-build-notag-string"] diff --git a/cmd/nerdctl/issues/issues_linux_test.go b/cmd/nerdctl/issues/issues_linux_test.go new file mode 100644 index 00000000000..72f68b707b5 --- /dev/null +++ b/cmd/nerdctl/issues/issues_linux_test.go @@ -0,0 +1,133 @@ +/* + Copyright The containerd Authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +// Package issues is meant to document testing for complex scenarios type of issues that cannot simply be ascribed +// to a specific package. +package issues + +import ( + "fmt" + "testing" + + "github.com/containerd/nerdctl/v2/pkg/testutil" + "github.com/containerd/nerdctl/v2/pkg/testutil/nerdtest" + "github.com/containerd/nerdctl/v2/pkg/testutil/test" + "github.com/containerd/nerdctl/v2/pkg/testutil/testregistry" +) + +func TestMain(m *testing.M) { + testutil.M(m) +} + +func TestIssue3425(t *testing.T) { + nerdtest.Setup() + + var registry *testregistry.RegistryServer + + testCase := &test.Case{ + Description: "TestIssue3425", + Setup: func(data test.Data, helpers test.Helpers) { + base := testutil.NewBase(t) + registry = testregistry.NewWithNoAuth(base, 0, false) + }, + Cleanup: func(data test.Data, helpers test.Helpers) { + if registry != nil { + registry.Cleanup(nil) + } + }, + SubTests: []*test.Case{ + { + Description: "with tag", + Require: nerdtest.Private, + Setup: func(data test.Data, helpers test.Helpers) { + helpers.Ensure("image", "pull", testutil.CommonImage) + helpers.Ensure("run", "-d", "--name", data.Identifier(), testutil.CommonImage) + helpers.Ensure("image", "rm", "-f", testutil.CommonImage) + helpers.Ensure("image", "pull", testutil.CommonImage) + helpers.Ensure("tag", testutil.CommonImage, fmt.Sprintf("localhost:%d/%s", registry.Port, data.Identifier())) + }, + Cleanup: func(data test.Data, helpers test.Helpers) { + helpers.Anyhow("rm", "-f", data.Identifier()) + helpers.Anyhow("rmi", "-f", fmt.Sprintf("localhost:%d/%s", registry.Port, data.Identifier())) + }, + Command: func(data test.Data, helpers test.Helpers) test.Command { + return helpers.Command("push", fmt.Sprintf("localhost:%d/%s", registry.Port, data.Identifier())) + }, + Expected: test.Expects(0, nil, nil), + }, + { + Description: "with commit", + Require: nerdtest.Private, + Setup: func(data test.Data, helpers test.Helpers) { + helpers.Ensure("image", "pull", testutil.CommonImage) + helpers.Ensure("run", "-d", "--name", data.Identifier(), testutil.CommonImage, "touch", "/something") + helpers.Ensure("image", "rm", "-f", testutil.CommonImage) + helpers.Ensure("image", "pull", testutil.CommonImage) + helpers.Ensure("commit", data.Identifier(), fmt.Sprintf("localhost:%d/%s", registry.Port, data.Identifier())) + }, + Cleanup: func(data test.Data, helpers test.Helpers) { + helpers.Anyhow("rm", "-f", data.Identifier()) + helpers.Anyhow("rmi", "-f", fmt.Sprintf("localhost:%d/%s", registry.Port, data.Identifier())) + }, + Command: func(data test.Data, helpers test.Helpers) test.Command { + return helpers.Command("push", fmt.Sprintf("localhost:%d/%s", registry.Port, data.Identifier())) + }, + Expected: test.Expects(0, nil, nil), + }, + { + Description: "with save", + Require: nerdtest.Private, + Setup: func(data test.Data, helpers test.Helpers) { + helpers.Ensure("image", "pull", testutil.CommonImage) + helpers.Ensure("run", "-d", "--name", data.Identifier(), testutil.CommonImage) + helpers.Ensure("image", "rm", "-f", testutil.CommonImage) + helpers.Ensure("image", "pull", testutil.CommonImage) + }, + Cleanup: func(data test.Data, helpers test.Helpers) { + helpers.Anyhow("rm", "-f", data.Identifier()) + }, + Command: func(data test.Data, helpers test.Helpers) test.Command { + return helpers.Command("save", testutil.CommonImage) + }, + Expected: test.Expects(0, nil, nil), + }, + { + Description: "with convert", + Require: test.Require( + nerdtest.Private, + test.Not(test.Windows), + test.Not(nerdtest.Docker), + ), + Setup: func(data test.Data, helpers test.Helpers) { + helpers.Ensure("image", "pull", testutil.CommonImage) + helpers.Ensure("run", "-d", "--name", data.Identifier(), testutil.CommonImage) + helpers.Ensure("image", "rm", "-f", testutil.CommonImage) + helpers.Ensure("image", "pull", testutil.CommonImage) + }, + Cleanup: func(data test.Data, helpers test.Helpers) { + helpers.Anyhow("rm", "-f", data.Identifier()) + helpers.Anyhow("rmi", "-f", data.Identifier()) + }, + Command: func(data test.Data, helpers test.Helpers) test.Command { + return helpers.Command("image", "convert", "--oci", "--estargz", testutil.CommonImage, data.Identifier()) + }, + Expected: test.Expects(0, nil, nil), + }, + }, + } + + testCase.Run(t) +} diff --git a/hack/build-integration-kubernetes.sh b/hack/build-integration-kubernetes.sh index 0fa32457b21..e41f13fcf7f 100755 --- a/hack/build-integration-kubernetes.sh +++ b/hack/build-integration-kubernetes.sh @@ -23,6 +23,7 @@ readonly root GO_VERSION=1.23 KIND_VERSION=v0.24.0 +CNI_PLUGINS_VERSION=v1.5.1 [ "$(uname -m)" == "aarch64" ] && GOARCH=arm64 || GOARCH=amd64 @@ -53,6 +54,19 @@ install::kubectl(){ host::install "$temp"/kubectl } +install::cni(){ + local version="$1" + local temp + temp="$(fs::mktemp "install")" + + http::get "$temp"/cni.tgz "https://github.com/containernetworking/plugins/releases/download/$version/cni-plugins-${GOOS:-linux}-${GOARCH:-amd64}-$version.tgz" + sudo mkdir -p /opt/cni/bin + sudo tar xzf "$temp"/cni.tgz -C /opt/cni/bin + mkdir -p ~/opt/cni/bin + tar xzf "$temp"/cni.tgz -C ~/opt/cni/bin + rm "$temp"/cni.tgz +} + exec::kind(){ local args=() [ ! "$_rootful" ] || args=(sudo env PATH="$PATH" KIND_EXPERIMENTAL_PROVIDER="$KIND_EXPERIMENTAL_PROVIDER") @@ -85,6 +99,9 @@ main(){ PATH=$(pwd)/_output:"$PATH" export PATH + # Add CNI plugins + install::cni "$CNI_PLUGINS_VERSION" + # Hack to get go into kind control plane exec::nerdctl rm -f go-kind 2>/dev/null || true exec::nerdctl run -d --name go-kind golang:"$GO_VERSION" sleep Inf @@ -97,4 +114,4 @@ main(){ exec::kind create cluster --name nerdctl-test --config=./hack/kind.yaml } -main "$@" \ No newline at end of file +main "$@" diff --git a/hack/kind.yaml b/hack/kind.yaml index 1695fafdb88..c6439c02458 100644 --- a/hack/kind.yaml +++ b/hack/kind.yaml @@ -10,3 +10,5 @@ nodes: containerPath: /usr/local/go - hostPath: . containerPath: /nerdctl-source + - hostPath: /opt/cni + containerPath: /opt/cni diff --git a/pkg/testutil/nerdtest/test.go b/pkg/testutil/nerdtest/test.go index a2f7a5bd3c2..812ff08591d 100644 --- a/pkg/testutil/nerdtest/test.go +++ b/pkg/testutil/nerdtest/test.go @@ -170,6 +170,20 @@ func InspectNetwork(helpers test.Helpers, name string, args ...string) dockercom return dc[0] } +func InspectImage(helpers test.Helpers, name string) dockercompat.Image { + var dc []dockercompat.Image + cmd := helpers.Command("image", "inspect", name) + cmd.Run(&test.Expected{ + ExitCode: 0, + Output: func(stdout string, info string, t *testing.T) { + err := json.Unmarshal([]byte(stdout), &dc) + assert.NilError(t, err, "Unable to unmarshal output\n"+info) + assert.Equal(t, 1, len(dc), "Unexpectedly got multiple results\n"+info) + }, + }) + return dc[0] +} + func nerdctlSetup(testCase *test.Case, t *testing.T) test.Command { t.Helper()