From 2ed94cbd9d9090ae85fa2dc8b39cfaa46ddf8f29 Mon Sep 17 00:00:00 2001 From: Wei Zhang Date: Wed, 4 Sep 2019 19:56:45 +0800 Subject: [PATCH] Config: Remove ConfigJSONKey from annotations Fixes: #2023 We can get OCI spec config from bundle instead of annotations, so this field isn't necessary. Signed-off-by: Wei Zhang --- cli/create.go | 3 +- cli/create_test.go | 13 +- cli/delete_test.go | 31 ++-- cli/exec_test.go | 47 +++--- cli/kill_test.go | 28 +-- cli/main_test.go | 20 +-- cli/network_test.go | 6 +- cli/pause_test.go | 12 +- cli/run_test.go | 23 +-- cli/start_test.go | 16 +- containerd-shim-v2/create.go | 21 ++- containerd-shim-v2/create_test.go | 14 +- containerd-shim-v2/delete_test.go | 4 +- containerd-shim-v2/service.go | 17 +- containerd-shim-v2/utils.go | 3 +- containerd-shim-v2/utils_test.go | 3 +- pkg/katautils/create_test.go | 11 +- pkg/katautils/utils_test.go | 4 +- virtcontainers/api.go | 1 + virtcontainers/api_test.go | 71 +++++--- virtcontainers/cgroups_test.go | 2 + virtcontainers/container.go | 24 +-- virtcontainers/kata_agent.go | 23 +-- virtcontainers/kata_agent_test.go | 7 +- virtcontainers/pkg/annotations/annotations.go | 3 - virtcontainers/pkg/compatoci/utils.go | 151 +++++++++++++++++ virtcontainers/pkg/compatoci/utils_test.go | 147 ++++++++++++++++ virtcontainers/pkg/oci/utils.go | 145 +--------------- virtcontainers/pkg/oci/utils_test.go | 159 +----------------- virtcontainers/sandbox.go | 92 ++++++---- virtcontainers/sandbox_test.go | 37 +--- 31 files changed, 574 insertions(+), 564 deletions(-) create mode 100644 virtcontainers/pkg/compatoci/utils.go create mode 100644 virtcontainers/pkg/compatoci/utils_test.go diff --git a/cli/create.go b/cli/create.go index 0d3cf9952b..02cb2c5368 100644 --- a/cli/create.go +++ b/cli/create.go @@ -14,6 +14,7 @@ import ( "github.com/kata-containers/runtime/pkg/katautils" vc "github.com/kata-containers/runtime/virtcontainers" + "github.com/kata-containers/runtime/virtcontainers/pkg/compatoci" "github.com/kata-containers/runtime/virtcontainers/pkg/oci" "github.com/urfave/cli" ) @@ -113,7 +114,7 @@ func create(ctx context.Context, containerID, bundlePath, console, pidFilePath s return err } - ociSpec, err := oci.ParseConfigJSON(bundlePath) + ociSpec, err := compatoci.ParseConfigJSON(bundlePath) if err != nil { return err } diff --git a/cli/create_test.go b/cli/create_test.go index 8f6c22bb31..41741507e8 100644 --- a/cli/create_test.go +++ b/cli/create_test.go @@ -18,6 +18,7 @@ import ( ktu "github.com/kata-containers/runtime/pkg/katatestutils" "github.com/kata-containers/runtime/pkg/katautils" vc "github.com/kata-containers/runtime/virtcontainers" + "github.com/kata-containers/runtime/virtcontainers/pkg/compatoci" "github.com/kata-containers/runtime/virtcontainers/pkg/oci" "github.com/kata-containers/runtime/virtcontainers/pkg/vcmock" specs "github.com/opencontainers/runtime-spec/specs-go" @@ -322,7 +323,7 @@ func TestCreateInvalidContainerType(t *testing.T) { ociConfigFile := filepath.Join(bundlePath, "config.json") assert.True(katautils.FileExists(ociConfigFile)) - spec, err := oci.ParseConfigJSON(bundlePath) + spec, err := compatoci.ParseConfigJSON(bundlePath) assert.NoError(err) // Force an invalid container type @@ -367,7 +368,7 @@ func TestCreateContainerInvalid(t *testing.T) { ociConfigFile := filepath.Join(bundlePath, "config.json") assert.True(katautils.FileExists(ociConfigFile)) - spec, err := oci.ParseConfigJSON(bundlePath) + spec, err := compatoci.ParseConfigJSON(bundlePath) assert.NoError(err) @@ -432,7 +433,7 @@ func TestCreateProcessCgroupsPathSuccessful(t *testing.T) { ociConfigFile := filepath.Join(bundlePath, "config.json") assert.True(katautils.FileExists(ociConfigFile)) - spec, err := oci.ParseConfigJSON(bundlePath) + spec, err := compatoci.ParseConfigJSON(bundlePath) assert.NoError(err) // Force sandbox-type container @@ -535,7 +536,7 @@ func TestCreateCreateCgroupsFilesFail(t *testing.T) { ociConfigFile := filepath.Join(bundlePath, "config.json") assert.True(katautils.FileExists(ociConfigFile)) - spec, err := oci.ParseConfigJSON(bundlePath) + spec, err := compatoci.ParseConfigJSON(bundlePath) assert.NoError(err) // Force sandbox-type container @@ -622,7 +623,7 @@ func TestCreateCreateCreatePidFileFail(t *testing.T) { ociConfigFile := filepath.Join(bundlePath, "config.json") assert.True(katautils.FileExists(ociConfigFile)) - spec, err := oci.ParseConfigJSON(bundlePath) + spec, err := compatoci.ParseConfigJSON(bundlePath) assert.NoError(err) // Force sandbox-type container @@ -697,7 +698,7 @@ func TestCreate(t *testing.T) { ociConfigFile := filepath.Join(bundlePath, "config.json") assert.True(katautils.FileExists(ociConfigFile)) - spec, err := oci.ParseConfigJSON(bundlePath) + spec, err := compatoci.ParseConfigJSON(bundlePath) assert.NoError(err) // Force sandbox-type container diff --git a/cli/delete_test.go b/cli/delete_test.go index a04d1ceb82..a2455deed4 100644 --- a/cli/delete_test.go +++ b/cli/delete_test.go @@ -13,13 +13,15 @@ import ( "path/filepath" "testing" + "github.com/stretchr/testify/assert" + "github.com/urfave/cli" + ktu "github.com/kata-containers/runtime/pkg/katatestutils" vc "github.com/kata-containers/runtime/virtcontainers" vcAnnotations "github.com/kata-containers/runtime/virtcontainers/pkg/annotations" + "github.com/kata-containers/runtime/virtcontainers/pkg/compatoci" "github.com/kata-containers/runtime/virtcontainers/pkg/vcmock" "github.com/kata-containers/runtime/virtcontainers/types" - "github.com/stretchr/testify/assert" - "github.com/urfave/cli" ) func testRemoveCgroupsPathSuccessful(t *testing.T, cgroupsPathList []string) { @@ -153,7 +155,8 @@ func TestDeleteSandbox(t *testing.T) { rootPath, bundlePath := testConfigSetup(t) defer os.RemoveAll(rootPath) - configJSON, err := readOCIConfigJSON(bundlePath) + + ociSpec, err := compatoci.ParseConfigJSON(bundlePath) assert.NoError(err) path, err := createTempContainerIDMapping(sandbox.ID(), sandbox.ID()) @@ -165,11 +168,11 @@ func TestDeleteSandbox(t *testing.T) { ID: sandbox.ID(), Annotations: map[string]string{ vcAnnotations.ContainerTypeKey: string(vc.PodSandbox), - vcAnnotations.ConfigJSONKey: configJSON, }, State: types.ContainerState{ State: "ready", }, + Spec: &ociSpec, }, nil } @@ -231,7 +234,7 @@ func TestDeleteInvalidContainerType(t *testing.T) { rootPath, bundlePath := testConfigSetup(t) defer os.RemoveAll(rootPath) - configJSON, err := readOCIConfigJSON(bundlePath) + ociSpec, err := compatoci.ParseConfigJSON(bundlePath) assert.NoError(err) path, err := createTempContainerIDMapping(sandbox.ID(), sandbox.ID()) @@ -243,11 +246,11 @@ func TestDeleteInvalidContainerType(t *testing.T) { ID: sandbox.ID(), Annotations: map[string]string{ vcAnnotations.ContainerTypeKey: "InvalidType", - vcAnnotations.ConfigJSONKey: configJSON, }, State: types.ContainerState{ State: "created", }, + Spec: &ociSpec, }, nil } @@ -270,7 +273,7 @@ func TestDeleteSandboxRunning(t *testing.T) { rootPath, bundlePath := testConfigSetup(t) defer os.RemoveAll(rootPath) - configJSON, err := readOCIConfigJSON(bundlePath) + ociSpec, err := compatoci.ParseConfigJSON(bundlePath) assert.NoError(err) path, err := createTempContainerIDMapping(sandbox.ID(), sandbox.ID()) @@ -282,11 +285,11 @@ func TestDeleteSandboxRunning(t *testing.T) { ID: sandbox.ID(), Annotations: map[string]string{ vcAnnotations.ContainerTypeKey: string(vc.PodSandbox), - vcAnnotations.ConfigJSONKey: configJSON, }, State: types.ContainerState{ State: "running", }, + Spec: &ociSpec, }, nil } @@ -350,7 +353,7 @@ func TestDeleteRunningContainer(t *testing.T) { rootPath, bundlePath := testConfigSetup(t) defer os.RemoveAll(rootPath) - configJSON, err := readOCIConfigJSON(bundlePath) + ociSpec, err := compatoci.ParseConfigJSON(bundlePath) assert.NoError(err) path, err := createTempContainerIDMapping(sandbox.MockContainers[0].ID(), sandbox.MockContainers[0].ID()) @@ -362,11 +365,11 @@ func TestDeleteRunningContainer(t *testing.T) { ID: sandbox.MockContainers[0].ID(), Annotations: map[string]string{ vcAnnotations.ContainerTypeKey: string(vc.PodContainer), - vcAnnotations.ConfigJSONKey: configJSON, }, State: types.ContainerState{ State: "running", }, + Spec: &ociSpec, }, nil } @@ -433,7 +436,7 @@ func TestDeleteContainer(t *testing.T) { rootPath, bundlePath := testConfigSetup(t) defer os.RemoveAll(rootPath) - configJSON, err := readOCIConfigJSON(bundlePath) + ociSpec, err := compatoci.ParseConfigJSON(bundlePath) assert.NoError(err) path, err := createTempContainerIDMapping(sandbox.MockContainers[0].ID(), sandbox.MockContainers[0].ID()) @@ -445,11 +448,11 @@ func TestDeleteContainer(t *testing.T) { ID: sandbox.MockContainers[0].ID(), Annotations: map[string]string{ vcAnnotations.ContainerTypeKey: string(vc.PodContainer), - vcAnnotations.ConfigJSONKey: configJSON, }, State: types.ContainerState{ State: "ready", }, + Spec: &ociSpec, }, nil } @@ -533,7 +536,7 @@ func TestDeleteCLIFunctionSuccess(t *testing.T) { rootPath, bundlePath := testConfigSetup(t) defer os.RemoveAll(rootPath) - configJSON, err := readOCIConfigJSON(bundlePath) + ociSpec, err := compatoci.ParseConfigJSON(bundlePath) assert.NoError(err) path, err := createTempContainerIDMapping(sandbox.ID(), sandbox.ID()) @@ -545,11 +548,11 @@ func TestDeleteCLIFunctionSuccess(t *testing.T) { ID: sandbox.ID(), Annotations: map[string]string{ vcAnnotations.ContainerTypeKey: string(vc.PodSandbox), - vcAnnotations.ConfigJSONKey: configJSON, }, State: types.ContainerState{ State: "ready", }, + Spec: &ociSpec, }, nil } diff --git a/cli/exec_test.go b/cli/exec_test.go index bb2ea35543..37da2faa82 100644 --- a/cli/exec_test.go +++ b/cli/exec_test.go @@ -20,6 +20,7 @@ import ( vc "github.com/kata-containers/runtime/virtcontainers" vcAnnotations "github.com/kata-containers/runtime/virtcontainers/pkg/annotations" + "github.com/kata-containers/runtime/virtcontainers/pkg/compatoci" "github.com/kata-containers/runtime/virtcontainers/pkg/vcmock" "github.com/kata-containers/runtime/virtcontainers/types" ) @@ -79,7 +80,7 @@ func TestExecuteErrors(t *testing.T) { } testingImpl.StatusContainerFunc = func(ctx context.Context, sandboxID, containerID string) (vc.ContainerStatus, error) { - return newSingleContainerStatus(testContainerID, types.ContainerState{}, annotations), nil + return newSingleContainerStatus(testContainerID, types.ContainerState{}, annotations, &specs.Spec{Process: &specs.Process{}}), nil } defer func() { @@ -93,17 +94,16 @@ func TestExecuteErrors(t *testing.T) { // Container state undefined rootPath, bundlePath := testConfigSetup(t) defer os.RemoveAll(rootPath) - configJSON, err := readOCIConfigJSON(bundlePath) + ociSpec, err := compatoci.ParseConfigJSON(bundlePath) assert.NoError(err) annotations = map[string]string{ vcAnnotations.ContainerTypeKey: string(vc.PodSandbox), - vcAnnotations.ConfigJSONKey: configJSON, } containerState := types.ContainerState{} testingImpl.StatusContainerFunc = func(ctx context.Context, sandboxID, containerID string) (vc.ContainerStatus, error) { - return newSingleContainerStatus(testContainerID, containerState, annotations), nil + return newSingleContainerStatus(testContainerID, containerState, annotations, &ociSpec), nil } err = execute(context.Background(), ctx) @@ -115,7 +115,7 @@ func TestExecuteErrors(t *testing.T) { State: types.StatePaused, } testingImpl.StatusContainerFunc = func(ctx context.Context, sandboxID, containerID string) (vc.ContainerStatus, error) { - return newSingleContainerStatus(testContainerID, containerState, annotations), nil + return newSingleContainerStatus(testContainerID, containerState, annotations, &ociSpec), nil } err = execute(context.Background(), ctx) @@ -127,7 +127,7 @@ func TestExecuteErrors(t *testing.T) { State: types.StateStopped, } testingImpl.StatusContainerFunc = func(ctx context.Context, sandboxID, containerID string) (vc.ContainerStatus, error) { - return newSingleContainerStatus(testContainerID, containerState, annotations), nil + return newSingleContainerStatus(testContainerID, containerState, annotations, &ociSpec), nil } err = execute(context.Background(), ctx) @@ -152,12 +152,11 @@ func TestExecuteErrorReadingProcessJson(t *testing.T) { rootPath, bundlePath := testConfigSetup(t) defer os.RemoveAll(rootPath) - configJSON, err := readOCIConfigJSON(bundlePath) + ociSpec, err := compatoci.ParseConfigJSON(bundlePath) assert.NoError(err) annotations := map[string]string{ vcAnnotations.ContainerTypeKey: string(vc.PodSandbox), - vcAnnotations.ConfigJSONKey: configJSON, } state := types.ContainerState{ @@ -169,7 +168,7 @@ func TestExecuteErrorReadingProcessJson(t *testing.T) { defer os.RemoveAll(path) testingImpl.StatusContainerFunc = func(ctx context.Context, sandboxID, containerID string) (vc.ContainerStatus, error) { - return newSingleContainerStatus(testContainerID, state, annotations), nil + return newSingleContainerStatus(testContainerID, state, annotations, &ociSpec), nil } defer func() { @@ -201,12 +200,11 @@ func TestExecuteErrorOpeningConsole(t *testing.T) { rootPath, bundlePath := testConfigSetup(t) defer os.RemoveAll(rootPath) - configJSON, err := readOCIConfigJSON(bundlePath) + ociSpec, err := compatoci.ParseConfigJSON(bundlePath) assert.NoError(err) annotations := map[string]string{ vcAnnotations.ContainerTypeKey: string(vc.PodSandbox), - vcAnnotations.ConfigJSONKey: configJSON, } state := types.ContainerState{ @@ -218,7 +216,7 @@ func TestExecuteErrorOpeningConsole(t *testing.T) { defer os.RemoveAll(path) testingImpl.StatusContainerFunc = func(ctx context.Context, sandboxID, containerID string) (vc.ContainerStatus, error) { - return newSingleContainerStatus(testContainerID, state, annotations), nil + return newSingleContainerStatus(testContainerID, state, annotations, &ociSpec), nil } defer func() { @@ -268,12 +266,11 @@ func TestExecuteWithFlags(t *testing.T) { rootPath, bundlePath := testConfigSetup(t) defer os.RemoveAll(rootPath) - configJSON, err := readOCIConfigJSON(bundlePath) + ociSpec, err := compatoci.ParseConfigJSON(bundlePath) assert.NoError(err) annotations := map[string]string{ vcAnnotations.ContainerTypeKey: string(vc.PodSandbox), - vcAnnotations.ConfigJSONKey: configJSON, } state := types.ContainerState{ @@ -285,7 +282,7 @@ func TestExecuteWithFlags(t *testing.T) { defer os.RemoveAll(path) testingImpl.StatusContainerFunc = func(ctx context.Context, sandboxID, containerID string) (vc.ContainerStatus, error) { - return newSingleContainerStatus(testContainerID, state, annotations), nil + return newSingleContainerStatus(testContainerID, state, annotations, &ociSpec), nil } defer func() { @@ -358,12 +355,11 @@ func TestExecuteWithFlagsDetached(t *testing.T) { rootPath, bundlePath := testConfigSetup(t) defer os.RemoveAll(rootPath) - configJSON, err := readOCIConfigJSON(bundlePath) + ociSpec, err := compatoci.ParseConfigJSON(bundlePath) assert.NoError(err) annotations := map[string]string{ vcAnnotations.ContainerTypeKey: string(vc.PodSandbox), - vcAnnotations.ConfigJSONKey: configJSON, } state := types.ContainerState{ @@ -375,7 +371,7 @@ func TestExecuteWithFlagsDetached(t *testing.T) { defer os.RemoveAll(path) testingImpl.StatusContainerFunc = func(ctx context.Context, sandboxID, containerID string) (vc.ContainerStatus, error) { - return newSingleContainerStatus(testContainerID, state, annotations), nil + return newSingleContainerStatus(testContainerID, state, annotations, &ociSpec), nil } defer func() { @@ -437,12 +433,11 @@ func TestExecuteWithInvalidProcessJson(t *testing.T) { rootPath, bundlePath := testConfigSetup(t) defer os.RemoveAll(rootPath) - configJSON, err := readOCIConfigJSON(bundlePath) + ociSpec, err := compatoci.ParseConfigJSON(bundlePath) assert.NoError(err) annotations := map[string]string{ vcAnnotations.ContainerTypeKey: string(vc.PodSandbox), - vcAnnotations.ConfigJSONKey: configJSON, } state := types.ContainerState{ @@ -454,7 +449,7 @@ func TestExecuteWithInvalidProcessJson(t *testing.T) { defer os.RemoveAll(path) testingImpl.StatusContainerFunc = func(ctx context.Context, sandboxID, containerID string) (vc.ContainerStatus, error) { - return newSingleContainerStatus(testContainerID, state, annotations), nil + return newSingleContainerStatus(testContainerID, state, annotations, &ociSpec), nil } defer func() { @@ -489,12 +484,11 @@ func TestExecuteWithValidProcessJson(t *testing.T) { rootPath, bundlePath := testConfigSetup(t) defer os.RemoveAll(rootPath) - configJSON, err := readOCIConfigJSON(bundlePath) + ociSpec, err := compatoci.ParseConfigJSON(bundlePath) assert.NoError(err) annotations := map[string]string{ vcAnnotations.ContainerTypeKey: string(vc.PodContainer), - vcAnnotations.ConfigJSONKey: configJSON, } state := types.ContainerState{ @@ -506,7 +500,7 @@ func TestExecuteWithValidProcessJson(t *testing.T) { defer os.RemoveAll(path) testingImpl.StatusContainerFunc = func(ctx context.Context, sandboxID, containerID string) (vc.ContainerStatus, error) { - return newSingleContainerStatus(testContainerID, state, annotations), nil + return newSingleContainerStatus(testContainerID, state, annotations, &ociSpec), nil } defer func() { @@ -590,12 +584,11 @@ func TestExecuteWithEmptyEnvironmentValue(t *testing.T) { rootPath, bundlePath := testConfigSetup(t) defer os.RemoveAll(rootPath) - configJSON, err := readOCIConfigJSON(bundlePath) + ociSpec, err := compatoci.ParseConfigJSON(bundlePath) assert.NoError(err) annotations := map[string]string{ vcAnnotations.ContainerTypeKey: string(vc.PodContainer), - vcAnnotations.ConfigJSONKey: configJSON, } state := types.ContainerState{ @@ -607,7 +600,7 @@ func TestExecuteWithEmptyEnvironmentValue(t *testing.T) { defer os.RemoveAll(path) testingImpl.StatusContainerFunc = func(ctx context.Context, sandboxID, containerID string) (vc.ContainerStatus, error) { - return newSingleContainerStatus(testContainerID, state, annotations), nil + return newSingleContainerStatus(testContainerID, state, annotations, &ociSpec), nil } defer func() { diff --git a/cli/kill_test.go b/cli/kill_test.go index a80bc2673d..7052b923b0 100644 --- a/cli/kill_test.go +++ b/cli/kill_test.go @@ -13,11 +13,13 @@ import ( "syscall" "testing" + "github.com/opencontainers/runtime-spec/specs-go" + "github.com/stretchr/testify/assert" + vc "github.com/kata-containers/runtime/virtcontainers" vcAnnotations "github.com/kata-containers/runtime/virtcontainers/pkg/annotations" "github.com/kata-containers/runtime/virtcontainers/pkg/vcmock" "github.com/kata-containers/runtime/virtcontainers/types" - "github.com/stretchr/testify/assert" ) var ( @@ -81,7 +83,7 @@ func testKillCLIFunctionTerminationSignalSuccessful(t *testing.T, sig string) { defer os.RemoveAll(path) testingImpl.StatusContainerFunc = func(ctx context.Context, sandboxID, containerID string) (vc.ContainerStatus, error) { - return newSingleContainerStatus(testContainerID, state, annotations), nil + return newSingleContainerStatus(testContainerID, state, annotations, &specs.Spec{}), nil } defer func() { @@ -100,7 +102,7 @@ func testKillCLIFunctionTerminationSignalSuccessful(t *testing.T, sig string) { } testingImpl.StatusContainerFunc = func(ctx context.Context, sandboxID, containerID string) (vc.ContainerStatus, error) { - return newSingleContainerStatus(testContainerID, state, annotations), nil + return newSingleContainerStatus(testContainerID, state, annotations, &specs.Spec{}), nil } testingImpl.StopContainerFunc = nil @@ -134,7 +136,7 @@ func TestKillCLIFunctionNotTerminationSignalSuccessful(t *testing.T) { defer os.RemoveAll(path) testingImpl.StatusContainerFunc = func(ctx context.Context, sandboxID, containerID string) (vc.ContainerStatus, error) { - return newSingleContainerStatus(testContainerID, state, map[string]string{}), nil + return newSingleContainerStatus(testContainerID, state, map[string]string{}, &specs.Spec{}), nil } defer func() { @@ -167,7 +169,7 @@ func TestKillCLIFunctionNoSignalSuccessful(t *testing.T) { defer os.RemoveAll(path) testingImpl.StatusContainerFunc = func(ctx context.Context, sandboxID, containerID string) (vc.ContainerStatus, error) { - return newSingleContainerStatus(testContainerID, state, annotations), nil + return newSingleContainerStatus(testContainerID, state, annotations, &specs.Spec{}), nil } defer func() { @@ -186,7 +188,7 @@ func TestKillCLIFunctionNoSignalSuccessful(t *testing.T) { } testingImpl.StatusContainerFunc = func(ctx context.Context, sandboxID, containerID string) (vc.ContainerStatus, error) { - return newSingleContainerStatus(testContainerID, state, annotations), nil + return newSingleContainerStatus(testContainerID, state, annotations, &specs.Spec{}), nil } testingImpl.StopContainerFunc = nil @@ -223,7 +225,7 @@ func TestKillCLIFunctionEnableAllSuccessful(t *testing.T) { defer os.RemoveAll(path) testingImpl.StatusContainerFunc = func(ctx context.Context, sandboxID, containerID string) (vc.ContainerStatus, error) { - return newSingleContainerStatus(testContainerID, state, annotations), nil + return newSingleContainerStatus(testContainerID, state, annotations, &specs.Spec{}), nil } defer func() { @@ -243,7 +245,7 @@ func TestKillCLIFunctionEnableAllSuccessful(t *testing.T) { } testingImpl.StatusContainerFunc = func(ctx context.Context, sandboxID, containerID string) (vc.ContainerStatus, error) { - return newSingleContainerStatus(testContainerID, state, annotations), nil + return newSingleContainerStatus(testContainerID, state, annotations, &specs.Spec{}), nil } testingImpl.StopContainerFunc = nil @@ -300,7 +302,7 @@ func TestKillCLIFunctionInvalidSignalFailure(t *testing.T) { defer os.RemoveAll(path) testingImpl.StatusContainerFunc = func(ctx context.Context, sandboxID, containerID string) (vc.ContainerStatus, error) { - return newSingleContainerStatus(testContainerID, state, map[string]string{}), nil + return newSingleContainerStatus(testContainerID, state, map[string]string{}, &specs.Spec{}), nil } defer func() { @@ -330,7 +332,7 @@ func TestKillCLIFunctionStatePausedSuccessful(t *testing.T) { testingImpl.StatusContainerFunc = func(ctx context.Context, sandboxID, containerID string) (vc.ContainerStatus, error) { return newSingleContainerStatus(testContainerID, state, - map[string]string{string(vcAnnotations.ContainerTypeKey): string(vc.PodContainer)}), nil + map[string]string{string(vcAnnotations.ContainerTypeKey): string(vc.PodContainer)}, &specs.Spec{}), nil } defer func() { @@ -359,7 +361,7 @@ func TestKillCLIFunctionInvalidStateStoppedFailure(t *testing.T) { defer os.RemoveAll(path) testingImpl.StatusContainerFunc = func(ctx context.Context, sandboxID, containerID string) (vc.ContainerStatus, error) { - return newSingleContainerStatus(testContainerID, state, map[string]string{}), nil + return newSingleContainerStatus(testContainerID, state, map[string]string{}, &specs.Spec{}), nil } defer func() { @@ -385,7 +387,7 @@ func TestKillCLIFunctionKillContainerFailure(t *testing.T) { defer os.RemoveAll(path) testingImpl.StatusContainerFunc = func(ctx context.Context, sandboxID, containerID string) (vc.ContainerStatus, error) { - return newSingleContainerStatus(testContainerID, state, map[string]string{}), nil + return newSingleContainerStatus(testContainerID, state, map[string]string{}, &specs.Spec{}), nil } defer func() { @@ -412,7 +414,7 @@ func TestKillCLIFunctionInvalidStateStoppedAllSuccess(t *testing.T) { defer os.RemoveAll(path) testingImpl.StatusContainerFunc = func(ctx context.Context, sandboxID, containerID string) (vc.ContainerStatus, error) { - return newSingleContainerStatus(testContainerID, state, map[string]string{}), nil + return newSingleContainerStatus(testContainerID, state, map[string]string{}, &specs.Spec{}), nil } defer func() { diff --git a/cli/main_test.go b/cli/main_test.go index 705722c24b..bcb613a7be 100644 --- a/cli/main_test.go +++ b/cli/main_test.go @@ -25,6 +25,7 @@ import ( ktu "github.com/kata-containers/runtime/pkg/katatestutils" "github.com/kata-containers/runtime/pkg/katautils" vc "github.com/kata-containers/runtime/virtcontainers" + "github.com/kata-containers/runtime/virtcontainers/pkg/compatoci" "github.com/kata-containers/runtime/virtcontainers/pkg/oci" "github.com/kata-containers/runtime/virtcontainers/pkg/vcmock" "github.com/kata-containers/runtime/virtcontainers/types" @@ -150,20 +151,6 @@ func runUnitTests(m *testing.M) { os.Exit(ret) } -// Read fail that should contain a specs.Spec and -// return its JSON representation on success -func readOCIConfigJSON(bundlePath string) (string, error) { - ociSpec, err := oci.ParseConfigJSON(bundlePath) - if err != nil { - return "", nil - } - ociSpecJSON, err := json.Marshal(ociSpec) - if err != nil { - return "", err - } - return string(ociSpecJSON), err -} - // TestMain is the common main function used by ALL the test functions // for this package. func TestMain(m *testing.M) { @@ -347,7 +334,7 @@ func realMakeOCIBundle(bundleDir string) error { // Note the unusual parameter (a directory, not the config // file to parse!) - spec, err := oci.ParseConfigJSON(bundleDir) + spec, err := compatoci.ParseConfigJSON(bundleDir) if err != nil { return err } @@ -412,11 +399,12 @@ func writeOCIConfigFile(spec specs.Spec, configPath string) error { return ioutil.WriteFile(configPath, bytes, testFileMode) } -func newSingleContainerStatus(containerID string, containerState types.ContainerState, annotations map[string]string) vc.ContainerStatus { +func newSingleContainerStatus(containerID string, containerState types.ContainerState, annotations map[string]string, spec *specs.Spec) vc.ContainerStatus { return vc.ContainerStatus{ ID: containerID, State: containerState, Annotations: annotations, + Spec: spec, } } diff --git a/cli/network_test.go b/cli/network_test.go index f6708eb07d..4e3d943dc1 100644 --- a/cli/network_test.go +++ b/cli/network_test.go @@ -12,10 +12,12 @@ import ( "os" "testing" + specs "github.com/opencontainers/runtime-spec/specs-go" + "github.com/stretchr/testify/assert" + vc "github.com/kata-containers/runtime/virtcontainers" vcTypes "github.com/kata-containers/runtime/virtcontainers/pkg/types" "github.com/kata-containers/runtime/virtcontainers/types" - "github.com/stretchr/testify/assert" ) var ( @@ -54,7 +56,7 @@ func TestNetworkCliFunction(t *testing.T) { defer os.RemoveAll(path) testingImpl.StatusContainerFunc = func(ctx context.Context, sandboxID, containerID string) (vc.ContainerStatus, error) { - return newSingleContainerStatus(testContainerID, state, map[string]string{}), nil + return newSingleContainerStatus(testContainerID, state, map[string]string{}, &specs.Spec{}), nil } defer func() { diff --git a/cli/pause_test.go b/cli/pause_test.go index 07d3c60b40..a3660fa6a6 100644 --- a/cli/pause_test.go +++ b/cli/pause_test.go @@ -12,9 +12,11 @@ import ( "os" "testing" + specs "github.com/opencontainers/runtime-spec/specs-go" + "github.com/stretchr/testify/assert" + vc "github.com/kata-containers/runtime/virtcontainers" "github.com/kata-containers/runtime/virtcontainers/types" - "github.com/stretchr/testify/assert" ) var ( @@ -41,7 +43,7 @@ func TestPauseCLIFunctionSuccessful(t *testing.T) { defer os.RemoveAll(path) testingImpl.StatusContainerFunc = func(ctx context.Context, sandboxID, containerID string) (vc.ContainerStatus, error) { - return newSingleContainerStatus(testContainerID, state, map[string]string{}), nil + return newSingleContainerStatus(testContainerID, state, map[string]string{}, &specs.Spec{}), nil } defer func() { @@ -87,7 +89,7 @@ func TestPauseCLIFunctionPauseContainerFailure(t *testing.T) { defer os.RemoveAll(path) testingImpl.StatusContainerFunc = func(ctx context.Context, sandboxID, containerID string) (vc.ContainerStatus, error) { - return newSingleContainerStatus(testContainerID, state, map[string]string{}), nil + return newSingleContainerStatus(testContainerID, state, map[string]string{}, &specs.Spec{}), nil } defer func() { @@ -114,7 +116,7 @@ func TestResumeCLIFunctionSuccessful(t *testing.T) { defer os.RemoveAll(path) testingImpl.StatusContainerFunc = func(ctx context.Context, sandboxID, containerID string) (vc.ContainerStatus, error) { - return newSingleContainerStatus(testContainerID, state, map[string]string{}), nil + return newSingleContainerStatus(testContainerID, state, map[string]string{}, &specs.Spec{}), nil } defer func() { @@ -159,7 +161,7 @@ func TestResumeCLIFunctionPauseContainerFailure(t *testing.T) { defer os.RemoveAll(path) testingImpl.StatusContainerFunc = func(ctx context.Context, sandboxID, containerID string) (vc.ContainerStatus, error) { - return newSingleContainerStatus(testContainerID, state, map[string]string{}), nil + return newSingleContainerStatus(testContainerID, state, map[string]string{}, &specs.Spec{}), nil } defer func() { diff --git a/cli/run_test.go b/cli/run_test.go index ef683fb2fd..a2b908c1e8 100644 --- a/cli/run_test.go +++ b/cli/run_test.go @@ -16,13 +16,16 @@ import ( "regexp" "testing" + "github.com/opencontainers/runtime-spec/specs-go" + "github.com/stretchr/testify/assert" + "github.com/urfave/cli" + ktu "github.com/kata-containers/runtime/pkg/katatestutils" vc "github.com/kata-containers/runtime/virtcontainers" vcAnnotations "github.com/kata-containers/runtime/virtcontainers/pkg/annotations" + "github.com/kata-containers/runtime/virtcontainers/pkg/compatoci" "github.com/kata-containers/runtime/virtcontainers/pkg/oci" "github.com/kata-containers/runtime/virtcontainers/pkg/vcmock" - "github.com/stretchr/testify/assert" - "github.com/urfave/cli" ) func TestRunCliAction(t *testing.T) { @@ -155,7 +158,7 @@ type runContainerData struct { pidFilePath string consolePath string bundlePath string - configJSON string + spec *specs.Spec sandbox *vcmock.Sandbox runtimeConfig oci.RuntimeConfig process *os.Process @@ -205,15 +208,15 @@ func testRunContainerSetup(t *testing.T) runContainerData { runtimeConfig, err := newTestRuntimeConfig(tmpdir, consolePath, true) assert.NoError(err) - configJSON, err := readOCIConfigJSON(bundlePath) + ociSpec, err := compatoci.ParseConfigJSON(bundlePath) assert.NoError(err) return runContainerData{ pidFilePath: pidFilePath, consolePath: consolePath, bundlePath: bundlePath, - configJSON: configJSON, sandbox: sandbox, + spec: &ociSpec, runtimeConfig: runtimeConfig, process: cmd.Process, tmpDir: tmpdir, @@ -259,8 +262,8 @@ func TestRunContainerSuccessful(t *testing.T) { ID: d.sandbox.ID(), Annotations: map[string]string{ vcAnnotations.ContainerTypeKey: string(vc.PodContainer), - vcAnnotations.ConfigJSONKey: d.configJSON, }, + Spec: d.spec, }, nil } @@ -368,8 +371,8 @@ func TestRunContainerDetachSuccessful(t *testing.T) { ID: d.sandbox.ID(), Annotations: map[string]string{ vcAnnotations.ContainerTypeKey: string(vc.PodContainer), - vcAnnotations.ConfigJSONKey: d.configJSON, }, + Spec: d.spec, }, nil } @@ -439,8 +442,8 @@ func TestRunContainerDeleteFail(t *testing.T) { ID: d.sandbox.ID(), Annotations: map[string]string{ vcAnnotations.ContainerTypeKey: string(vc.PodContainer), - vcAnnotations.ConfigJSONKey: d.configJSON, }, + Spec: d.spec, }, nil } @@ -513,8 +516,8 @@ func TestRunContainerWaitFail(t *testing.T) { ID: d.sandbox.ID(), Annotations: map[string]string{ vcAnnotations.ContainerTypeKey: string(vc.PodContainer), - vcAnnotations.ConfigJSONKey: d.configJSON, }, + Spec: d.spec, }, nil } @@ -595,8 +598,8 @@ func TestRunContainerStartFail(t *testing.T) { ID: d.sandbox.ID(), Annotations: map[string]string{ vcAnnotations.ContainerTypeKey: string(vc.PodContainer), - vcAnnotations.ConfigJSONKey: d.configJSON, }, + Spec: d.spec, }, nil } diff --git a/cli/start_test.go b/cli/start_test.go index 28005a2fb1..bcf4793988 100644 --- a/cli/start_test.go +++ b/cli/start_test.go @@ -7,7 +7,6 @@ package main import ( "context" - "encoding/json" "flag" "io/ioutil" "os" @@ -62,16 +61,13 @@ func TestStartSandbox(t *testing.T) { assert.NoError(err) defer os.RemoveAll(path) - ociSpecJSON, err := json.Marshal(specs.Spec{}) - assert.NoError(err) - testingImpl.StatusContainerFunc = func(ctx context.Context, sandboxID, containerID string) (vc.ContainerStatus, error) { return vc.ContainerStatus{ ID: sandbox.ID(), Annotations: map[string]string{ vcAnnotations.ContainerTypeKey: string(vc.PodSandbox), - vcAnnotations.ConfigJSONKey: string(ociSpecJSON), }, + Spec: &specs.Spec{}, }, nil } @@ -140,16 +136,13 @@ func TestStartContainerSucessFailure(t *testing.T) { assert.NoError(err) defer os.RemoveAll(path) - ociSpecJSON, err := json.Marshal(specs.Spec{}) - assert.NoError(err) - testingImpl.StatusContainerFunc = func(ctx context.Context, sandboxID, containerID string) (vc.ContainerStatus, error) { return vc.ContainerStatus{ ID: testContainerID, Annotations: map[string]string{ vcAnnotations.ContainerTypeKey: string(vc.PodContainer), - vcAnnotations.ConfigJSONKey: string(ociSpecJSON), }, + Spec: &specs.Spec{}, }, nil } @@ -218,16 +211,13 @@ func TestStartCLIFunctionSuccess(t *testing.T) { assert.NoError(err) defer os.RemoveAll(path) - ociSpecJSON, err := json.Marshal(specs.Spec{}) - assert.NoError(err) - testingImpl.StatusContainerFunc = func(ctx context.Context, sandboxID, containerID string) (vc.ContainerStatus, error) { return vc.ContainerStatus{ ID: testContainerID, Annotations: map[string]string{ vcAnnotations.ContainerTypeKey: string(vc.PodContainer), - vcAnnotations.ConfigJSONKey: string(ociSpecJSON), }, + Spec: &specs.Spec{}, }, nil } diff --git a/containerd-shim-v2/create.go b/containerd-shim-v2/create.go index 04b0cd50ca..fdd7b59280 100644 --- a/containerd-shim-v2/create.go +++ b/containerd-shim-v2/create.go @@ -13,22 +13,21 @@ import ( "os" "path/filepath" - "github.com/containerd/typeurl" - vc "github.com/kata-containers/runtime/virtcontainers" - "github.com/kata-containers/runtime/virtcontainers/pkg/oci" - "github.com/pkg/errors" - - taskAPI "github.com/containerd/containerd/runtime/v2/task" - - "github.com/kata-containers/runtime/pkg/katautils" - "github.com/opencontainers/runtime-spec/specs-go" - containerd_types "github.com/containerd/containerd/api/types" "github.com/containerd/containerd/mount" + taskAPI "github.com/containerd/containerd/runtime/v2/task" + "github.com/containerd/typeurl" + "github.com/opencontainers/runtime-spec/specs-go" + "github.com/pkg/errors" "github.com/sirupsen/logrus" // only register the proto type _ "github.com/containerd/containerd/runtime/linux/runctypes" crioption "github.com/containerd/cri-containerd/pkg/api/runtimeoptions/v1" + + "github.com/kata-containers/runtime/pkg/katautils" + vc "github.com/kata-containers/runtime/virtcontainers" + "github.com/kata-containers/runtime/virtcontainers/pkg/compatoci" + "github.com/kata-containers/runtime/virtcontainers/pkg/oci" ) func create(ctx context.Context, s *service, r *taskAPI.CreateTaskRequest) (*container, error) { @@ -132,7 +131,7 @@ func loadSpec(r *taskAPI.CreateTaskRequest) (*specs.Spec, string, error) { return nil, "", err } - ociSpec, err := oci.ParseConfigJSON(bundlePath) + ociSpec, err := compatoci.ParseConfigJSON(bundlePath) if err != nil { return nil, "", err } diff --git a/containerd-shim-v2/create_test.go b/containerd-shim-v2/create_test.go index 88b0b948fa..27efb906f8 100644 --- a/containerd-shim-v2/create_test.go +++ b/containerd-shim-v2/create_test.go @@ -21,7 +21,7 @@ import ( ktu "github.com/kata-containers/runtime/pkg/katatestutils" "github.com/kata-containers/runtime/pkg/katautils" vc "github.com/kata-containers/runtime/virtcontainers" - "github.com/kata-containers/runtime/virtcontainers/pkg/oci" + "github.com/kata-containers/runtime/virtcontainers/pkg/compatoci" "github.com/kata-containers/runtime/virtcontainers/pkg/vcmock" ) @@ -62,7 +62,7 @@ func TestCreateSandboxSuccess(t *testing.T) { ociConfigFile := filepath.Join(bundlePath, "config.json") assert.True(katautils.FileExists(ociConfigFile)) - spec, err := oci.ParseConfigJSON(bundlePath) + spec, err := compatoci.ParseConfigJSON(bundlePath) assert.NoError(err) // Force sandbox-type container @@ -120,7 +120,7 @@ func TestCreateSandboxFail(t *testing.T) { ociConfigFile := filepath.Join(bundlePath, "config.json") assert.True(katautils.FileExists(ociConfigFile)) - spec, err := oci.ParseConfigJSON(bundlePath) + spec, err := compatoci.ParseConfigJSON(bundlePath) assert.NoError(err) err = writeOCIConfigFile(spec, ociConfigFile) @@ -167,7 +167,7 @@ func TestCreateSandboxConfigFail(t *testing.T) { ociConfigFile := filepath.Join(bundlePath, "config.json") assert.True(katautils.FileExists(ociConfigFile)) - spec, err := oci.ParseConfigJSON(bundlePath) + spec, err := compatoci.ParseConfigJSON(bundlePath) assert.NoError(err) quota := int64(0) @@ -231,7 +231,7 @@ func TestCreateContainerSuccess(t *testing.T) { ociConfigFile := filepath.Join(bundlePath, "config.json") assert.True(katautils.FileExists(ociConfigFile)) - spec, err := oci.ParseConfigJSON(bundlePath) + spec, err := compatoci.ParseConfigJSON(bundlePath) assert.NoError(err) // set expected container type and sandboxID @@ -280,7 +280,7 @@ func TestCreateContainerFail(t *testing.T) { ociConfigFile := filepath.Join(bundlePath, "config.json") assert.True(katautils.FileExists(ociConfigFile)) - spec, err := oci.ParseConfigJSON(bundlePath) + spec, err := compatoci.ParseConfigJSON(bundlePath) assert.NoError(err) spec.Annotations = make(map[string]string) @@ -340,7 +340,7 @@ func TestCreateContainerConfigFail(t *testing.T) { ociConfigFile := filepath.Join(bundlePath, "config.json") assert.True(katautils.FileExists(ociConfigFile)) - spec, err := oci.ParseConfigJSON(bundlePath) + spec, err := compatoci.ParseConfigJSON(bundlePath) assert.NoError(err) // set the error containerType diff --git a/containerd-shim-v2/delete_test.go b/containerd-shim-v2/delete_test.go index 3bc4dfb7d6..c77c1adae1 100644 --- a/containerd-shim-v2/delete_test.go +++ b/containerd-shim-v2/delete_test.go @@ -15,7 +15,7 @@ import ( taskAPI "github.com/containerd/containerd/runtime/v2/task" "github.com/stretchr/testify/assert" - "github.com/kata-containers/runtime/virtcontainers/pkg/oci" + "github.com/kata-containers/runtime/virtcontainers/pkg/compatoci" "github.com/kata-containers/runtime/virtcontainers/pkg/vcmock" ) @@ -28,7 +28,7 @@ func TestDeleteContainerSuccessAndFail(t *testing.T) { rootPath, bundlePath := testConfigSetup(t) defer os.RemoveAll(rootPath) - _, err := oci.ParseConfigJSON(bundlePath) + _, err := compatoci.ParseConfigJSON(bundlePath) assert.NoError(err) s := &service{ diff --git a/containerd-shim-v2/service.go b/containerd-shim-v2/service.go index a46fe8c2b1..89a4642fbd 100644 --- a/containerd-shim-v2/service.go +++ b/containerd-shim-v2/service.go @@ -15,24 +15,25 @@ import ( "time" eventstypes "github.com/containerd/containerd/api/events" + "github.com/containerd/containerd/api/types/task" "github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/events" "github.com/containerd/containerd/namespaces" cdruntime "github.com/containerd/containerd/runtime" cdshim "github.com/containerd/containerd/runtime/v2/shim" taskAPI "github.com/containerd/containerd/runtime/v2/task" - "github.com/kata-containers/runtime/pkg/katautils" - vc "github.com/kata-containers/runtime/virtcontainers" - "github.com/kata-containers/runtime/virtcontainers/pkg/oci" - "github.com/kata-containers/runtime/virtcontainers/types" - "github.com/opencontainers/runtime-spec/specs-go" - - "github.com/containerd/containerd/api/types/task" "github.com/containerd/typeurl" ptypes "github.com/gogo/protobuf/types" + "github.com/opencontainers/runtime-spec/specs-go" "github.com/pkg/errors" "github.com/sirupsen/logrus" "golang.org/x/sys/unix" + + "github.com/kata-containers/runtime/pkg/katautils" + vc "github.com/kata-containers/runtime/virtcontainers" + "github.com/kata-containers/runtime/virtcontainers/pkg/compatoci" + "github.com/kata-containers/runtime/virtcontainers/pkg/oci" + "github.com/kata-containers/runtime/virtcontainers/types" ) const ( @@ -291,7 +292,7 @@ func (s *service) Cleanup(ctx context.Context) (_ *taskAPI.DeleteResponse, err e return nil, err } - ociSpec, err := oci.ParseConfigJSON(path) + ociSpec, err := compatoci.ParseConfigJSON(path) if err != nil { return nil, err } diff --git a/containerd-shim-v2/utils.go b/containerd-shim-v2/utils.go index eee923595a..cebac177b3 100644 --- a/containerd-shim-v2/utils.go +++ b/containerd-shim-v2/utils.go @@ -17,6 +17,7 @@ import ( cdshim "github.com/containerd/containerd/runtime/v2/shim" "github.com/kata-containers/runtime/pkg/katautils" vc "github.com/kata-containers/runtime/virtcontainers" + "github.com/kata-containers/runtime/virtcontainers/pkg/compatoci" "github.com/kata-containers/runtime/virtcontainers/pkg/oci" "github.com/opencontainers/runtime-spec/specs-go" "github.com/sirupsen/logrus" @@ -87,7 +88,7 @@ func getAddress(ctx context.Context, bundlePath, id string) (string, error) { return "", err } - ociSpec, err := oci.ParseConfigJSON(bundlePath) + ociSpec, err := compatoci.ParseConfigJSON(bundlePath) if err != nil { return "", err } diff --git a/containerd-shim-v2/utils_test.go b/containerd-shim-v2/utils_test.go index 2470547f33..fd543affdf 100644 --- a/containerd-shim-v2/utils_test.go +++ b/containerd-shim-v2/utils_test.go @@ -22,6 +22,7 @@ import ( ktu "github.com/kata-containers/runtime/pkg/katatestutils" "github.com/kata-containers/runtime/pkg/katautils" vc "github.com/kata-containers/runtime/virtcontainers" + "github.com/kata-containers/runtime/virtcontainers/pkg/compatoci" "github.com/kata-containers/runtime/virtcontainers/pkg/oci" "github.com/kata-containers/runtime/virtcontainers/pkg/vcmock" ) @@ -236,7 +237,7 @@ func realMakeOCIBundle(bundleDir string) error { // Note the unusual parameter (a directory, not the config // file to parse!) - spec, err := oci.ParseConfigJSON(bundleDir) + spec, err := compatoci.ParseConfigJSON(bundleDir) if err != nil { return err } diff --git a/pkg/katautils/create_test.go b/pkg/katautils/create_test.go index 5170927d17..7c95003c88 100644 --- a/pkg/katautils/create_test.go +++ b/pkg/katautils/create_test.go @@ -21,6 +21,7 @@ import ( ktu "github.com/kata-containers/runtime/pkg/katatestutils" vc "github.com/kata-containers/runtime/virtcontainers" + "github.com/kata-containers/runtime/virtcontainers/pkg/compatoci" "github.com/kata-containers/runtime/virtcontainers/pkg/oci" "github.com/kata-containers/runtime/virtcontainers/pkg/vcmock" "github.com/opencontainers/runtime-spec/specs-go" @@ -275,7 +276,7 @@ func TestCreateSandboxConfigFail(t *testing.T) { ociConfigFile := filepath.Join(bundlePath, "config.json") assert.True(FileExists(ociConfigFile)) - spec, err := oci.ParseConfigJSON(bundlePath) + spec, err := compatoci.ParseConfigJSON(bundlePath) assert.NoError(err) quota := int64(0) @@ -323,7 +324,7 @@ func TestCreateSandboxFail(t *testing.T) { ociConfigFile := filepath.Join(bundlePath, "config.json") assert.True(FileExists(ociConfigFile)) - spec, err := oci.ParseConfigJSON(bundlePath) + spec, err := compatoci.ParseConfigJSON(bundlePath) assert.NoError(err) rootFs := vc.RootFs{Mounted: true} @@ -353,7 +354,7 @@ func TestCreateContainerContainerConfigFail(t *testing.T) { ociConfigFile := filepath.Join(bundlePath, "config.json") assert.True(FileExists(ociConfigFile)) - spec, err := oci.ParseConfigJSON(bundlePath) + spec, err := compatoci.ParseConfigJSON(bundlePath) assert.NoError(err) // Set invalid container type @@ -396,7 +397,7 @@ func TestCreateContainerFail(t *testing.T) { ociConfigFile := filepath.Join(bundlePath, "config.json") assert.True(FileExists(ociConfigFile)) - spec, err := oci.ParseConfigJSON(bundlePath) + spec, err := compatoci.ParseConfigJSON(bundlePath) assert.NoError(err) // set expected container type and sandboxID @@ -446,7 +447,7 @@ func TestCreateContainer(t *testing.T) { ociConfigFile := filepath.Join(bundlePath, "config.json") assert.True(FileExists(ociConfigFile)) - spec, err := oci.ParseConfigJSON(bundlePath) + spec, err := compatoci.ParseConfigJSON(bundlePath) assert.NoError(err) // set expected container type and sandboxID diff --git a/pkg/katautils/utils_test.go b/pkg/katautils/utils_test.go index 03ab5bf1dd..4806c18fa6 100644 --- a/pkg/katautils/utils_test.go +++ b/pkg/katautils/utils_test.go @@ -18,7 +18,7 @@ import ( "syscall" "testing" - "github.com/kata-containers/runtime/virtcontainers/pkg/oci" + "github.com/kata-containers/runtime/virtcontainers/pkg/compatoci" "github.com/stretchr/testify/assert" ) @@ -124,7 +124,7 @@ func realMakeOCIBundle(bundleDir string) error { // Note the unusual parameter (a directory, not the config // file to parse!) - spec, err := oci.ParseConfigJSON(bundleDir) + spec, err := compatoci.ParseConfigJSON(bundleDir) if err != nil { return err } diff --git a/virtcontainers/api.go b/virtcontainers/api.go index 769ae660f1..97b0f44aa1 100644 --- a/virtcontainers/api.go +++ b/virtcontainers/api.go @@ -613,6 +613,7 @@ func statusContainer(sandbox *Sandbox, containerID string) (ContainerStatus, err PID: container.process.Pid, StartTime: container.process.StartTime, RootFs: container.config.RootFs.Target, + Spec: container.GetOCISpec(), Annotations: container.config.Annotations, }, nil } diff --git a/virtcontainers/api_test.go b/virtcontainers/api_test.go index d53ed065e7..1c76ec5683 100644 --- a/virtcontainers/api_test.go +++ b/virtcontainers/api_test.go @@ -7,6 +7,7 @@ package virtcontainers import ( "context" + "encoding/json" "fmt" "os" "path/filepath" @@ -15,7 +16,6 @@ import ( "testing" ktu "github.com/kata-containers/runtime/pkg/katatestutils" - "github.com/kata-containers/runtime/virtcontainers/pkg/annotations" "github.com/kata-containers/runtime/virtcontainers/pkg/mock" vcTypes "github.com/kata-containers/runtime/virtcontainers/pkg/types" "github.com/kata-containers/runtime/virtcontainers/store" @@ -30,15 +30,24 @@ const ( ) var sandboxAnnotations = map[string]string{ - "sandbox.foo": "sandbox.bar", - "sandbox.hello": "sandbox.world", - annotations.ConfigJSONKey: `{"linux":{"resources":{}}}`, + "sandbox.foo": "sandbox.bar", + "sandbox.hello": "sandbox.world", } var containerAnnotations = map[string]string{ - "container.foo": "container.bar", - "container.hello": "container.world", - annotations.ConfigJSONKey: `{"linux":{"resources":{}}}`, + "container.foo": "container.bar", + "container.hello": "container.world", +} + +func newEmptySpec() *specs.Spec { + return &specs.Spec{ + Linux: &specs.Linux{ + Resources: &specs.LinuxResources{}, + }, + Process: &specs.Process{ + Capabilities: &specs.LinuxCapabilities{}, + }, + } } func newBasicTestCmd() types.Cmd { @@ -59,12 +68,19 @@ func newBasicTestCmd() types.Cmd { } func newTestSandboxConfigNoop() SandboxConfig { + bundlePath := filepath.Join(testDir, testBundle) + containerAnnotations["com.github.containers.virtcontainers.pkg.oci.bundle_path"] = bundlePath + // containerAnnotations["com.github.containers.virtcontainers.pkg.oci.container_type"] = "pod_sandbox" + + emptySpec := newEmptySpec() + // Define the container command and bundle. container := ContainerConfig{ ID: containerID, - RootFs: RootFs{Target: filepath.Join(testDir, testBundle), Mounted: true}, + RootFs: RootFs{Target: bundlePath, Mounted: true}, Cmd: newBasicTestCmd(), Annotations: containerAnnotations, + Spec: emptySpec, } // Sets the hypervisor configuration. @@ -88,28 +104,24 @@ func newTestSandboxConfigNoop() SandboxConfig { ProxyType: NoopProxyType, } + configFile := filepath.Join(bundlePath, "config.json") + f, err := os.OpenFile(configFile, os.O_RDWR|os.O_CREATE, 0644) + if err != nil { + return SandboxConfig{} + } + defer f.Close() + + if err := json.NewEncoder(f).Encode(emptySpec); err != nil { + return SandboxConfig{} + } + return sandboxConfig } func newTestSandboxConfigKataAgent() SandboxConfig { - // Sets the hypervisor configuration. - hypervisorConfig := HypervisorConfig{ - KernelPath: filepath.Join(testDir, testKernel), - ImagePath: filepath.Join(testDir, testImage), - HypervisorPath: filepath.Join(testDir, testHypervisor), - } - - sandboxConfig := SandboxConfig{ - ID: testSandboxID, - HypervisorType: MockHypervisor, - HypervisorConfig: hypervisorConfig, - - AgentType: KataContainersAgent, - - Annotations: sandboxAnnotations, - - ProxyType: NoopProxyType, - } + sandboxConfig := newTestSandboxConfigNoop() + sandboxConfig.AgentType = KataContainersAgent + sandboxConfig.Containers = nil return sandboxConfig } @@ -577,6 +589,7 @@ func TestStatusSandboxSuccessfulStateReady(t *testing.T) { PID: 0, RootFs: filepath.Join(testDir, testBundle), Annotations: containerAnnotations, + Spec: newEmptySpec(), }, }, } @@ -593,7 +606,7 @@ func TestStatusSandboxSuccessfulStateReady(t *testing.T) { // value will be. expectedStatus.ContainersStatus[0].StartTime = status.ContainersStatus[0].StartTime - assert.Exactly(status, expectedStatus) + assert.Equal(status, expectedStatus) } func TestStatusSandboxSuccessfulStateRunning(t *testing.T) { @@ -635,6 +648,7 @@ func TestStatusSandboxSuccessfulStateRunning(t *testing.T) { PID: 0, RootFs: filepath.Join(testDir, testBundle), Annotations: containerAnnotations, + Spec: newEmptySpec(), }, }, } @@ -701,6 +715,7 @@ func newTestContainerConfigNoop(contID string) ContainerConfig { RootFs: RootFs{Target: filepath.Join(testDir, testBundle), Mounted: true}, Cmd: newBasicTestCmd(), Annotations: containerAnnotations, + Spec: newEmptySpec(), } return container @@ -1202,6 +1217,7 @@ func TestStatusContainerStateReady(t *testing.T) { PID: 0, RootFs: filepath.Join(testDir, testBundle), Annotations: containerAnnotations, + Spec: newEmptySpec(), } defer p2.wg.Wait() @@ -1268,6 +1284,7 @@ func TestStatusContainerStateRunning(t *testing.T) { PID: 0, RootFs: filepath.Join(testDir, testBundle), Annotations: containerAnnotations, + Spec: newEmptySpec(), } defer p2.wg.Wait() diff --git a/virtcontainers/cgroups_test.go b/virtcontainers/cgroups_test.go index 9c8dc691fb..98ca42f69b 100644 --- a/virtcontainers/cgroups_test.go +++ b/virtcontainers/cgroups_test.go @@ -174,6 +174,7 @@ func TestUpdateCgroups(t *testing.T) { }, config: &ContainerConfig{ Annotations: containerAnnotations, + Spec: newEmptySpec(), }, }, "xyz": { @@ -182,6 +183,7 @@ func TestUpdateCgroups(t *testing.T) { }, config: &ContainerConfig{ Annotations: containerAnnotations, + Spec: newEmptySpec(), }, }, } diff --git a/virtcontainers/container.go b/virtcontainers/container.go index 1422a02dd8..cbe979386d 100644 --- a/virtcontainers/container.go +++ b/virtcontainers/container.go @@ -9,7 +9,6 @@ package virtcontainers import ( "context" "encoding/hex" - "encoding/json" "fmt" "io" "os" @@ -18,7 +17,6 @@ import ( "time" "github.com/containerd/cgroups" - "github.com/kata-containers/runtime/virtcontainers/pkg/annotations" vcTypes "github.com/kata-containers/runtime/virtcontainers/pkg/types" "github.com/kata-containers/runtime/virtcontainers/types" "github.com/kata-containers/runtime/virtcontainers/utils" @@ -80,6 +78,7 @@ type ContainerStatus struct { PID int StartTime time.Time RootFs string + Spec *specs.Spec // Annotations allow clients to store arbitrary values, // for example to add additional status values required @@ -250,6 +249,9 @@ type ContainerConfig struct { // Resources container resources Resources specs.LinuxResources + + // Raw OCI specification, it won't be saved to disk. + Spec *specs.Spec `json:"_"` } // valid checks that the container configuration is valid. @@ -403,6 +405,11 @@ func (c *Container) GetAnnotations() map[string]string { return c.config.Annotations } +// GetOCISpec returns container's OCI specification +func (c *Container) GetOCISpec() *specs.Spec { + return c.config.Spec +} + // storeContainer stores a container config. func (c *Container) storeContainer() error { if c.sandbox.supportNewStore() { @@ -1453,16 +1460,9 @@ func (c *Container) detachDevices() error { // cgroupsCreate creates cgroups on the host for the associated container func (c *Container) cgroupsCreate() (err error) { - ann := c.GetAnnotations() - - config, ok := ann[annotations.ConfigJSONKey] - if !ok { - return fmt.Errorf("Could not find json config in annotations") - } - - var spec specs.Spec - if err := json.Unmarshal([]byte(config), &spec); err != nil { - return err + spec := c.GetOCISpec() + if spec == nil { + return errorMissingOCISpec } // https://github.com/kata-containers/runtime/issues/168 diff --git a/virtcontainers/kata_agent.go b/virtcontainers/kata_agent.go index f78e126d60..4cb104d16b 100644 --- a/virtcontainers/kata_agent.go +++ b/virtcontainers/kata_agent.go @@ -745,14 +745,10 @@ func (k *kataAgent) setProxyFromGrpc(proxy proxy, pid int, url string) { } func (k *kataAgent) getDNS(sandbox *Sandbox) ([]string, error) { - ociSpecJSON, ok := sandbox.config.Annotations[vcAnnotations.ConfigJSONKey] - if !ok { - return nil, errorMissingOCISpec - } - - ociSpec := &specs.Spec{} - if err := json.Unmarshal([]byte(ociSpecJSON), ociSpec); err != nil { - return nil, err + ociSpec := sandbox.GetOCISpec() + if ociSpec == nil { + k.Logger().Debug("Sandbox OCI spec not found. Sandbox DNS will not be set.") + return nil, nil } ociMounts := ociSpec.Mounts @@ -1260,11 +1256,6 @@ func (k *kataAgent) createContainer(sandbox *Sandbox, c *Container) (p *Process, span, _ := k.trace("createContainer") defer span.Finish() - ociSpecJSON, ok := c.config.Annotations[vcAnnotations.ConfigJSONKey] - if !ok { - return nil, errorMissingOCISpec - } - var ctrStorages []*grpc.Storage var ctrDevices []*grpc.Device var rootfs *grpc.Storage @@ -1291,9 +1282,9 @@ func (k *kataAgent) createContainer(sandbox *Sandbox, c *Container) (p *Process, ctrStorages = append(ctrStorages, rootfs) } - ociSpec := &specs.Spec{} - if err = json.Unmarshal([]byte(ociSpecJSON), ociSpec); err != nil { - return nil, err + ociSpec := c.GetOCISpec() + if ociSpec == nil { + return nil, errorMissingOCISpec } // Handle container mounts diff --git a/virtcontainers/kata_agent_test.go b/virtcontainers/kata_agent_test.go index 3c4576ad0c..cba9b01437 100644 --- a/virtcontainers/kata_agent_test.go +++ b/virtcontainers/kata_agent_test.go @@ -7,7 +7,6 @@ package virtcontainers import ( "context" - "encoding/json" "fmt" "io/ioutil" "net" @@ -30,7 +29,6 @@ import ( "github.com/kata-containers/runtime/virtcontainers/device/config" "github.com/kata-containers/runtime/virtcontainers/device/drivers" "github.com/kata-containers/runtime/virtcontainers/device/manager" - vcAnnotations "github.com/kata-containers/runtime/virtcontainers/pkg/annotations" "github.com/kata-containers/runtime/virtcontainers/pkg/mock" vcTypes "github.com/kata-containers/runtime/virtcontainers/pkg/types" "github.com/kata-containers/runtime/virtcontainers/store" @@ -747,14 +745,11 @@ func TestAgentCreateContainer(t *testing.T) { Fstype: "xfs", }, config: &ContainerConfig{ + Spec: &specs.Spec{}, Annotations: map[string]string{}, }, } - ociSpec, err := json.Marshal(&specs.Spec{}) - assert.Nil(err) - container.config.Annotations[vcAnnotations.ConfigJSONKey] = string(ociSpec[:]) - impl := &gRPCProxy{} proxy := mock.ProxyGRPCMock{ diff --git a/virtcontainers/pkg/annotations/annotations.go b/virtcontainers/pkg/annotations/annotations.go index b62c14e9da..42e43c9f1b 100644 --- a/virtcontainers/pkg/annotations/annotations.go +++ b/virtcontainers/pkg/annotations/annotations.go @@ -47,9 +47,6 @@ const ( // AssetHashType is the hash type used for assets verification AssetHashType = vcAnnotationsPrefix + "AssetHashType" - // ConfigJSONKey is the annotation key to fetch the OCI configuration. - ConfigJSONKey = vcAnnotationsPrefix + "pkg.oci.config" - // BundlePathKey is the annotation key to fetch the OCI configuration file path. BundlePathKey = vcAnnotationsPrefix + "pkg.oci.bundle_path" diff --git a/virtcontainers/pkg/compatoci/utils.go b/virtcontainers/pkg/compatoci/utils.go new file mode 100644 index 0000000000..edd2201da1 --- /dev/null +++ b/virtcontainers/pkg/compatoci/utils.go @@ -0,0 +1,151 @@ +// Copyright (c) 2017 Intel Corporation +// +// SPDX-License-Identifier: Apache-2.0 +// + +package compatoci + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "path/filepath" + + specs "github.com/opencontainers/runtime-spec/specs-go" + "github.com/sirupsen/logrus" + + vcAnnotations "github.com/kata-containers/runtime/virtcontainers/pkg/annotations" +) + +var ociLog = logrus.WithFields(logrus.Fields{ + "source": "virtcontainers", + "subsystem": "compatoci", +}) + +// compatOCIProcess is a structure inheriting from specs.Process defined +// in runtime-spec/specs-go package. The goal is to be compatible with +// both v1.0.0-rc4 and v1.0.0-rc5 since the latter introduced a change +// about the type of the Capabilities field. +// Refer to: https://github.com/opencontainers/runtime-spec/commit/37391fb +type compatOCIProcess struct { + specs.Process + Capabilities interface{} `json:"capabilities,omitempty" platform:"linux"` //nolint:govet +} + +// compatOCISpec is a structure inheriting from specs.Spec defined +// in runtime-spec/specs-go package. It relies on the compatOCIProcess +// structure declared above, in order to be compatible with both +// v1.0.0-rc4 and v1.0.0-rc5. +// Refer to: https://github.com/opencontainers/runtime-spec/commit/37391fb +type compatOCISpec struct { + specs.Spec + Process *compatOCIProcess `json:"process,omitempty"` //nolint:govet +} + +func containerCapabilities(s compatOCISpec) (specs.LinuxCapabilities, error) { + capabilities := s.Process.Capabilities + var c specs.LinuxCapabilities + + // In spec v1.0.0-rc4, capabilities was a list of strings. This was changed + // to an object with v1.0.0-rc5. + // Check for the interface type to support both the versions. + switch caps := capabilities.(type) { + case map[string]interface{}: + for key, value := range caps { + switch val := value.(type) { + case []interface{}: + var list []string + + for _, str := range val { + list = append(list, str.(string)) + } + + switch key { + case "bounding": + c.Bounding = list + case "effective": + c.Effective = list + case "inheritable": + c.Inheritable = list + case "ambient": + c.Ambient = list + case "permitted": + c.Permitted = list + } + + default: + return c, fmt.Errorf("Unexpected format for capabilities: %v", caps) + } + } + case []interface{}: + var list []string + for _, str := range caps { + list = append(list, str.(string)) + } + + c = specs.LinuxCapabilities{ + Bounding: list, + Effective: list, + Inheritable: list, + Ambient: list, + Permitted: list, + } + case nil: + ociLog.Debug("Empty capabilities have been passed") + return c, nil + default: + return c, fmt.Errorf("Unexpected format for capabilities: %v", caps) + } + + return c, nil +} + +// ContainerCapabilities return a LinuxCapabilities for virtcontainer +func ContainerCapabilities(s compatOCISpec) (specs.LinuxCapabilities, error) { + if s.Process == nil { + return specs.LinuxCapabilities{}, fmt.Errorf("ContainerCapabilities, Process is nil") + } + return containerCapabilities(s) +} + +// getConfigPath returns the full config path from the bundle +// path provided. +func getConfigPath(bundlePath string) string { + return filepath.Join(bundlePath, "config.json") +} + +// ParseConfigJSON unmarshals the config.json file. +func ParseConfigJSON(bundlePath string) (specs.Spec, error) { + configPath := getConfigPath(bundlePath) + ociLog.Debugf("converting %s", configPath) + + configByte, err := ioutil.ReadFile(configPath) + if err != nil { + return specs.Spec{}, err + } + + var compSpec compatOCISpec + if err := json.Unmarshal(configByte, &compSpec); err != nil { + return specs.Spec{}, err + } + + caps, err := ContainerCapabilities(compSpec) + if err != nil { + return specs.Spec{}, err + } + + compSpec.Spec.Process = &compSpec.Process.Process + compSpec.Spec.Process.Capabilities = &caps + + return compSpec.Spec, nil +} + +func GetContainerSpec(annotations map[string]string) (specs.Spec, error) { + if bundlePath, ok := annotations[vcAnnotations.BundlePathKey]; ok { + return ParseConfigJSON(bundlePath) + } + + ociLog.Errorf("Annotations[%s] not found, cannot find container spec", + vcAnnotations.BundlePathKey) + return specs.Spec{}, fmt.Errorf("Could not find container spec") +} diff --git a/virtcontainers/pkg/compatoci/utils_test.go b/virtcontainers/pkg/compatoci/utils_test.go new file mode 100644 index 0000000000..ed8bdf864a --- /dev/null +++ b/virtcontainers/pkg/compatoci/utils_test.go @@ -0,0 +1,147 @@ +// Copyright (c) 2017 Intel Corporation +// +// SPDX-License-Identifier: Apache-2.0 +// + +package compatoci + +import ( + "encoding/json" + "path/filepath" + "testing" + + specs "github.com/opencontainers/runtime-spec/specs-go" + "github.com/stretchr/testify/assert" +) + +const ( + tempBundlePath = "/tmp/virtc/ocibundle/" + capabilitiesSpecArray = ` + { + "ociVersion": "1.0.0-rc2-dev", + "process": { + "capabilities": [ + "CAP_CHOWN", + "CAP_DAC_OVERRIDE", + "CAP_FSETID" + ] + } + }` + + capabilitiesSpecStruct = ` + { + "ociVersion": "1.0.0-rc5", + "process": { + "capabilities": { + "bounding": [ + "CAP_CHOWN", + "CAP_DAC_OVERRIDE", + "CAP_FSETID" + ], + "effective": [ + "CAP_CHOWN", + "CAP_DAC_OVERRIDE", + "CAP_FSETID" + ], + "inheritable": [ + "CAP_CHOWN", + "CAP_DAC_OVERRIDE", + "CAP_FSETID" + ], + "permitted": [ + "CAP_CHOWN", + "CAP_DAC_OVERRIDE", + "CAP_FSETID" + ] + } + } + }` +) + +func TestContainerCapabilities(t *testing.T) { + var ociSpec compatOCISpec + + ociSpec.Process = &compatOCIProcess{} + ociSpec.Process.Capabilities = map[string]interface{}{ + "bounding": []interface{}{"CAP_KILL"}, + "effective": []interface{}{"CAP_KILL", "CAP_LEASE"}, + "permitted": []interface{}{"CAP_SETUID"}, + "inheritable": []interface{}{"CAP_KILL", "CAP_LEASE", "CAP_SYS_ADMIN"}, + "ambient": []interface{}{""}, + } + + c, err := ContainerCapabilities(ociSpec) + assert.Nil(t, err) + assert.Equal(t, c.Bounding, []string{"CAP_KILL"}) + assert.Equal(t, c.Effective, []string{"CAP_KILL", "CAP_LEASE"}) + assert.Equal(t, c.Permitted, []string{"CAP_SETUID"}) + assert.Equal(t, c.Inheritable, []string{"CAP_KILL", "CAP_LEASE", "CAP_SYS_ADMIN"}) + assert.Equal(t, c.Ambient, []string{""}) + + ociSpec.Process.Capabilities = []interface{}{"CAP_LEASE", "CAP_SETUID"} + + c, err = ContainerCapabilities(ociSpec) + assert.Nil(t, err) + assert.Equal(t, c.Bounding, []string{"CAP_LEASE", "CAP_SETUID"}) + assert.Equal(t, c.Effective, []string{"CAP_LEASE", "CAP_SETUID"}) + assert.Equal(t, c.Permitted, []string{"CAP_LEASE", "CAP_SETUID"}) + assert.Equal(t, c.Inheritable, []string{"CAP_LEASE", "CAP_SETUID"}) + assert.Equal(t, c.Ambient, []string{"CAP_LEASE", "CAP_SETUID"}) + + ociSpec.Process.Capabilities = nil + + c, err = ContainerCapabilities(ociSpec) + assert.Nil(t, err) + assert.Equal(t, c.Bounding, []string(nil)) + assert.Equal(t, c.Effective, []string(nil)) + assert.Equal(t, c.Permitted, []string(nil)) + assert.Equal(t, c.Inheritable, []string(nil)) + assert.Equal(t, c.Ambient, []string(nil)) +} + +// use specs.Spec to decode the spec, the content of capabilities is [] string +func TestCompatOCISpecWithArray(t *testing.T) { + compatOCISpec := compatOCISpec{} + err := json.Unmarshal([]byte(capabilitiesSpecArray), &compatOCISpec) + assert.Nil(t, err, "use compatOCISpec to decode capabilitiesSpecArray failed") + + ociSpecJSON, err := json.Marshal(compatOCISpec) + assert.Nil(t, err, "encode compatOCISpec failed") + + // use specs.Spec to decode the spec, specs.Spec' capabilities is struct, + // but the content of spec' capabilities is [] string + ociSpec := specs.Spec{} + err = json.Unmarshal(ociSpecJSON, &ociSpec) + assert.NotNil(t, err, "This test should fail") + + caps, err := ContainerCapabilities(compatOCISpec) + assert.Nil(t, err, "decode capabilities failed") + compatOCISpec.Process.Capabilities = caps + + ociSpecJSON, err = json.Marshal(compatOCISpec) + assert.Nil(t, err, "encode compatOCISpec failed") + + // capabilities has been chaged to struct + err = json.Unmarshal(ociSpecJSON, &ociSpec) + assert.Nil(t, err, "This test should fail") +} + +// use specs.Spec to decode the spec, the content of capabilities is struct +func TestCompatOCISpecWithStruct(t *testing.T) { + compatOCISpec := compatOCISpec{} + err := json.Unmarshal([]byte(capabilitiesSpecStruct), &compatOCISpec) + assert.Nil(t, err, "use compatOCISpec to decode capabilitiesSpecStruct failed") + + ociSpecJSON, err := json.Marshal(compatOCISpec) + assert.Nil(t, err, "encode compatOCISpec failed") + + ociSpec := specs.Spec{} + err = json.Unmarshal(ociSpecJSON, &ociSpec) + assert.Nil(t, err, "This test should not fail") +} + +func TestGetConfigPath(t *testing.T) { + expected := filepath.Join(tempBundlePath, "config.json") + configPath := getConfigPath(tempBundlePath) + assert.Equal(t, configPath, expected) +} diff --git a/virtcontainers/pkg/oci/utils.go b/virtcontainers/pkg/oci/utils.go index 0c3c1e61e4..7419239459 100644 --- a/virtcontainers/pkg/oci/utils.go +++ b/virtcontainers/pkg/oci/utils.go @@ -7,10 +7,8 @@ package oci import ( "context" - "encoding/json" "errors" "fmt" - "io/ioutil" "path/filepath" "strconv" "strings" @@ -75,26 +73,6 @@ const ( const KernelModulesSeparator = ";" -// compatOCIProcess is a structure inheriting from specs.Process defined -// in runtime-spec/specs-go package. The goal is to be compatible with -// both v1.0.0-rc4 and v1.0.0-rc5 since the latter introduced a change -// about the type of the Capabilities field. -// Refer to: https://github.com/opencontainers/runtime-spec/commit/37391fb -type compatOCIProcess struct { - specs.Process - Capabilities interface{} `json:"capabilities,omitempty" platform:"linux"` //nolint:govet -} - -// compatOCISpec is a structure inheriting from specs.Spec defined -// in runtime-spec/specs-go package. It relies on the CompatOCIProcess -// structure declared above, in order to be compatible with both -// v1.0.0-rc4 and v1.0.0-rc5. -// Refer to: https://github.com/opencontainers/runtime-spec/commit/37391fb -type compatOCISpec struct { - specs.Spec - Process *compatOCIProcess `json:"process,omitempty"` //nolint:govet -} - // FactoryConfig is a structure to set the VM factory configuration. type FactoryConfig struct { // Template enables VM templating support in VM factory. @@ -267,69 +245,6 @@ func containerDeviceInfos(spec specs.Spec) ([]config.DeviceInfo, error) { return devices, nil } -// containerCapabilities return a LinuxCapabilities for virtcontainer -func containerCapabilities(s compatOCISpec) (specs.LinuxCapabilities, error) { - if s.Process == nil { - return specs.LinuxCapabilities{}, fmt.Errorf("containerCapabilities, Process is nil") - } - - capabilities := s.Process.Capabilities - var c specs.LinuxCapabilities - - // In spec v1.0.0-rc4, capabilities was a list of strings. This was changed - // to an object with v1.0.0-rc5. - // Check for the interface type to support both the versions. - switch caps := capabilities.(type) { - case map[string]interface{}: - for key, value := range caps { - switch val := value.(type) { - case []interface{}: - var list []string - - for _, str := range val { - list = append(list, str.(string)) - } - - switch key { - case "bounding": - c.Bounding = list - case "effective": - c.Effective = list - case "inheritable": - c.Inheritable = list - case "ambient": - c.Ambient = list - case "permitted": - c.Permitted = list - } - - default: - return c, fmt.Errorf("Unexpected format for capabilities: %v", caps) - } - } - case []interface{}: - var list []string - for _, str := range caps { - list = append(list, str.(string)) - } - - c = specs.LinuxCapabilities{ - Bounding: list, - Effective: list, - Inheritable: list, - Ambient: list, - Permitted: list, - } - case nil: - ociLog.Debug("Empty capabilities have been passed") - return c, nil - default: - return c, fmt.Errorf("Unexpected format for capabilities: %v", caps) - } - - return c, nil -} - func networkConfig(ocispec specs.Spec, config RuntimeConfig) (vc.NetworkConfig, error) { linux := ocispec.Linux if linux == nil { @@ -359,38 +274,6 @@ func networkConfig(ocispec specs.Spec, config RuntimeConfig) (vc.NetworkConfig, return netConf, nil } -// getConfigPath returns the full config path from the bundle -// path provided. -func getConfigPath(bundlePath string) string { - return filepath.Join(bundlePath, "config.json") -} - -// ParseConfigJSON unmarshals the config.json file. -func ParseConfigJSON(bundlePath string) (specs.Spec, error) { - configPath := getConfigPath(bundlePath) - ociLog.Debugf("converting %s", configPath) - - configByte, err := ioutil.ReadFile(configPath) - if err != nil { - return specs.Spec{}, err - } - - var compSpec compatOCISpec - if err := json.Unmarshal(configByte, &compSpec); err != nil { - return specs.Spec{}, err - } - - caps, err := containerCapabilities(compSpec) - if err != nil { - return specs.Spec{}, err - } - - compSpec.Spec.Process = &compSpec.Process.Process - compSpec.Spec.Process.Capabilities = &caps - - return compSpec.Spec, nil -} - // GetContainerType determines which type of container matches the annotations // table provided. func GetContainerType(annotations map[string]string) (vc.ContainerType, error) { @@ -484,11 +367,6 @@ func SandboxConfig(ocispec specs.Spec, runtime RuntimeConfig, bundlePath, cid, c return vc.SandboxConfig{}, err } - ociSpecJSON, err := json.Marshal(ocispec) - if err != nil { - return vc.SandboxConfig{}, err - } - sandboxConfig := vc.SandboxConfig{ ID: cid, @@ -511,7 +389,6 @@ func SandboxConfig(ocispec specs.Spec, runtime RuntimeConfig, bundlePath, cid, c Containers: []vc.ContainerConfig{containerConfig}, Annotations: map[string]string{ - vcAnnotations.ConfigJSONKey: string(ociSpecJSON), vcAnnotations.BundlePathKey: bundlePath, }, @@ -523,6 +400,9 @@ func SandboxConfig(ocispec specs.Spec, runtime RuntimeConfig, bundlePath, cid, c DisableGuestSeccomp: runtime.DisableGuestSeccomp, + // Q: Is this really necessary? @weizhang555 + // Spec: &ocispec, + Experimental: runtime.Experimental, } @@ -534,11 +414,6 @@ func SandboxConfig(ocispec specs.Spec, runtime RuntimeConfig, bundlePath, cid, c // ContainerConfig converts an OCI compatible runtime configuration // file to a virtcontainers container configuration structure. func ContainerConfig(ocispec specs.Spec, bundlePath, cid, console string, detach bool) (vc.ContainerConfig, error) { - ociSpecJSON, err := json.Marshal(ocispec) - if err != nil { - return vc.ContainerConfig{}, err - } - rootfs := vc.RootFs{Target: ocispec.Root.Path, Mounted: true} if !filepath.IsAbs(rootfs.Target) { rootfs.Target = filepath.Join(bundlePath, ocispec.Root.Path) @@ -578,12 +453,12 @@ func ContainerConfig(ocispec specs.Spec, bundlePath, cid, console string, detach ReadonlyRootfs: ocispec.Root.Readonly, Cmd: cmd, Annotations: map[string]string{ - vcAnnotations.ConfigJSONKey: string(ociSpecJSON), vcAnnotations.BundlePathKey: bundlePath, }, Mounts: containerMounts(ocispec), DeviceInfos: deviceInfos, Resources: *ocispec.Linux.Resources, + Spec: &ocispec, } cType, err := ContainerType(ocispec) @@ -686,15 +561,9 @@ func EnvVars(envs []string) ([]types.EnvVar, error) { // GetOCIConfig returns an OCI spec configuration from the annotation // stored into the container status. func GetOCIConfig(status vc.ContainerStatus) (specs.Spec, error) { - ociConfigStr, ok := status.Annotations[vcAnnotations.ConfigJSONKey] - if !ok { - return specs.Spec{}, fmt.Errorf("Annotation[%s] not found", vcAnnotations.ConfigJSONKey) + if status.Spec == nil { + return specs.Spec{}, fmt.Errorf("missing OCI spec for container") } - var ociSpec specs.Spec - if err := json.Unmarshal([]byte(ociConfigStr), &ociSpec); err != nil { - return specs.Spec{}, err - } - - return ociSpec, nil + return *status.Spec, nil } diff --git a/virtcontainers/pkg/oci/utils_test.go b/virtcontainers/pkg/oci/utils_test.go index dafb2451c8..8f526be1ef 100644 --- a/virtcontainers/pkg/oci/utils_test.go +++ b/virtcontainers/pkg/oci/utils_test.go @@ -6,7 +6,6 @@ package oci import ( - "encoding/json" "fmt" "io/ioutil" "os" @@ -18,7 +17,6 @@ import ( "testing" "github.com/cri-o/cri-o/pkg/annotations" - spec "github.com/opencontainers/runtime-spec/specs-go" specs "github.com/opencontainers/runtime-spec/specs-go" "github.com/stretchr/testify/assert" "golang.org/x/sys/unix" @@ -26,6 +24,7 @@ import ( vc "github.com/kata-containers/runtime/virtcontainers" "github.com/kata-containers/runtime/virtcontainers/device/config" vcAnnotations "github.com/kata-containers/runtime/virtcontainers/pkg/annotations" + "github.com/kata-containers/runtime/virtcontainers/pkg/compatoci" "github.com/kata-containers/runtime/virtcontainers/types" ) @@ -35,47 +34,6 @@ const ( consolePath = "/tmp/virtc/console" fileMode = os.FileMode(0640) dirMode = os.FileMode(0750) - - capabilitiesSpecArray = ` - { - "ociVersion": "1.0.0-rc2-dev", - "process": { - "capabilities": [ - "CAP_CHOWN", - "CAP_DAC_OVERRIDE", - "CAP_FSETID" - ] - } - }` - - capabilitiesSpecStruct = ` - { - "ociVersion": "1.0.0-rc5", - "process": { - "capabilities": { - "bounding": [ - "CAP_CHOWN", - "CAP_DAC_OVERRIDE", - "CAP_FSETID" - ], - "effective": [ - "CAP_CHOWN", - "CAP_DAC_OVERRIDE", - "CAP_FSETID" - ], - "inheritable": [ - "CAP_CHOWN", - "CAP_DAC_OVERRIDE", - "CAP_FSETID" - ], - "permitted": [ - "CAP_CHOWN", - "CAP_DAC_OVERRIDE", - "CAP_FSETID" - ] - } - } - }` ) func createConfig(fileName string, fileData string) (string, error) { @@ -168,18 +126,7 @@ func TestMinimalSandboxConfig(t *testing.T) { }, } - var minimalOCISpec compatOCISpec - - //Marshal and unmarshall json to compare sandboxConfig and expectedSandboxConfig - err = json.Unmarshal([]byte(minimalConfig), &minimalOCISpec) - assert.NoError(err) - if minimalOCISpec.Process != nil { - caps, err := containerCapabilities(minimalOCISpec) - assert.NoError(err) - minimalOCISpec.Spec.Process = &minimalOCISpec.Process.Process - minimalOCISpec.Spec.Process.Capabilities = &caps - } - ociSpecJSON, err := json.Marshal(minimalOCISpec.Spec) + spec, err := compatoci.ParseConfigJSON(tempBundlePath) assert.NoError(err) devInfo := config.DeviceInfo{ @@ -201,7 +148,6 @@ func TestMinimalSandboxConfig(t *testing.T) { ReadonlyRootfs: true, Cmd: expectedCmd, Annotations: map[string]string{ - vcAnnotations.ConfigJSONKey: string(ociSpecJSON), vcAnnotations.BundlePathKey: tempBundlePath, vcAnnotations.ContainerTypeKey: string(vc.PodSandbox), }, @@ -210,6 +156,7 @@ func TestMinimalSandboxConfig(t *testing.T) { Resources: specs.LinuxResources{Devices: []specs.LinuxDeviceCgroup{ {Allow: false, Type: "", Major: (*int64)(nil), Minor: (*int64)(nil), Access: "rwm"}, }}, + Spec: &spec, } expectedNetworkConfig := vc.NetworkConfig{} @@ -228,17 +175,13 @@ func TestMinimalSandboxConfig(t *testing.T) { Containers: []vc.ContainerConfig{expectedContainerConfig}, Annotations: map[string]string{ - vcAnnotations.ConfigJSONKey: string(ociSpecJSON), vcAnnotations.BundlePathKey: tempBundlePath, }, SystemdCgroup: true, } - ociSpec, err := ParseConfigJSON(tempBundlePath) - assert.NoError(err) - - sandboxConfig, err := SandboxConfig(ociSpec, runtimeConfig, tempBundlePath, containerID, consolePath, false, true) + sandboxConfig, err := SandboxConfig(spec, runtimeConfig, tempBundlePath, containerID, consolePath, false, true) assert.NoError(err) assert.Exactly(sandboxConfig, expectedSandboxConfig) @@ -261,7 +204,6 @@ func TestStatusToOCIStateSuccessfulWithReadyState(t *testing.T) { } containerAnnotations := map[string]string{ - vcAnnotations.ConfigJSONKey: minimalConfig, vcAnnotations.BundlePathKey: tempBundlePath, } @@ -297,7 +239,6 @@ func TestStatusToOCIStateSuccessfulWithRunningState(t *testing.T) { } containerAnnotations := map[string]string{ - vcAnnotations.ConfigJSONKey: minimalConfig, vcAnnotations.BundlePathKey: tempBundlePath, } @@ -332,7 +273,6 @@ func TestStatusToOCIStateSuccessfulWithStoppedState(t *testing.T) { } containerAnnotations := map[string]string{ - vcAnnotations.ConfigJSONKey: minimalConfig, vcAnnotations.BundlePathKey: tempBundlePath, } @@ -363,7 +303,6 @@ func TestStatusToOCIStateSuccessfulWithNoState(t *testing.T) { testRootFs := "testRootFs" containerAnnotations := map[string]string{ - vcAnnotations.ConfigJSONKey: minimalConfig, vcAnnotations.BundlePathKey: tempBundlePath, } @@ -452,12 +391,6 @@ func TestMalformedEnvVars(t *testing.T) { assert.Error(err) } -func TestGetConfigPath(t *testing.T) { - expected := filepath.Join(tempBundlePath, "config.json") - configPath := getConfigPath(tempBundlePath) - assert.Equal(t, configPath, expected) -} - func testGetContainerTypeSuccessful(t *testing.T, annotations map[string]string, expected vc.ContainerType) { assert := assert.New(t) containerType, err := GetContainerType(annotations) @@ -631,88 +564,6 @@ func TestDevicePathEmpty(t *testing.T) { assert.NotNil(t, err, "This test should fail as path cannot be empty for device") } -func TestContainerCapabilities(t *testing.T) { - var ociSpec compatOCISpec - - ociSpec.Process = &compatOCIProcess{} - ociSpec.Process.Capabilities = map[string]interface{}{ - "bounding": []interface{}{"CAP_KILL"}, - "effective": []interface{}{"CAP_KILL", "CAP_LEASE"}, - "permitted": []interface{}{"CAP_SETUID"}, - "inheritable": []interface{}{"CAP_KILL", "CAP_LEASE", "CAP_SYS_ADMIN"}, - "ambient": []interface{}{""}, - } - - c, err := containerCapabilities(ociSpec) - assert.Nil(t, err) - assert.Equal(t, c.Bounding, []string{"CAP_KILL"}) - assert.Equal(t, c.Effective, []string{"CAP_KILL", "CAP_LEASE"}) - assert.Equal(t, c.Permitted, []string{"CAP_SETUID"}) - assert.Equal(t, c.Inheritable, []string{"CAP_KILL", "CAP_LEASE", "CAP_SYS_ADMIN"}) - assert.Equal(t, c.Ambient, []string{""}) - - ociSpec.Process.Capabilities = []interface{}{"CAP_LEASE", "CAP_SETUID"} - - c, err = containerCapabilities(ociSpec) - assert.Nil(t, err) - assert.Equal(t, c.Bounding, []string{"CAP_LEASE", "CAP_SETUID"}) - assert.Equal(t, c.Effective, []string{"CAP_LEASE", "CAP_SETUID"}) - assert.Equal(t, c.Permitted, []string{"CAP_LEASE", "CAP_SETUID"}) - assert.Equal(t, c.Inheritable, []string{"CAP_LEASE", "CAP_SETUID"}) - assert.Equal(t, c.Ambient, []string{"CAP_LEASE", "CAP_SETUID"}) - - ociSpec.Process.Capabilities = nil - - c, err = containerCapabilities(ociSpec) - assert.Nil(t, err) - assert.Equal(t, c.Bounding, []string(nil)) - assert.Equal(t, c.Effective, []string(nil)) - assert.Equal(t, c.Permitted, []string(nil)) - assert.Equal(t, c.Inheritable, []string(nil)) - assert.Equal(t, c.Ambient, []string(nil)) -} - -// use specs.Spec to decode the spec, the content of capabilities is [] string -func TestCompatOCISpecWithArray(t *testing.T) { - compatOCISpec := compatOCISpec{} - err := json.Unmarshal([]byte(capabilitiesSpecArray), &compatOCISpec) - assert.Nil(t, err, "use compatOCISpec to decode capabilitiesSpecArray failed") - - ociSpecJSON, err := json.Marshal(compatOCISpec) - assert.Nil(t, err, "encode compatOCISpec failed") - - // use specs.Spec to decode the spec, specs.Spec' capabilities is struct, - // but the content of spec' capabilities is [] string - ociSpec := specs.Spec{} - err = json.Unmarshal(ociSpecJSON, &ociSpec) - assert.NotNil(t, err, "This test should fail") - - caps, err := containerCapabilities(compatOCISpec) - assert.Nil(t, err, "decode capabilities failed") - compatOCISpec.Process.Capabilities = caps - - ociSpecJSON, err = json.Marshal(compatOCISpec) - assert.Nil(t, err, "encode compatOCISpec failed") - - // capabilities has been chaged to struct - err = json.Unmarshal(ociSpecJSON, &ociSpec) - assert.Nil(t, err, "This test should fail") -} - -// use specs.Spec to decode the spec, the content of capabilities is struct -func TestCompatOCISpecWithStruct(t *testing.T) { - compatOCISpec := compatOCISpec{} - err := json.Unmarshal([]byte(capabilitiesSpecStruct), &compatOCISpec) - assert.Nil(t, err, "use compatOCISpec to decode capabilitiesSpecStruct failed") - - ociSpecJSON, err := json.Marshal(compatOCISpec) - assert.Nil(t, err, "encode compatOCISpec failed") - - ociSpec := specs.Spec{} - err = json.Unmarshal(ociSpecJSON, &ociSpec) - assert.Nil(t, err, "This test should not fail") -} - func TestGetShmSize(t *testing.T) { containerConfig := vc.ContainerConfig{ Mounts: []vc.Mount{}, @@ -811,7 +662,7 @@ func TestAddAssetAnnotations(t *testing.T) { AgentConfig: vc.KataAgentConfig{}, } - ocispec := spec.Spec{ + ocispec := specs.Spec{ Annotations: expectedAnnotations, } diff --git a/virtcontainers/sandbox.go b/virtcontainers/sandbox.go index 3d04941b5f..a8a34570c5 100644 --- a/virtcontainers/sandbox.go +++ b/virtcontainers/sandbox.go @@ -7,7 +7,6 @@ package virtcontainers import ( "context" - "encoding/json" "fmt" "io" "math" @@ -20,6 +19,12 @@ import ( "github.com/containerd/cgroups" "github.com/containernetworking/plugins/pkg/ns" + specs "github.com/opencontainers/runtime-spec/specs-go" + opentracing "github.com/opentracing/opentracing-go" + "github.com/pkg/errors" + "github.com/sirupsen/logrus" + "github.com/vishvananda/netlink" + "github.com/kata-containers/agent/protocols/grpc" "github.com/kata-containers/runtime/virtcontainers/device/api" "github.com/kata-containers/runtime/virtcontainers/device/config" @@ -29,15 +34,11 @@ import ( "github.com/kata-containers/runtime/virtcontainers/persist" persistapi "github.com/kata-containers/runtime/virtcontainers/persist/api" "github.com/kata-containers/runtime/virtcontainers/pkg/annotations" + "github.com/kata-containers/runtime/virtcontainers/pkg/compatoci" vcTypes "github.com/kata-containers/runtime/virtcontainers/pkg/types" "github.com/kata-containers/runtime/virtcontainers/store" "github.com/kata-containers/runtime/virtcontainers/types" "github.com/kata-containers/runtime/virtcontainers/utils" - specs "github.com/opencontainers/runtime-spec/specs-go" - opentracing "github.com/opentracing/opentracing-go" - "github.com/pkg/errors" - "github.com/sirupsen/logrus" - "github.com/vishvananda/netlink" ) const ( @@ -1089,7 +1090,15 @@ func (s *Sandbox) addContainer(c *Container) error { // in the guest. This should only be used when fetching a // sandbox that already exists. func (s *Sandbox) fetchContainers() error { - for _, contConfig := range s.config.Containers { + for i, contConfig := range s.config.Containers { + // Add spec from bundle path + spec, err := compatoci.GetContainerSpec(contConfig.Annotations) + if err != nil { + return err + } + contConfig.Spec = &spec + s.config.Containers[i] = contConfig + c, err := newContainer(s, contConfig) if err != nil { return err @@ -2090,45 +2099,21 @@ func (s *Sandbox) cpuResources() *specs.LinuxCPU { // setupSandboxCgroup creates and joins sandbox cgroups for the sandbox config func (s *Sandbox) setupSandboxCgroup() error { - var podSandboxConfig *ContainerConfig + spec := s.GetOCISpec() - if s.config == nil { - return fmt.Errorf("Sandbox config is nil") - } - - // get the container associated with the PodSandbox annotation. In Kubernetes, this - // represents the pause container. In Docker, this is the container. We derive the - // cgroup path from this container. - for _, cConfig := range s.config.Containers { - if cConfig.Annotations[annotations.ContainerTypeKey] == string(PodSandbox) { - podSandboxConfig = &cConfig - break - } - } - - if podSandboxConfig == nil { - return fmt.Errorf("Failed to find cgroup path for sandbox: Container of type '%s' not found", PodSandbox) - } - - configJSON, ok := podSandboxConfig.Annotations[annotations.ConfigJSONKey] - if !ok { - return fmt.Errorf("Could not find json config in annotations for container '%s'", podSandboxConfig.ID) - } - - var spec specs.Spec - if err := json.Unmarshal([]byte(configJSON), &spec); err != nil { - return err + if spec == nil { + return errorMissingOCISpec } if spec.Linux == nil { // Cgroup path is optional, though expected. If not defined, skip the setup - s.Logger().WithField("sandboxid", podSandboxConfig.ID).Warning("no cgroup path provided for pod sandbox, not creating sandbox cgroup") + s.Logger().WithField("sandboxid", s.id).Warning("no cgroup path provided for pod sandbox, not creating sandbox cgroup") return nil } validContainerCgroup := utils.ValidCgroupPath(spec.Linux.CgroupsPath) // Create a Kata sandbox cgroup with the cgroup of the sandbox container as the parent - s.state.CgroupPath = filepath.Join(filepath.Dir(validContainerCgroup), cgroupKataPrefix+"_"+podSandboxConfig.ID) + s.state.CgroupPath = filepath.Join(filepath.Dir(validContainerCgroup), cgroupKataPrefix+"_"+s.id) cgroup, err := cgroupsNewFunc(cgroups.V1, cgroups.StaticPath(s.state.CgroupPath), &specs.LinuxResources{}) if err != nil { return fmt.Errorf("Could not create sandbox cgroup in %v: %v", s.state.CgroupPath, err) @@ -2143,3 +2128,38 @@ func (s *Sandbox) setupSandboxCgroup() error { return nil } + +func (s *Sandbox) sandboxContConf() *ContainerConfig { + var podSandboxConfig *ContainerConfig + + if s.config == nil { + return nil + } + + // get the container associated with the PodSandbox annotation. In Kubernetes, this + // represents the pause container. In Docker, this is the container. We derive the + // cgroup path from this container. + for _, cConfig := range s.config.Containers { + if cConfig.Annotations[annotations.ContainerTypeKey] == string(PodSandbox) { + podSandboxConfig = &cConfig + break + } + } + + if podSandboxConfig == nil { + return nil + } + + return podSandboxConfig +} + +// GetOCISpec returns sandbox's OCI specification +func (s *Sandbox) GetOCISpec() *specs.Spec { + conf := s.sandboxContConf() + if conf == nil { + return nil + } + + // First container is sandbox container as default + return conf.Spec +} diff --git a/virtcontainers/sandbox_test.go b/virtcontainers/sandbox_test.go index 0f3942a6ab..9402b96f72 100644 --- a/virtcontainers/sandbox_test.go +++ b/virtcontainers/sandbox_test.go @@ -649,6 +649,7 @@ func TestContainerStateSetFstype(t *testing.T) { { ID: "100", Annotations: containerAnnotations, + Spec: newEmptySpec(), }, } @@ -1517,44 +1518,24 @@ func TestSandboxExperimentalFeature(t *testing.T) { assert.True(t, sconfig.valid()) } -/* -func TestSandbox_joinSandboxCgroup(t *testing.T) { - - mockValidCgroup := &Sandbox{} - mockValidCgroup.state.CgroupPath = "/my/cgroup" - - tests := []struct { - name string - s *Sandbox - wantErr bool - }{ - {"New Config", &Sandbox{}, false}, - {"Mock cgroup path", mockValidCgroup, false}, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if err := tt.s.joinSandboxCgroup(); (err != nil) != tt.wantErr { - t.Errorf("Sandbox.joinSandboxCgroup() error = %v, wantErr %v", err, tt.wantErr) - } - }) - } -} -*/ - func TestSandbox_SetupSandboxCgroup(t *testing.T) { sandboxContainer := ContainerConfig{} sandboxContainer.Annotations = make(map[string]string) sandboxContainer.Annotations[annotations.ContainerTypeKey] = string(PodSandbox) - emptyJSONLinux := ContainerConfig{} + emptyJSONLinux := ContainerConfig{ + Spec: newEmptySpec(), + } emptyJSONLinux.Annotations = make(map[string]string) emptyJSONLinux.Annotations[annotations.ContainerTypeKey] = string(PodSandbox) - emptyJSONLinux.Annotations[annotations.ConfigJSONKey] = "{}" - successfulContainer := ContainerConfig{} + cloneSpec1 := newEmptySpec() + cloneSpec1.Linux.CgroupsPath = "/myRuntime/myContainer" + successfulContainer := ContainerConfig{ + Spec: cloneSpec1, + } successfulContainer.Annotations = make(map[string]string) successfulContainer.Annotations[annotations.ContainerTypeKey] = string(PodSandbox) - successfulContainer.Annotations[annotations.ConfigJSONKey] = "{\"linux\": { \"cgroupsPath\": \"/myRuntime/myContainer\" }}" tests := []struct { name string