CompatOCISpec: limit usage of CompatOCISpec

Fixes: #2023

CompatOCISpec is used to gurantee backward compatbility for old runtime
specs, after we convert CompatOCISpec to standard specs.Spec, we should
use specs.Spec instead of CompatOCISpec, and CompatOCISpec should be
useless from then.

Spread usage of CompatOCISpec can make code structure confusing and making
the runtime spec usage non-standard. Besides, this can be the very first
step of removing CompatOCISpec from config's Annotations field.

Signed-off-by: Wei Zhang <weizhang555.zw@gmail.com>
This commit is contained in:
Wei Zhang 2019-09-04 19:56:23 +08:00
parent 4176a7c947
commit 9507f45a0f
22 changed files with 221 additions and 344 deletions

View File

@ -118,7 +118,7 @@ func create(ctx context.Context, containerID, bundlePath, console, pidFilePath s
return err return err
} }
containerType, err := ociSpec.ContainerType() containerType, err := oci.ContainerType(ociSpec)
if err != nil { if err != nil {
return err return err
} }

View File

@ -322,7 +322,7 @@ func TestCreateInvalidContainerType(t *testing.T) {
ociConfigFile := filepath.Join(bundlePath, "config.json") ociConfigFile := filepath.Join(bundlePath, "config.json")
assert.True(katautils.FileExists(ociConfigFile)) assert.True(katautils.FileExists(ociConfigFile))
spec, err := readOCIConfigFile(ociConfigFile) spec, err := oci.ParseConfigJSON(bundlePath)
assert.NoError(err) assert.NoError(err)
// Force an invalid container type // Force an invalid container type
@ -367,7 +367,7 @@ func TestCreateContainerInvalid(t *testing.T) {
ociConfigFile := filepath.Join(bundlePath, "config.json") ociConfigFile := filepath.Join(bundlePath, "config.json")
assert.True(katautils.FileExists(ociConfigFile)) assert.True(katautils.FileExists(ociConfigFile))
spec, err := readOCIConfigFile(ociConfigFile) spec, err := oci.ParseConfigJSON(bundlePath)
assert.NoError(err) assert.NoError(err)
@ -432,7 +432,7 @@ func TestCreateProcessCgroupsPathSuccessful(t *testing.T) {
ociConfigFile := filepath.Join(bundlePath, "config.json") ociConfigFile := filepath.Join(bundlePath, "config.json")
assert.True(katautils.FileExists(ociConfigFile)) assert.True(katautils.FileExists(ociConfigFile))
spec, err := readOCIConfigFile(ociConfigFile) spec, err := oci.ParseConfigJSON(bundlePath)
assert.NoError(err) assert.NoError(err)
// Force sandbox-type container // Force sandbox-type container
@ -535,7 +535,7 @@ func TestCreateCreateCgroupsFilesFail(t *testing.T) {
ociConfigFile := filepath.Join(bundlePath, "config.json") ociConfigFile := filepath.Join(bundlePath, "config.json")
assert.True(katautils.FileExists(ociConfigFile)) assert.True(katautils.FileExists(ociConfigFile))
spec, err := readOCIConfigFile(ociConfigFile) spec, err := oci.ParseConfigJSON(bundlePath)
assert.NoError(err) assert.NoError(err)
// Force sandbox-type container // Force sandbox-type container
@ -622,7 +622,7 @@ func TestCreateCreateCreatePidFileFail(t *testing.T) {
ociConfigFile := filepath.Join(bundlePath, "config.json") ociConfigFile := filepath.Join(bundlePath, "config.json")
assert.True(katautils.FileExists(ociConfigFile)) assert.True(katautils.FileExists(ociConfigFile))
spec, err := readOCIConfigFile(ociConfigFile) spec, err := oci.ParseConfigJSON(bundlePath)
assert.NoError(err) assert.NoError(err)
// Force sandbox-type container // Force sandbox-type container
@ -697,7 +697,7 @@ func TestCreate(t *testing.T) {
ociConfigFile := filepath.Join(bundlePath, "config.json") ociConfigFile := filepath.Join(bundlePath, "config.json")
assert.True(katautils.FileExists(ociConfigFile)) assert.True(katautils.FileExists(ociConfigFile))
spec, err := readOCIConfigFile(ociConfigFile) spec, err := oci.ParseConfigJSON(bundlePath)
assert.NoError(err) assert.NoError(err)
// Force sandbox-type container // Force sandbox-type container

View File

@ -128,22 +128,20 @@ func TestDeleteInvalidConfig(t *testing.T) {
assert.False(vcmock.IsMockError(err)) assert.False(vcmock.IsMockError(err))
} }
func testConfigSetup(t *testing.T) (rootPath string, configPath string) { func testConfigSetup(t *testing.T) (rootPath string, bundlePath string) {
assert := assert.New(t) assert := assert.New(t)
tmpdir, err := ioutil.TempDir("", "") tmpdir, err := ioutil.TempDir("", "")
assert.NoError(err) assert.NoError(err)
bundlePath := filepath.Join(tmpdir, "bundle") bundlePath = filepath.Join(tmpdir, "bundle")
err = os.MkdirAll(bundlePath, testDirMode) err = os.MkdirAll(bundlePath, testDirMode)
assert.NoError(err) assert.NoError(err)
err = createOCIConfig(bundlePath) err = createOCIConfig(bundlePath)
assert.NoError(err) assert.NoError(err)
// config json path return tmpdir, bundlePath
configPath = filepath.Join(bundlePath, "config.json")
return tmpdir, configPath
} }
func TestDeleteSandbox(t *testing.T) { func TestDeleteSandbox(t *testing.T) {
@ -153,9 +151,9 @@ func TestDeleteSandbox(t *testing.T) {
MockID: testSandboxID, MockID: testSandboxID,
} }
rootPath, configPath := testConfigSetup(t) rootPath, bundlePath := testConfigSetup(t)
defer os.RemoveAll(rootPath) defer os.RemoveAll(rootPath)
configJSON, err := readOCIConfigJSON(configPath) configJSON, err := readOCIConfigJSON(bundlePath)
assert.NoError(err) assert.NoError(err)
path, err := createTempContainerIDMapping(sandbox.ID(), sandbox.ID()) path, err := createTempContainerIDMapping(sandbox.ID(), sandbox.ID())
@ -231,9 +229,9 @@ func TestDeleteInvalidContainerType(t *testing.T) {
MockID: testSandboxID, MockID: testSandboxID,
} }
rootPath, configPath := testConfigSetup(t) rootPath, bundlePath := testConfigSetup(t)
defer os.RemoveAll(rootPath) defer os.RemoveAll(rootPath)
configJSON, err := readOCIConfigJSON(configPath) configJSON, err := readOCIConfigJSON(bundlePath)
assert.NoError(err) assert.NoError(err)
path, err := createTempContainerIDMapping(sandbox.ID(), sandbox.ID()) path, err := createTempContainerIDMapping(sandbox.ID(), sandbox.ID())
@ -270,9 +268,9 @@ func TestDeleteSandboxRunning(t *testing.T) {
MockID: testSandboxID, MockID: testSandboxID,
} }
rootPath, configPath := testConfigSetup(t) rootPath, bundlePath := testConfigSetup(t)
defer os.RemoveAll(rootPath) defer os.RemoveAll(rootPath)
configJSON, err := readOCIConfigJSON(configPath) configJSON, err := readOCIConfigJSON(bundlePath)
assert.NoError(err) assert.NoError(err)
path, err := createTempContainerIDMapping(sandbox.ID(), sandbox.ID()) path, err := createTempContainerIDMapping(sandbox.ID(), sandbox.ID())
@ -350,9 +348,9 @@ func TestDeleteRunningContainer(t *testing.T) {
}, },
} }
rootPath, configPath := testConfigSetup(t) rootPath, bundlePath := testConfigSetup(t)
defer os.RemoveAll(rootPath) defer os.RemoveAll(rootPath)
configJSON, err := readOCIConfigJSON(configPath) configJSON, err := readOCIConfigJSON(bundlePath)
assert.NoError(err) assert.NoError(err)
path, err := createTempContainerIDMapping(sandbox.MockContainers[0].ID(), sandbox.MockContainers[0].ID()) path, err := createTempContainerIDMapping(sandbox.MockContainers[0].ID(), sandbox.MockContainers[0].ID())
@ -433,9 +431,9 @@ func TestDeleteContainer(t *testing.T) {
}, },
} }
rootPath, configPath := testConfigSetup(t) rootPath, bundlePath := testConfigSetup(t)
defer os.RemoveAll(rootPath) defer os.RemoveAll(rootPath)
configJSON, err := readOCIConfigJSON(configPath) configJSON, err := readOCIConfigJSON(bundlePath)
assert.NoError(err) assert.NoError(err)
path, err := createTempContainerIDMapping(sandbox.MockContainers[0].ID(), sandbox.MockContainers[0].ID()) path, err := createTempContainerIDMapping(sandbox.MockContainers[0].ID(), sandbox.MockContainers[0].ID())
@ -533,9 +531,9 @@ func TestDeleteCLIFunctionSuccess(t *testing.T) {
}, },
} }
rootPath, configPath := testConfigSetup(t) rootPath, bundlePath := testConfigSetup(t)
defer os.RemoveAll(rootPath) defer os.RemoveAll(rootPath)
configJSON, err := readOCIConfigJSON(configPath) configJSON, err := readOCIConfigJSON(bundlePath)
assert.NoError(err) assert.NoError(err)
path, err := createTempContainerIDMapping(sandbox.ID(), sandbox.ID()) path, err := createTempContainerIDMapping(sandbox.ID(), sandbox.ID())

View File

@ -23,7 +23,7 @@ import (
) )
type execParams struct { type execParams struct {
ociProcess oci.CompatOCIProcess ociProcess specs.Process
cID string cID string
pidFile string pidFile string
console string console string
@ -119,7 +119,7 @@ EXAMPLE:
}, },
} }
func generateExecParams(context *cli.Context, specProcess *oci.CompatOCIProcess) (execParams, error) { func generateExecParams(context *cli.Context, specProcess *specs.Process) (execParams, error) {
ctxArgs := context.Args() ctxArgs := context.Args()
params := execParams{ params := execParams{
@ -133,7 +133,7 @@ func generateExecParams(context *cli.Context, specProcess *oci.CompatOCIProcess)
} }
if context.String("process") != "" { if context.String("process") != "" {
var ociProcess oci.CompatOCIProcess var ociProcess specs.Process
fileContent, err := ioutil.ReadFile(context.String("process")) fileContent, err := ioutil.ReadFile(context.String("process"))
if err != nil { if err != nil {

View File

@ -14,13 +14,14 @@ import (
"path/filepath" "path/filepath"
"testing" "testing"
vc "github.com/kata-containers/runtime/virtcontainers" specs "github.com/opencontainers/runtime-spec/specs-go"
vcAnnotations "github.com/kata-containers/runtime/virtcontainers/pkg/annotations"
"github.com/kata-containers/runtime/virtcontainers/pkg/oci"
"github.com/kata-containers/runtime/virtcontainers/pkg/vcmock"
"github.com/kata-containers/runtime/virtcontainers/types"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/urfave/cli" "github.com/urfave/cli"
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"
) )
func TestExecCLIFunction(t *testing.T) { func TestExecCLIFunction(t *testing.T) {
@ -90,9 +91,9 @@ func TestExecuteErrors(t *testing.T) {
assert.False(vcmock.IsMockError(err)) assert.False(vcmock.IsMockError(err))
// Container state undefined // Container state undefined
rootPath, configPath := testConfigSetup(t) rootPath, bundlePath := testConfigSetup(t)
defer os.RemoveAll(rootPath) defer os.RemoveAll(rootPath)
configJSON, err := readOCIConfigJSON(configPath) configJSON, err := readOCIConfigJSON(bundlePath)
assert.NoError(err) assert.NoError(err)
annotations = map[string]string{ annotations = map[string]string{
@ -149,9 +150,9 @@ func TestExecuteErrorReadingProcessJson(t *testing.T) {
flagSet.Parse([]string{testContainerID}) flagSet.Parse([]string{testContainerID})
ctx := createCLIContext(flagSet) ctx := createCLIContext(flagSet)
rootPath, configPath := testConfigSetup(t) rootPath, bundlePath := testConfigSetup(t)
defer os.RemoveAll(rootPath) defer os.RemoveAll(rootPath)
configJSON, err := readOCIConfigJSON(configPath) configJSON, err := readOCIConfigJSON(bundlePath)
assert.NoError(err) assert.NoError(err)
annotations := map[string]string{ annotations := map[string]string{
@ -198,9 +199,9 @@ func TestExecuteErrorOpeningConsole(t *testing.T) {
flagSet.Parse([]string{testContainerID}) flagSet.Parse([]string{testContainerID})
ctx := createCLIContext(flagSet) ctx := createCLIContext(flagSet)
rootPath, configPath := testConfigSetup(t) rootPath, bundlePath := testConfigSetup(t)
defer os.RemoveAll(rootPath) defer os.RemoveAll(rootPath)
configJSON, err := readOCIConfigJSON(configPath) configJSON, err := readOCIConfigJSON(bundlePath)
assert.NoError(err) assert.NoError(err)
annotations := map[string]string{ annotations := map[string]string{
@ -265,9 +266,9 @@ func TestExecuteWithFlags(t *testing.T) {
flagSet.Parse([]string{testContainerID, "/tmp/foo"}) flagSet.Parse([]string{testContainerID, "/tmp/foo"})
ctx := createCLIContext(flagSet) ctx := createCLIContext(flagSet)
rootPath, configPath := testConfigSetup(t) rootPath, bundlePath := testConfigSetup(t)
defer os.RemoveAll(rootPath) defer os.RemoveAll(rootPath)
configJSON, err := readOCIConfigJSON(configPath) configJSON, err := readOCIConfigJSON(bundlePath)
assert.NoError(err) assert.NoError(err)
annotations := map[string]string{ annotations := map[string]string{
@ -355,9 +356,9 @@ func TestExecuteWithFlagsDetached(t *testing.T) {
flagSet.Parse([]string{testContainerID, "/tmp/foo"}) flagSet.Parse([]string{testContainerID, "/tmp/foo"})
ctx := createCLIContext(flagSet) ctx := createCLIContext(flagSet)
rootPath, configPath := testConfigSetup(t) rootPath, bundlePath := testConfigSetup(t)
defer os.RemoveAll(rootPath) defer os.RemoveAll(rootPath)
configJSON, err := readOCIConfigJSON(configPath) configJSON, err := readOCIConfigJSON(bundlePath)
assert.NoError(err) assert.NoError(err)
annotations := map[string]string{ annotations := map[string]string{
@ -434,9 +435,9 @@ func TestExecuteWithInvalidProcessJson(t *testing.T) {
flagSet.Parse([]string{testContainerID}) flagSet.Parse([]string{testContainerID})
ctx := createCLIContext(flagSet) ctx := createCLIContext(flagSet)
rootPath, configPath := testConfigSetup(t) rootPath, bundlePath := testConfigSetup(t)
defer os.RemoveAll(rootPath) defer os.RemoveAll(rootPath)
configJSON, err := readOCIConfigJSON(configPath) configJSON, err := readOCIConfigJSON(bundlePath)
assert.NoError(err) assert.NoError(err)
annotations := map[string]string{ annotations := map[string]string{
@ -486,9 +487,9 @@ func TestExecuteWithValidProcessJson(t *testing.T) {
flagSet.Parse([]string{testContainerID, "/tmp/foo"}) flagSet.Parse([]string{testContainerID, "/tmp/foo"})
ctx := createCLIContext(flagSet) ctx := createCLIContext(flagSet)
rootPath, configPath := testConfigSetup(t) rootPath, bundlePath := testConfigSetup(t)
defer os.RemoveAll(rootPath) defer os.RemoveAll(rootPath)
configJSON, err := readOCIConfigJSON(configPath) configJSON, err := readOCIConfigJSON(bundlePath)
assert.NoError(err) assert.NoError(err)
annotations := map[string]string{ annotations := map[string]string{
@ -587,9 +588,9 @@ func TestExecuteWithEmptyEnvironmentValue(t *testing.T) {
flagSet.Parse([]string{testContainerID}) flagSet.Parse([]string{testContainerID})
ctx := createCLIContext(flagSet) ctx := createCLIContext(flagSet)
rootPath, configPath := testConfigSetup(t) rootPath, bundlePath := testConfigSetup(t)
defer os.RemoveAll(rootPath) defer os.RemoveAll(rootPath)
configJSON, err := readOCIConfigJSON(configPath) configJSON, err := readOCIConfigJSON(bundlePath)
assert.NoError(err) assert.NoError(err)
annotations := map[string]string{ annotations := map[string]string{
@ -698,7 +699,7 @@ func TestGenerateExecParams(t *testing.T) {
flagSet.String("apparmor", apparmor, "") flagSet.String("apparmor", apparmor, "")
ctx := createCLIContext(flagSet) ctx := createCLIContext(flagSet)
process := &oci.CompatOCIProcess{} process := &specs.Process{}
params, err := generateExecParams(ctx, process) params, err := generateExecParams(ctx, process)
assert.NoError(err) assert.NoError(err)
@ -771,7 +772,7 @@ func TestGenerateExecParamsWithProcessJsonFile(t *testing.T) {
defer os.Remove(processPath) defer os.Remove(processPath)
process := &oci.CompatOCIProcess{} process := &specs.Process{}
params, err := generateExecParams(ctx, process) params, err := generateExecParams(ctx, process)
assert.NoError(err) assert.NoError(err)

View File

@ -150,10 +150,9 @@ func runUnitTests(m *testing.M) {
os.Exit(ret) os.Exit(ret)
} }
// Read fail that should contain a CompatOCISpec and // Read fail that should contain a specs.Spec and
// return its JSON representation on success // return its JSON representation on success
func readOCIConfigJSON(configFile string) (string, error) { func readOCIConfigJSON(bundlePath string) (string, error) {
bundlePath := filepath.Dir(configFile)
ociSpec, err := oci.ParseConfigJSON(bundlePath) ociSpec, err := oci.ParseConfigJSON(bundlePath)
if err != nil { if err != nil {
return "", nil return "", nil
@ -400,30 +399,7 @@ func makeOCIBundle(bundleDir string) error {
return nil return nil
} }
// readOCIConfig returns an OCI spec. func writeOCIConfigFile(spec specs.Spec, configPath string) error {
func readOCIConfigFile(configPath string) (oci.CompatOCISpec, error) {
if configPath == "" {
return oci.CompatOCISpec{}, errors.New("BUG: need config file path")
}
data, err := ioutil.ReadFile(configPath)
if err != nil {
return oci.CompatOCISpec{}, err
}
var ociSpec oci.CompatOCISpec
if err := json.Unmarshal(data, &ociSpec); err != nil {
return oci.CompatOCISpec{}, err
}
caps, err := oci.ContainerCapabilities(ociSpec)
if err != nil {
return oci.CompatOCISpec{}, err
}
ociSpec.Process.Capabilities = caps
return ociSpec, nil
}
func writeOCIConfigFile(spec oci.CompatOCISpec, configPath string) error {
if configPath == "" { if configPath == "" {
return errors.New("BUG: need config file path") return errors.New("BUG: need config file path")
} }

View File

@ -188,9 +188,6 @@ func testRunContainerSetup(t *testing.T) runContainerData {
err = makeOCIBundle(bundlePath) err = makeOCIBundle(bundlePath)
assert.NoError(err) assert.NoError(err)
// config json path
configPath := filepath.Join(bundlePath, specConfig)
// sandbox id and container id must be the same otherwise delete will not works // sandbox id and container id must be the same otherwise delete will not works
sandbox := &vcmock.Sandbox{ sandbox := &vcmock.Sandbox{
MockID: testContainerID, MockID: testContainerID,
@ -208,7 +205,7 @@ func testRunContainerSetup(t *testing.T) runContainerData {
runtimeConfig, err := newTestRuntimeConfig(tmpdir, consolePath, true) runtimeConfig, err := newTestRuntimeConfig(tmpdir, consolePath, true)
assert.NoError(err) assert.NoError(err)
configJSON, err := readOCIConfigJSON(configPath) configJSON, err := readOCIConfigJSON(bundlePath)
assert.NoError(err) assert.NoError(err)
return runContainerData{ return runContainerData{

View File

@ -13,13 +13,14 @@ import (
"os" "os"
"testing" "testing"
"github.com/opencontainers/runtime-spec/specs-go"
"github.com/stretchr/testify/assert"
"github.com/urfave/cli"
"github.com/kata-containers/runtime/pkg/katautils" "github.com/kata-containers/runtime/pkg/katautils"
vc "github.com/kata-containers/runtime/virtcontainers" vc "github.com/kata-containers/runtime/virtcontainers"
vcAnnotations "github.com/kata-containers/runtime/virtcontainers/pkg/annotations" vcAnnotations "github.com/kata-containers/runtime/virtcontainers/pkg/annotations"
"github.com/kata-containers/runtime/virtcontainers/pkg/oci"
"github.com/kata-containers/runtime/virtcontainers/pkg/vcmock" "github.com/kata-containers/runtime/virtcontainers/pkg/vcmock"
"github.com/stretchr/testify/assert"
"github.com/urfave/cli"
) )
func TestStartInvalidArgs(t *testing.T) { func TestStartInvalidArgs(t *testing.T) {
@ -61,7 +62,7 @@ func TestStartSandbox(t *testing.T) {
assert.NoError(err) assert.NoError(err)
defer os.RemoveAll(path) defer os.RemoveAll(path)
ociSpecJSON, err := json.Marshal(oci.CompatOCISpec{}) ociSpecJSON, err := json.Marshal(specs.Spec{})
assert.NoError(err) assert.NoError(err)
testingImpl.StatusContainerFunc = func(ctx context.Context, sandboxID, containerID string) (vc.ContainerStatus, error) { testingImpl.StatusContainerFunc = func(ctx context.Context, sandboxID, containerID string) (vc.ContainerStatus, error) {
@ -139,7 +140,7 @@ func TestStartContainerSucessFailure(t *testing.T) {
assert.NoError(err) assert.NoError(err)
defer os.RemoveAll(path) defer os.RemoveAll(path)
ociSpecJSON, err := json.Marshal(oci.CompatOCISpec{}) ociSpecJSON, err := json.Marshal(specs.Spec{})
assert.NoError(err) assert.NoError(err)
testingImpl.StatusContainerFunc = func(ctx context.Context, sandboxID, containerID string) (vc.ContainerStatus, error) { testingImpl.StatusContainerFunc = func(ctx context.Context, sandboxID, containerID string) (vc.ContainerStatus, error) {
@ -217,7 +218,7 @@ func TestStartCLIFunctionSuccess(t *testing.T) {
assert.NoError(err) assert.NoError(err)
defer os.RemoveAll(path) defer os.RemoveAll(path)
ociSpecJSON, err := json.Marshal(oci.CompatOCISpec{}) ociSpecJSON, err := json.Marshal(specs.Spec{})
assert.NoError(err) assert.NoError(err)
testingImpl.StatusContainerFunc = func(ctx context.Context, sandboxID, containerID string) (vc.ContainerStatus, error) { testingImpl.StatusContainerFunc = func(ctx context.Context, sandboxID, containerID string) (vc.ContainerStatus, error) {

View File

@ -11,15 +11,15 @@ import (
"github.com/containerd/containerd/api/types/task" "github.com/containerd/containerd/api/types/task"
"github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/errdefs"
taskAPI "github.com/containerd/containerd/runtime/v2/task" taskAPI "github.com/containerd/containerd/runtime/v2/task"
"github.com/opencontainers/runtime-spec/specs-go"
vc "github.com/kata-containers/runtime/virtcontainers" vc "github.com/kata-containers/runtime/virtcontainers"
"github.com/kata-containers/runtime/virtcontainers/pkg/oci"
) )
type container struct { type container struct {
s *service s *service
ttyio *ttyIO ttyio *ttyIO
spec *oci.CompatOCISpec spec *specs.Spec
exitTime time.Time exitTime time.Time
execs map[string]*exec execs map[string]*exec
exitIOch chan struct{} exitIOch chan struct{}
@ -35,14 +35,14 @@ type container struct {
terminal bool terminal bool
} }
func newContainer(s *service, r *taskAPI.CreateTaskRequest, containerType vc.ContainerType, spec *oci.CompatOCISpec) (*container, error) { func newContainer(s *service, r *taskAPI.CreateTaskRequest, containerType vc.ContainerType, spec *specs.Spec) (*container, error) {
if r == nil { if r == nil {
return nil, errdefs.ToGRPCf(errdefs.ErrInvalidArgument, " CreateTaskRequest points to nil") return nil, errdefs.ToGRPCf(errdefs.ErrInvalidArgument, " CreateTaskRequest points to nil")
} }
// in order to avoid deferencing a nil pointer in test // in order to avoid deferencing a nil pointer in test
if spec == nil { if spec == nil {
spec = &oci.CompatOCISpec{} spec = &specs.Spec{}
} }
c := &container{ c := &container{

View File

@ -46,7 +46,7 @@ func create(ctx context.Context, s *service, r *taskAPI.CreateTaskRequest) (*con
return nil, err return nil, err
} }
containerType, err := ociSpec.ContainerType() containerType, err := oci.ContainerType(*ociSpec)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -125,7 +125,7 @@ func create(ctx context.Context, s *service, r *taskAPI.CreateTaskRequest) (*con
return container, nil return container, nil
} }
func loadSpec(r *taskAPI.CreateTaskRequest) (*oci.CompatOCISpec, string, error) { func loadSpec(r *taskAPI.CreateTaskRequest) (*specs.Spec, string, error) {
// Checks the MUST and MUST NOT from OCI runtime specification // Checks the MUST and MUST NOT from OCI runtime specification
bundlePath, err := validBundle(r.ID, r.Bundle) bundlePath, err := validBundle(r.ID, r.Bundle)
if err != nil { if err != nil {

View File

@ -15,14 +15,14 @@ import (
"github.com/containerd/containerd/namespaces" "github.com/containerd/containerd/namespaces"
taskAPI "github.com/containerd/containerd/runtime/v2/task" taskAPI "github.com/containerd/containerd/runtime/v2/task"
specs "github.com/opencontainers/runtime-spec/specs-go"
vc "github.com/kata-containers/runtime/virtcontainers" "github.com/stretchr/testify/assert"
"github.com/kata-containers/runtime/virtcontainers/pkg/vcmock"
ktu "github.com/kata-containers/runtime/pkg/katatestutils" ktu "github.com/kata-containers/runtime/pkg/katatestutils"
"github.com/kata-containers/runtime/pkg/katautils" "github.com/kata-containers/runtime/pkg/katautils"
specs "github.com/opencontainers/runtime-spec/specs-go" vc "github.com/kata-containers/runtime/virtcontainers"
"github.com/stretchr/testify/assert" "github.com/kata-containers/runtime/virtcontainers/pkg/oci"
"github.com/kata-containers/runtime/virtcontainers/pkg/vcmock"
) )
func TestCreateSandboxSuccess(t *testing.T) { func TestCreateSandboxSuccess(t *testing.T) {
@ -62,7 +62,7 @@ func TestCreateSandboxSuccess(t *testing.T) {
ociConfigFile := filepath.Join(bundlePath, "config.json") ociConfigFile := filepath.Join(bundlePath, "config.json")
assert.True(katautils.FileExists(ociConfigFile)) assert.True(katautils.FileExists(ociConfigFile))
spec, err := readOCIConfigFile(ociConfigFile) spec, err := oci.ParseConfigJSON(bundlePath)
assert.NoError(err) assert.NoError(err)
// Force sandbox-type container // Force sandbox-type container
@ -120,7 +120,7 @@ func TestCreateSandboxFail(t *testing.T) {
ociConfigFile := filepath.Join(bundlePath, "config.json") ociConfigFile := filepath.Join(bundlePath, "config.json")
assert.True(katautils.FileExists(ociConfigFile)) assert.True(katautils.FileExists(ociConfigFile))
spec, err := readOCIConfigFile(ociConfigFile) spec, err := oci.ParseConfigJSON(bundlePath)
assert.NoError(err) assert.NoError(err)
err = writeOCIConfigFile(spec, ociConfigFile) err = writeOCIConfigFile(spec, ociConfigFile)
@ -167,7 +167,7 @@ func TestCreateSandboxConfigFail(t *testing.T) {
ociConfigFile := filepath.Join(bundlePath, "config.json") ociConfigFile := filepath.Join(bundlePath, "config.json")
assert.True(katautils.FileExists(ociConfigFile)) assert.True(katautils.FileExists(ociConfigFile))
spec, err := readOCIConfigFile(ociConfigFile) spec, err := oci.ParseConfigJSON(bundlePath)
assert.NoError(err) assert.NoError(err)
quota := int64(0) quota := int64(0)
@ -231,7 +231,7 @@ func TestCreateContainerSuccess(t *testing.T) {
ociConfigFile := filepath.Join(bundlePath, "config.json") ociConfigFile := filepath.Join(bundlePath, "config.json")
assert.True(katautils.FileExists(ociConfigFile)) assert.True(katautils.FileExists(ociConfigFile))
spec, err := readOCIConfigFile(ociConfigFile) spec, err := oci.ParseConfigJSON(bundlePath)
assert.NoError(err) assert.NoError(err)
// set expected container type and sandboxID // set expected container type and sandboxID
@ -280,7 +280,7 @@ func TestCreateContainerFail(t *testing.T) {
ociConfigFile := filepath.Join(bundlePath, "config.json") ociConfigFile := filepath.Join(bundlePath, "config.json")
assert.True(katautils.FileExists(ociConfigFile)) assert.True(katautils.FileExists(ociConfigFile))
spec, err := readOCIConfigFile(ociConfigFile) spec, err := oci.ParseConfigJSON(bundlePath)
assert.NoError(err) assert.NoError(err)
spec.Annotations = make(map[string]string) spec.Annotations = make(map[string]string)
@ -340,7 +340,7 @@ func TestCreateContainerConfigFail(t *testing.T) {
ociConfigFile := filepath.Join(bundlePath, "config.json") ociConfigFile := filepath.Join(bundlePath, "config.json")
assert.True(katautils.FileExists(ociConfigFile)) assert.True(katautils.FileExists(ociConfigFile))
spec, err := readOCIConfigFile(ociConfigFile) spec, err := oci.ParseConfigJSON(bundlePath)
assert.NoError(err) assert.NoError(err)
// set the error containerType // set the error containerType

View File

@ -13,8 +13,10 @@ import (
"testing" "testing"
taskAPI "github.com/containerd/containerd/runtime/v2/task" taskAPI "github.com/containerd/containerd/runtime/v2/task"
"github.com/kata-containers/runtime/virtcontainers/pkg/vcmock"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/kata-containers/runtime/virtcontainers/pkg/oci"
"github.com/kata-containers/runtime/virtcontainers/pkg/vcmock"
) )
func TestDeleteContainerSuccessAndFail(t *testing.T) { func TestDeleteContainerSuccessAndFail(t *testing.T) {
@ -24,9 +26,9 @@ func TestDeleteContainerSuccessAndFail(t *testing.T) {
MockID: testSandboxID, MockID: testSandboxID,
} }
rootPath, configPath := testConfigSetup(t) rootPath, bundlePath := testConfigSetup(t)
defer os.RemoveAll(rootPath) defer os.RemoveAll(rootPath)
_, err := readOCIConfigJSON(configPath) _, err := oci.ParseConfigJSON(bundlePath)
assert.NoError(err) assert.NoError(err)
s := &service{ s := &service{
@ -42,20 +44,18 @@ func TestDeleteContainerSuccessAndFail(t *testing.T) {
assert.NoError(err) assert.NoError(err)
} }
func testConfigSetup(t *testing.T) (rootPath string, configPath string) { func testConfigSetup(t *testing.T) (rootPath string, bundlePath string) {
assert := assert.New(t) assert := assert.New(t)
tmpdir, err := ioutil.TempDir("", "") tmpdir, err := ioutil.TempDir("", "")
assert.NoError(err) assert.NoError(err)
bundlePath := filepath.Join(tmpdir, "bundle") bundlePath = filepath.Join(tmpdir, "bundle")
err = os.MkdirAll(bundlePath, testDirMode) err = os.MkdirAll(bundlePath, testDirMode)
assert.NoError(err) assert.NoError(err)
err = createOCIConfig(bundlePath) err = createOCIConfig(bundlePath)
assert.NoError(err) assert.NoError(err)
// config json path return tmpdir, bundlePath
configPath = filepath.Join(bundlePath, "config.json")
return tmpdir, configPath
} }

View File

@ -296,7 +296,7 @@ func (s *service) Cleanup(ctx context.Context) (_ *taskAPI.DeleteResponse, err e
return nil, err return nil, err
} }
containerType, err := ociSpec.ContainerType() containerType, err := oci.ContainerType(ociSpec)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -308,7 +308,7 @@ func (s *service) Cleanup(ctx context.Context) (_ *taskAPI.DeleteResponse, err e
return nil, err return nil, err
} }
case vc.PodContainer: case vc.PodContainer:
sandboxID, err := ociSpec.SandboxID() sandboxID, err := oci.SandboxID(ociSpec)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -92,13 +92,13 @@ func getAddress(ctx context.Context, bundlePath, id string) (string, error) {
return "", err return "", err
} }
containerType, err := ociSpec.ContainerType() containerType, err := oci.ContainerType(ociSpec)
if err != nil { if err != nil {
return "", err return "", err
} }
if containerType == vc.PodContainer { if containerType == vc.PodContainer {
sandboxID, err := ociSpec.SandboxID() sandboxID, err := oci.SandboxID(ociSpec)
if err != nil { if err != nil {
return "", err return "", err
} }
@ -124,7 +124,7 @@ func noNeedForOutput(detach bool, tty bool) bool {
return true return true
} }
func removeNamespace(s *oci.CompatOCISpec, nsType specs.LinuxNamespaceType) { func removeNamespace(s *specs.Spec, nsType specs.LinuxNamespaceType) {
for i, n := range s.Linux.Namespaces { for i, n := range s.Linux.Namespaces {
if n.Type == nsType { if n.Type == nsType {
s.Linux.Namespaces = append(s.Linux.Namespaces[:i], s.Linux.Namespaces[i+1:]...) s.Linux.Namespaces = append(s.Linux.Namespaces[:i], s.Linux.Namespaces[i+1:]...)

View File

@ -17,6 +17,8 @@ import (
"path/filepath" "path/filepath"
"strings" "strings"
"github.com/opencontainers/runtime-spec/specs-go"
ktu "github.com/kata-containers/runtime/pkg/katatestutils" ktu "github.com/kata-containers/runtime/pkg/katatestutils"
"github.com/kata-containers/runtime/pkg/katautils" "github.com/kata-containers/runtime/pkg/katautils"
vc "github.com/kata-containers/runtime/virtcontainers" vc "github.com/kata-containers/runtime/virtcontainers"
@ -213,29 +215,6 @@ func newTestRuntimeConfig(dir, consolePath string, create bool) (oci.RuntimeConf
}, nil }, nil
} }
// readOCIConfig returns an OCI spec.
func readOCIConfigFile(configPath string) (oci.CompatOCISpec, error) {
if configPath == "" {
return oci.CompatOCISpec{}, errors.New("BUG: need config file path")
}
data, err := ioutil.ReadFile(configPath)
if err != nil {
return oci.CompatOCISpec{}, err
}
var ociSpec oci.CompatOCISpec
if err := json.Unmarshal(data, &ociSpec); err != nil {
return oci.CompatOCISpec{}, err
}
caps, err := oci.ContainerCapabilities(ociSpec)
if err != nil {
return oci.CompatOCISpec{}, err
}
ociSpec.Process.Capabilities = caps
return ociSpec, nil
}
// realMakeOCIBundle will create an OCI bundle (including the "config.json" // realMakeOCIBundle will create an OCI bundle (including the "config.json"
// config file) in the directory specified (which must already exist). // config file) in the directory specified (which must already exist).
// //
@ -336,7 +315,7 @@ func createRootfs(dir string) error {
return nil return nil
} }
func writeOCIConfigFile(spec oci.CompatOCISpec, configPath string) error { func writeOCIConfigFile(spec specs.Spec, configPath string) error {
if configPath == "" { if configPath == "" {
return errors.New("BUG: need config file path") return errors.New("BUG: need config file path")
} }
@ -348,18 +327,3 @@ func writeOCIConfigFile(spec oci.CompatOCISpec, configPath string) error {
return ioutil.WriteFile(configPath, bytes, testFileMode) return ioutil.WriteFile(configPath, bytes, testFileMode)
} }
// Read fail that should contain a CompatOCISpec and
// return its JSON representation on success
func readOCIConfigJSON(configFile string) (string, error) {
bundlePath := filepath.Dir(configFile)
ociSpec, err := oci.ParseConfigJSON(bundlePath)
if err != nil {
return "", nil
}
ociSpecJSON, err := json.Marshal(ociSpec)
if err != nil {
return "", err
}
return string(ociSpecJSON), err
}

View File

@ -13,6 +13,7 @@ import (
vc "github.com/kata-containers/runtime/virtcontainers" vc "github.com/kata-containers/runtime/virtcontainers"
vf "github.com/kata-containers/runtime/virtcontainers/factory" vf "github.com/kata-containers/runtime/virtcontainers/factory"
"github.com/kata-containers/runtime/virtcontainers/pkg/oci" "github.com/kata-containers/runtime/virtcontainers/pkg/oci"
specs "github.com/opencontainers/runtime-spec/specs-go"
) )
// GetKernelParamsFunc use a variable to allow tests to modify its value // GetKernelParamsFunc use a variable to allow tests to modify its value
@ -87,7 +88,7 @@ func HandleFactory(ctx context.Context, vci vc.VC, runtimeConfig *oci.RuntimeCon
// For the given pod ephemeral volume is created only once // For the given pod ephemeral volume is created only once
// backed by tmpfs inside the VM. For successive containers // backed by tmpfs inside the VM. For successive containers
// of the same pod the already existing volume is reused. // of the same pod the already existing volume is reused.
func SetEphemeralStorageType(ociSpec oci.CompatOCISpec) oci.CompatOCISpec { func SetEphemeralStorageType(ociSpec specs.Spec) specs.Spec {
for idx, mnt := range ociSpec.Mounts { for idx, mnt := range ociSpec.Mounts {
if vc.IsEphemeralStorage(mnt.Source) { if vc.IsEphemeralStorage(mnt.Source) {
ociSpec.Mounts[idx].Type = vc.KataEphemeralDevType ociSpec.Mounts[idx].Type = vc.KataEphemeralDevType
@ -100,7 +101,7 @@ func SetEphemeralStorageType(ociSpec oci.CompatOCISpec) oci.CompatOCISpec {
} }
// CreateSandbox create a sandbox container // CreateSandbox create a sandbox container
func CreateSandbox(ctx context.Context, vci vc.VC, ociSpec oci.CompatOCISpec, runtimeConfig oci.RuntimeConfig, rootFs vc.RootFs, func CreateSandbox(ctx context.Context, vci vc.VC, ociSpec specs.Spec, runtimeConfig oci.RuntimeConfig, rootFs vc.RootFs,
containerID, bundlePath, console string, disableOutput, systemdCgroup, builtIn bool) (_ vc.VCSandbox, _ vc.Process, err error) { containerID, bundlePath, console string, disableOutput, systemdCgroup, builtIn bool) (_ vc.VCSandbox, _ vc.Process, err error) {
span, ctx := Trace(ctx, "createSandbox") span, ctx := Trace(ctx, "createSandbox")
defer span.Finish() defer span.Finish()
@ -175,7 +176,7 @@ func CreateSandbox(ctx context.Context, vci vc.VC, ociSpec oci.CompatOCISpec, ru
} }
// CreateContainer create a container // CreateContainer create a container
func CreateContainer(ctx context.Context, vci vc.VC, sandbox vc.VCSandbox, ociSpec oci.CompatOCISpec, rootFs vc.RootFs, containerID, bundlePath, console string, disableOutput, builtIn bool) (vc.Process, error) { func CreateContainer(ctx context.Context, vci vc.VC, sandbox vc.VCSandbox, ociSpec specs.Spec, rootFs vc.RootFs, containerID, bundlePath, console string, disableOutput, builtIn bool) (vc.Process, error) {
var c vc.VCContainer var c vc.VCContainer
span, ctx := Trace(ctx, "createContainer") span, ctx := Trace(ctx, "createContainer")
@ -199,7 +200,7 @@ func CreateContainer(ctx context.Context, vci vc.VC, sandbox vc.VCSandbox, ociSp
contConfig.RootFs = rootFs contConfig.RootFs = rootFs
} }
sandboxID, err := ociSpec.SandboxID() sandboxID, err := oci.SandboxID(ociSpec)
if err != nil { if err != nil {
return vc.Process{}, err return vc.Process{}, err
} }

View File

@ -47,30 +47,7 @@ func init() {
tc = ktu.NewTestConstraint(false) tc = ktu.NewTestConstraint(false)
} }
// readOCIConfig returns an OCI spec. func writeOCIConfigFile(spec specs.Spec, configPath string) error {
func readOCIConfigFile(configPath string) (oci.CompatOCISpec, error) {
if configPath == "" {
return oci.CompatOCISpec{}, errors.New("BUG: need config file path")
}
data, err := ioutil.ReadFile(configPath)
if err != nil {
return oci.CompatOCISpec{}, err
}
var ociSpec oci.CompatOCISpec
if err := json.Unmarshal(data, &ociSpec); err != nil {
return oci.CompatOCISpec{}, err
}
caps, err := oci.ContainerCapabilities(ociSpec)
if err != nil {
return oci.CompatOCISpec{}, err
}
ociSpec.Process.Capabilities = caps
return ociSpec, nil
}
func writeOCIConfigFile(spec oci.CompatOCISpec, configPath string) error {
if configPath == "" { if configPath == "" {
return errors.New("BUG: need config file path") return errors.New("BUG: need config file path")
} }
@ -205,7 +182,7 @@ func TestSetEphemeralStorageType(t *testing.T) {
assert.Nil(err) assert.Nil(err)
defer syscall.Unmount(ephePath, 0) defer syscall.Unmount(ephePath, 0)
ociSpec := oci.CompatOCISpec{} ociSpec := specs.Spec{}
var ociMounts []specs.Mount var ociMounts []specs.Mount
mount := specs.Mount{ mount := specs.Mount{
Source: ephePath, Source: ephePath,
@ -298,7 +275,7 @@ func TestCreateSandboxConfigFail(t *testing.T) {
ociConfigFile := filepath.Join(bundlePath, "config.json") ociConfigFile := filepath.Join(bundlePath, "config.json")
assert.True(FileExists(ociConfigFile)) assert.True(FileExists(ociConfigFile))
spec, err := readOCIConfigFile(ociConfigFile) spec, err := oci.ParseConfigJSON(bundlePath)
assert.NoError(err) assert.NoError(err)
quota := int64(0) quota := int64(0)
@ -346,7 +323,7 @@ func TestCreateSandboxFail(t *testing.T) {
ociConfigFile := filepath.Join(bundlePath, "config.json") ociConfigFile := filepath.Join(bundlePath, "config.json")
assert.True(FileExists(ociConfigFile)) assert.True(FileExists(ociConfigFile))
spec, err := readOCIConfigFile(ociConfigFile) spec, err := oci.ParseConfigJSON(bundlePath)
assert.NoError(err) assert.NoError(err)
rootFs := vc.RootFs{Mounted: true} rootFs := vc.RootFs{Mounted: true}
@ -376,7 +353,7 @@ func TestCreateContainerContainerConfigFail(t *testing.T) {
ociConfigFile := filepath.Join(bundlePath, "config.json") ociConfigFile := filepath.Join(bundlePath, "config.json")
assert.True(FileExists(ociConfigFile)) assert.True(FileExists(ociConfigFile))
spec, err := readOCIConfigFile(ociConfigFile) spec, err := oci.ParseConfigJSON(bundlePath)
assert.NoError(err) assert.NoError(err)
// Set invalid container type // Set invalid container type
@ -419,7 +396,7 @@ func TestCreateContainerFail(t *testing.T) {
ociConfigFile := filepath.Join(bundlePath, "config.json") ociConfigFile := filepath.Join(bundlePath, "config.json")
assert.True(FileExists(ociConfigFile)) assert.True(FileExists(ociConfigFile))
spec, err := readOCIConfigFile(ociConfigFile) spec, err := oci.ParseConfigJSON(bundlePath)
assert.NoError(err) assert.NoError(err)
// set expected container type and sandboxID // set expected container type and sandboxID
@ -469,7 +446,7 @@ func TestCreateContainer(t *testing.T) {
ociConfigFile := filepath.Join(bundlePath, "config.json") ociConfigFile := filepath.Join(bundlePath, "config.json")
assert.True(FileExists(ociConfigFile)) assert.True(FileExists(ociConfigFile))
spec, err := readOCIConfigFile(ociConfigFile) spec, err := oci.ParseConfigJSON(bundlePath)
assert.NoError(err) assert.NoError(err)
// set expected container type and sandboxID // set expected container type and sandboxID

View File

@ -16,7 +16,6 @@ import (
"syscall" "syscall"
"time" "time"
"github.com/kata-containers/runtime/virtcontainers/pkg/oci"
"github.com/opencontainers/runtime-spec/specs-go" "github.com/opencontainers/runtime-spec/specs-go"
"github.com/opentracing/opentracing-go/log" "github.com/opentracing/opentracing-go/log"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
@ -111,7 +110,7 @@ func runHooks(ctx context.Context, hooks []specs.Hook, cid, bundlePath, hookType
} }
// PreStartHooks run the hooks before start container // PreStartHooks run the hooks before start container
func PreStartHooks(ctx context.Context, spec oci.CompatOCISpec, cid, bundlePath string) error { func PreStartHooks(ctx context.Context, spec specs.Spec, cid, bundlePath string) error {
// If no hook available, nothing needs to be done. // If no hook available, nothing needs to be done.
if spec.Hooks == nil { if spec.Hooks == nil {
return nil return nil
@ -121,7 +120,7 @@ func PreStartHooks(ctx context.Context, spec oci.CompatOCISpec, cid, bundlePath
} }
// PostStartHooks run the hooks just after start container // PostStartHooks run the hooks just after start container
func PostStartHooks(ctx context.Context, spec oci.CompatOCISpec, cid, bundlePath string) error { func PostStartHooks(ctx context.Context, spec specs.Spec, cid, bundlePath string) error {
// If no hook available, nothing needs to be done. // If no hook available, nothing needs to be done.
if spec.Hooks == nil { if spec.Hooks == nil {
return nil return nil
@ -131,7 +130,7 @@ func PostStartHooks(ctx context.Context, spec oci.CompatOCISpec, cid, bundlePath
} }
// PostStopHooks run the hooks after stop container // PostStopHooks run the hooks after stop container
func PostStopHooks(ctx context.Context, spec oci.CompatOCISpec, cid, bundlePath string) error { func PostStopHooks(ctx context.Context, spec specs.Spec, cid, bundlePath string) error {
// If no hook available, nothing needs to be done. // If no hook available, nothing needs to be done.
if spec.Hooks == nil { if spec.Hooks == nil {
return nil return nil

View File

@ -13,7 +13,6 @@ import (
ktu "github.com/kata-containers/runtime/pkg/katatestutils" ktu "github.com/kata-containers/runtime/pkg/katatestutils"
. "github.com/kata-containers/runtime/virtcontainers/pkg/mock" . "github.com/kata-containers/runtime/virtcontainers/pkg/mock"
"github.com/kata-containers/runtime/virtcontainers/pkg/oci"
"github.com/opencontainers/runtime-spec/specs-go" "github.com/opencontainers/runtime-spec/specs-go"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
@ -96,39 +95,33 @@ func TestPreStartHooks(t *testing.T) {
ctx := context.Background() ctx := context.Background()
// Hooks field is nil // Hooks field is nil
spec := oci.CompatOCISpec{} spec := specs.Spec{}
err := PreStartHooks(ctx, spec, "", "") err := PreStartHooks(ctx, spec, "", "")
assert.NoError(err) assert.NoError(err)
// Hooks list is empty // Hooks list is empty
spec = oci.CompatOCISpec{ spec = specs.Spec{
Spec: specs.Spec{
Hooks: &specs.Hooks{}, Hooks: &specs.Hooks{},
},
} }
err = PreStartHooks(ctx, spec, "", "") err = PreStartHooks(ctx, spec, "", "")
assert.NoError(err) assert.NoError(err)
// Run with timeout 0 // Run with timeout 0
hook := createHook(0) hook := createHook(0)
spec = oci.CompatOCISpec{ spec = specs.Spec{
Spec: specs.Spec{
Hooks: &specs.Hooks{ Hooks: &specs.Hooks{
Prestart: []specs.Hook{hook}, Prestart: []specs.Hook{hook},
}, },
},
} }
err = PreStartHooks(ctx, spec, testSandboxID, testBundlePath) err = PreStartHooks(ctx, spec, testSandboxID, testBundlePath)
assert.NoError(err) assert.NoError(err)
// Failure due to wrong hook // Failure due to wrong hook
hook = createWrongHook() hook = createWrongHook()
spec = oci.CompatOCISpec{ spec = specs.Spec{
Spec: specs.Spec{
Hooks: &specs.Hooks{ Hooks: &specs.Hooks{
Prestart: []specs.Hook{hook}, Prestart: []specs.Hook{hook},
}, },
},
} }
err = PreStartHooks(ctx, spec, testSandboxID, testBundlePath) err = PreStartHooks(ctx, spec, testSandboxID, testBundlePath)
assert.Error(err) assert.Error(err)
@ -144,39 +137,33 @@ func TestPostStartHooks(t *testing.T) {
ctx := context.Background() ctx := context.Background()
// Hooks field is nil // Hooks field is nil
spec := oci.CompatOCISpec{} spec := specs.Spec{}
err := PostStartHooks(ctx, spec, "", "") err := PostStartHooks(ctx, spec, "", "")
assert.NoError(err) assert.NoError(err)
// Hooks list is empty // Hooks list is empty
spec = oci.CompatOCISpec{ spec = specs.Spec{
Spec: specs.Spec{
Hooks: &specs.Hooks{}, Hooks: &specs.Hooks{},
},
} }
err = PostStartHooks(ctx, spec, "", "") err = PostStartHooks(ctx, spec, "", "")
assert.NoError(err) assert.NoError(err)
// Run with timeout 0 // Run with timeout 0
hook := createHook(0) hook := createHook(0)
spec = oci.CompatOCISpec{ spec = specs.Spec{
Spec: specs.Spec{
Hooks: &specs.Hooks{ Hooks: &specs.Hooks{
Poststart: []specs.Hook{hook}, Poststart: []specs.Hook{hook},
}, },
},
} }
err = PostStartHooks(ctx, spec, testSandboxID, testBundlePath) err = PostStartHooks(ctx, spec, testSandboxID, testBundlePath)
assert.NoError(err) assert.NoError(err)
// Failure due to wrong hook // Failure due to wrong hook
hook = createWrongHook() hook = createWrongHook()
spec = oci.CompatOCISpec{ spec = specs.Spec{
Spec: specs.Spec{
Hooks: &specs.Hooks{ Hooks: &specs.Hooks{
Poststart: []specs.Hook{hook}, Poststart: []specs.Hook{hook},
}, },
},
} }
err = PostStartHooks(ctx, spec, testSandboxID, testBundlePath) err = PostStartHooks(ctx, spec, testSandboxID, testBundlePath)
assert.Error(err) assert.Error(err)
@ -192,39 +179,33 @@ func TestPostStopHooks(t *testing.T) {
ctx := context.Background() ctx := context.Background()
// Hooks field is nil // Hooks field is nil
spec := oci.CompatOCISpec{} spec := specs.Spec{}
err := PostStopHooks(ctx, spec, "", "") err := PostStopHooks(ctx, spec, "", "")
assert.NoError(err) assert.NoError(err)
// Hooks list is empty // Hooks list is empty
spec = oci.CompatOCISpec{ spec = specs.Spec{
Spec: specs.Spec{
Hooks: &specs.Hooks{}, Hooks: &specs.Hooks{},
},
} }
err = PostStopHooks(ctx, spec, "", "") err = PostStopHooks(ctx, spec, "", "")
assert.NoError(err) assert.NoError(err)
// Run with timeout 0 // Run with timeout 0
hook := createHook(0) hook := createHook(0)
spec = oci.CompatOCISpec{ spec = specs.Spec{
Spec: specs.Spec{
Hooks: &specs.Hooks{ Hooks: &specs.Hooks{
Poststop: []specs.Hook{hook}, Poststop: []specs.Hook{hook},
}, },
},
} }
err = PostStopHooks(ctx, spec, testSandboxID, testBundlePath) err = PostStopHooks(ctx, spec, testSandboxID, testBundlePath)
assert.NoError(err) assert.NoError(err)
// Failure due to wrong hook // Failure due to wrong hook
hook = createWrongHook() hook = createWrongHook()
spec = oci.CompatOCISpec{ spec = specs.Spec{
Spec: specs.Spec{
Hooks: &specs.Hooks{ Hooks: &specs.Hooks{
Poststop: []specs.Hook{hook}, Poststop: []specs.Hook{hook},
}, },
},
} }
err = PostStopHooks(ctx, spec, testSandboxID, testBundlePath) err = PostStopHooks(ctx, spec, testSandboxID, testBundlePath)
assert.Error(err) assert.Error(err)

View File

@ -18,7 +18,7 @@ import (
criContainerdAnnotations "github.com/containerd/cri-containerd/pkg/annotations" criContainerdAnnotations "github.com/containerd/cri-containerd/pkg/annotations"
crioAnnotations "github.com/cri-o/cri-o/pkg/annotations" crioAnnotations "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/sirupsen/logrus" "github.com/sirupsen/logrus"
vc "github.com/kata-containers/runtime/virtcontainers" vc "github.com/kata-containers/runtime/virtcontainers"
@ -75,24 +75,24 @@ const (
const KernelModulesSeparator = ";" const KernelModulesSeparator = ";"
// CompatOCIProcess is a structure inheriting from spec.Process defined // compatOCIProcess is a structure inheriting from specs.Process defined
// in runtime-spec/specs-go package. The goal is to be compatible with // 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 // both v1.0.0-rc4 and v1.0.0-rc5 since the latter introduced a change
// about the type of the Capabilities field. // about the type of the Capabilities field.
// Refer to: https://github.com/opencontainers/runtime-spec/commit/37391fb // Refer to: https://github.com/opencontainers/runtime-spec/commit/37391fb
type CompatOCIProcess struct { type compatOCIProcess struct {
spec.Process specs.Process
Capabilities interface{} `json:"capabilities,omitempty" platform:"linux"` //nolint:govet Capabilities interface{} `json:"capabilities,omitempty" platform:"linux"` //nolint:govet
} }
// CompatOCISpec is a structure inheriting from spec.Spec defined // compatOCISpec is a structure inheriting from specs.Spec defined
// in runtime-spec/specs-go package. It relies on the CompatOCIProcess // in runtime-spec/specs-go package. It relies on the CompatOCIProcess
// structure declared above, in order to be compatible with both // structure declared above, in order to be compatible with both
// v1.0.0-rc4 and v1.0.0-rc5. // v1.0.0-rc4 and v1.0.0-rc5.
// Refer to: https://github.com/opencontainers/runtime-spec/commit/37391fb // Refer to: https://github.com/opencontainers/runtime-spec/commit/37391fb
type CompatOCISpec struct { type compatOCISpec struct {
spec.Spec specs.Spec
Process *CompatOCIProcess `json:"process,omitempty"` //nolint:govet Process *compatOCIProcess `json:"process,omitempty"` //nolint:govet
} }
// FactoryConfig is a structure to set the VM factory configuration. // FactoryConfig is a structure to set the VM factory configuration.
@ -162,7 +162,7 @@ func SetLogger(ctx context.Context, logger *logrus.Entry) {
ociLog = logger.WithFields(fields) ociLog = logger.WithFields(fields)
} }
func cmdEnvs(spec CompatOCISpec, envs []types.EnvVar) []types.EnvVar { func cmdEnvs(spec specs.Spec, envs []types.EnvVar) []types.EnvVar {
for _, env := range spec.Process.Env { for _, env := range spec.Process.Env {
kv := strings.Split(env, "=") kv := strings.Split(env, "=")
if len(kv) < 2 { if len(kv) < 2 {
@ -179,7 +179,7 @@ func cmdEnvs(spec CompatOCISpec, envs []types.EnvVar) []types.EnvVar {
return envs return envs
} }
func newMount(m spec.Mount) vc.Mount { func newMount(m specs.Mount) vc.Mount {
return vc.Mount{ return vc.Mount{
Source: m.Source, Source: m.Source,
Destination: m.Destination, Destination: m.Destination,
@ -188,8 +188,8 @@ func newMount(m spec.Mount) vc.Mount {
} }
} }
func containerMounts(spec CompatOCISpec) []vc.Mount { func containerMounts(spec specs.Spec) []vc.Mount {
ociMounts := spec.Spec.Mounts ociMounts := spec.Mounts
if ociMounts == nil { if ociMounts == nil {
return []vc.Mount{} return []vc.Mount{}
@ -212,7 +212,7 @@ func contains(s []string, e string) bool {
return false return false
} }
func newLinuxDeviceInfo(d spec.LinuxDevice) (*config.DeviceInfo, error) { func newLinuxDeviceInfo(d specs.LinuxDevice) (*config.DeviceInfo, error) {
allowedDeviceTypes := []string{"c", "b", "u", "p"} allowedDeviceTypes := []string{"c", "b", "u", "p"}
if !contains(allowedDeviceTypes, d.Type) { if !contains(allowedDeviceTypes, d.Type) {
@ -244,8 +244,8 @@ func newLinuxDeviceInfo(d spec.LinuxDevice) (*config.DeviceInfo, error) {
return &deviceInfo, nil return &deviceInfo, nil
} }
func containerDeviceInfos(spec CompatOCISpec) ([]config.DeviceInfo, error) { func containerDeviceInfos(spec specs.Spec) ([]config.DeviceInfo, error) {
ociLinuxDevices := spec.Spec.Linux.Devices ociLinuxDevices := spec.Linux.Devices
if ociLinuxDevices == nil { if ociLinuxDevices == nil {
return []config.DeviceInfo{}, nil return []config.DeviceInfo{}, nil
@ -264,9 +264,14 @@ func containerDeviceInfos(spec CompatOCISpec) ([]config.DeviceInfo, error) {
return devices, nil return devices, nil
} }
func containerCapabilities(s CompatOCISpec) (types.LinuxCapabilities, error) { // 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 capabilities := s.Process.Capabilities
var c types.LinuxCapabilities var c specs.LinuxCapabilities
// In spec v1.0.0-rc4, capabilities was a list of strings. This was changed // In spec v1.0.0-rc4, capabilities was a list of strings. This was changed
// to an object with v1.0.0-rc5. // to an object with v1.0.0-rc5.
@ -305,7 +310,7 @@ func containerCapabilities(s CompatOCISpec) (types.LinuxCapabilities, error) {
list = append(list, str.(string)) list = append(list, str.(string))
} }
c = types.LinuxCapabilities{ c = specs.LinuxCapabilities{
Bounding: list, Bounding: list,
Effective: list, Effective: list,
Inheritable: list, Inheritable: list,
@ -322,15 +327,7 @@ func containerCapabilities(s CompatOCISpec) (types.LinuxCapabilities, error) {
return c, nil return c, nil
} }
// ContainerCapabilities return a LinuxCapabilities for virtcontainer func networkConfig(ocispec specs.Spec, config RuntimeConfig) (vc.NetworkConfig, error) {
func ContainerCapabilities(s CompatOCISpec) (types.LinuxCapabilities, error) {
if s.Process == nil {
return types.LinuxCapabilities{}, fmt.Errorf("ContainerCapabilities, Process is nil")
}
return containerCapabilities(s)
}
func networkConfig(ocispec CompatOCISpec, config RuntimeConfig) (vc.NetworkConfig, error) {
linux := ocispec.Linux linux := ocispec.Linux
if linux == nil { if linux == nil {
return vc.NetworkConfig{}, ErrNoLinux return vc.NetworkConfig{}, ErrNoLinux
@ -339,7 +336,7 @@ func networkConfig(ocispec CompatOCISpec, config RuntimeConfig) (vc.NetworkConfi
var netConf vc.NetworkConfig var netConf vc.NetworkConfig
for _, n := range linux.Namespaces { for _, n := range linux.Namespaces {
if n.Type != spec.NetworkNamespace { if n.Type != specs.NetworkNamespace {
continue continue
} }
@ -366,26 +363,29 @@ func getConfigPath(bundlePath string) string {
} }
// ParseConfigJSON unmarshals the config.json file. // ParseConfigJSON unmarshals the config.json file.
func ParseConfigJSON(bundlePath string) (CompatOCISpec, error) { func ParseConfigJSON(bundlePath string) (specs.Spec, error) {
configPath := getConfigPath(bundlePath) configPath := getConfigPath(bundlePath)
ociLog.Debugf("converting %s", configPath) ociLog.Debugf("converting %s", configPath)
configByte, err := ioutil.ReadFile(configPath) configByte, err := ioutil.ReadFile(configPath)
if err != nil { if err != nil {
return CompatOCISpec{}, err return specs.Spec{}, err
} }
var ocispec CompatOCISpec var compSpec compatOCISpec
if err := json.Unmarshal(configByte, &ocispec); err != nil { if err := json.Unmarshal(configByte, &compSpec); err != nil {
return CompatOCISpec{}, err return specs.Spec{}, err
} }
caps, err := ContainerCapabilities(ocispec)
caps, err := containerCapabilities(compSpec)
if err != nil { if err != nil {
return CompatOCISpec{}, err return specs.Spec{}, err
} }
ocispec.Process.Capabilities = caps
return ocispec, nil compSpec.Spec.Process = &compSpec.Process.Process
compSpec.Spec.Process.Capabilities = &caps
return compSpec.Spec, nil
} }
// GetContainerType determines which type of container matches the annotations // GetContainerType determines which type of container matches the annotations
@ -402,7 +402,7 @@ func GetContainerType(annotations map[string]string) (vc.ContainerType, error) {
// ContainerType returns the type of container and if the container type was // ContainerType returns the type of container and if the container type was
// found from CRI servers annotations. // found from CRI servers annotations.
func (spec *CompatOCISpec) ContainerType() (vc.ContainerType, error) { func ContainerType(spec specs.Spec) (vc.ContainerType, error) {
for _, key := range CRIContainerTypeKeyList { for _, key := range CRIContainerTypeKeyList {
containerTypeVal, ok := spec.Annotations[key] containerTypeVal, ok := spec.Annotations[key]
if !ok { if !ok {
@ -424,7 +424,7 @@ func (spec *CompatOCISpec) ContainerType() (vc.ContainerType, error) {
// SandboxID determines the sandbox ID related to an OCI configuration. This function // SandboxID determines the sandbox ID related to an OCI configuration. This function
// is expected to be called only when the container type is "PodContainer". // is expected to be called only when the container type is "PodContainer".
func (spec *CompatOCISpec) SandboxID() (string, error) { func SandboxID(spec specs.Spec) (string, error) {
for _, key := range CRISandboxNameKeyList { for _, key := range CRISandboxNameKeyList {
sandboxID, ok := spec.Annotations[key] sandboxID, ok := spec.Annotations[key]
if ok { if ok {
@ -435,7 +435,7 @@ func (spec *CompatOCISpec) SandboxID() (string, error) {
return "", fmt.Errorf("Could not find sandbox ID") return "", fmt.Errorf("Could not find sandbox ID")
} }
func addAssetAnnotations(ocispec CompatOCISpec, config *vc.SandboxConfig) { func addAssetAnnotations(ocispec specs.Spec, config *vc.SandboxConfig) {
assetAnnotations := []string{ assetAnnotations := []string{
vcAnnotations.KernelPath, vcAnnotations.KernelPath,
vcAnnotations.ImagePath, vcAnnotations.ImagePath,
@ -465,7 +465,7 @@ func addAssetAnnotations(ocispec CompatOCISpec, config *vc.SandboxConfig) {
// SandboxConfig converts an OCI compatible runtime configuration file // SandboxConfig converts an OCI compatible runtime configuration file
// to a virtcontainers sandbox configuration structure. // to a virtcontainers sandbox configuration structure.
func SandboxConfig(ocispec CompatOCISpec, runtime RuntimeConfig, bundlePath, cid, console string, detach, systemdCgroup bool) (vc.SandboxConfig, error) { func SandboxConfig(ocispec specs.Spec, runtime RuntimeConfig, bundlePath, cid, console string, detach, systemdCgroup bool) (vc.SandboxConfig, error) {
containerConfig, err := ContainerConfig(ocispec, bundlePath, cid, console, detach) containerConfig, err := ContainerConfig(ocispec, bundlePath, cid, console, detach)
if err != nil { if err != nil {
return vc.SandboxConfig{}, err return vc.SandboxConfig{}, err
@ -528,7 +528,7 @@ func SandboxConfig(ocispec CompatOCISpec, runtime RuntimeConfig, bundlePath, cid
// ContainerConfig converts an OCI compatible runtime configuration // ContainerConfig converts an OCI compatible runtime configuration
// file to a virtcontainers container configuration structure. // file to a virtcontainers container configuration structure.
func ContainerConfig(ocispec CompatOCISpec, bundlePath, cid, console string, detach bool) (vc.ContainerConfig, error) { func ContainerConfig(ocispec specs.Spec, bundlePath, cid, console string, detach bool) (vc.ContainerConfig, error) {
ociSpecJSON, err := json.Marshal(ocispec) ociSpecJSON, err := json.Marshal(ocispec)
if err != nil { if err != nil {
return vc.ContainerConfig{}, err return vc.ContainerConfig{}, err
@ -564,17 +564,13 @@ func ContainerConfig(ocispec CompatOCISpec, bundlePath, cid, console string, det
} }
if ocispec.Process != nil { if ocispec.Process != nil {
caps, ok := ocispec.Process.Capabilities.(types.LinuxCapabilities) cmd.Capabilities = ocispec.Process.Capabilities
if !ok {
return vc.ContainerConfig{}, fmt.Errorf("Unexpected format for capabilities: %v", ocispec.Process.Capabilities)
}
cmd.Capabilities = caps
} }
containerConfig := vc.ContainerConfig{ containerConfig := vc.ContainerConfig{
ID: cid, ID: cid,
RootFs: rootfs, RootFs: rootfs,
ReadonlyRootfs: ocispec.Spec.Root.Readonly, ReadonlyRootfs: ocispec.Root.Readonly,
Cmd: cmd, Cmd: cmd,
Annotations: map[string]string{ Annotations: map[string]string{
vcAnnotations.ConfigJSONKey: string(ociSpecJSON), vcAnnotations.ConfigJSONKey: string(ociSpecJSON),
@ -585,7 +581,7 @@ func ContainerConfig(ocispec CompatOCISpec, bundlePath, cid, console string, det
Resources: *ocispec.Linux.Resources, Resources: *ocispec.Linux.Resources,
} }
cType, err := ocispec.ContainerType() cType, err := ContainerType(ocispec)
if err != nil { if err != nil {
return vc.ContainerConfig{}, err return vc.ContainerConfig{}, err
} }
@ -622,9 +618,9 @@ func getShmSize(c vc.ContainerConfig) (uint64, error) {
} }
// StatusToOCIState translates a virtcontainers container status into an OCI state. // StatusToOCIState translates a virtcontainers container status into an OCI state.
func StatusToOCIState(status vc.ContainerStatus) spec.State { func StatusToOCIState(status vc.ContainerStatus) specs.State {
return spec.State{ return specs.State{
Version: spec.Version, Version: specs.Version,
ID: status.ID, ID: status.ID,
Status: StateToOCIState(status.State.State), Status: StateToOCIState(status.State.State),
Pid: status.PID, Pid: status.PID,
@ -684,15 +680,15 @@ func EnvVars(envs []string) ([]types.EnvVar, error) {
// GetOCIConfig returns an OCI spec configuration from the annotation // GetOCIConfig returns an OCI spec configuration from the annotation
// stored into the container status. // stored into the container status.
func GetOCIConfig(status vc.ContainerStatus) (CompatOCISpec, error) { func GetOCIConfig(status vc.ContainerStatus) (specs.Spec, error) {
ociConfigStr, ok := status.Annotations[vcAnnotations.ConfigJSONKey] ociConfigStr, ok := status.Annotations[vcAnnotations.ConfigJSONKey]
if !ok { if !ok {
return CompatOCISpec{}, fmt.Errorf("Annotation[%s] not found", vcAnnotations.ConfigJSONKey) return specs.Spec{}, fmt.Errorf("Annotation[%s] not found", vcAnnotations.ConfigJSONKey)
} }
var ociSpec CompatOCISpec var ociSpec specs.Spec
if err := json.Unmarshal([]byte(ociConfigStr), &ociSpec); err != nil { if err := json.Unmarshal([]byte(ociConfigStr), &ociSpec); err != nil {
return CompatOCISpec{}, err return specs.Spec{}, err
} }
return ociSpec, nil return ociSpec, nil

View File

@ -135,7 +135,7 @@ func TestMinimalSandboxConfig(t *testing.T) {
Interactive: true, Interactive: true,
Console: consolePath, Console: consolePath,
NoNewPrivileges: true, NoNewPrivileges: true,
Capabilities: types.LinuxCapabilities{ Capabilities: &specs.LinuxCapabilities{
Bounding: capList, Bounding: capList,
Effective: capList, Effective: capList,
Inheritable: capList, Inheritable: capList,
@ -168,17 +168,18 @@ func TestMinimalSandboxConfig(t *testing.T) {
}, },
} }
var minimalOCISpec CompatOCISpec var minimalOCISpec compatOCISpec
//Marshal and unmarshall json to compare sandboxConfig and expectedSandboxConfig //Marshal and unmarshall json to compare sandboxConfig and expectedSandboxConfig
err = json.Unmarshal([]byte(minimalConfig), &minimalOCISpec) err = json.Unmarshal([]byte(minimalConfig), &minimalOCISpec)
assert.NoError(err) assert.NoError(err)
if minimalOCISpec.Process != nil { if minimalOCISpec.Process != nil {
caps, err := ContainerCapabilities(minimalOCISpec) caps, err := containerCapabilities(minimalOCISpec)
assert.NoError(err) assert.NoError(err)
minimalOCISpec.Process.Capabilities = caps minimalOCISpec.Spec.Process = &minimalOCISpec.Process.Process
minimalOCISpec.Spec.Process.Capabilities = &caps
} }
ociSpecJSON, err := json.Marshal(minimalOCISpec) ociSpecJSON, err := json.Marshal(minimalOCISpec.Spec)
assert.NoError(err) assert.NoError(err)
devInfo := config.DeviceInfo{ devInfo := config.DeviceInfo{
@ -489,8 +490,8 @@ func TestGetContainerTypeFailure(t *testing.T) {
assert.Equal(containerType, expected) assert.Equal(containerType, expected)
} }
func testContainerTypeSuccessful(t *testing.T, ociSpec CompatOCISpec, expected vc.ContainerType) { func testContainerTypeSuccessful(t *testing.T, ociSpec specs.Spec, expected vc.ContainerType) {
containerType, err := ociSpec.ContainerType() containerType, err := ContainerType(ociSpec)
assert := assert.New(t) assert := assert.New(t)
assert.NoError(err) assert.NoError(err)
@ -498,7 +499,7 @@ func testContainerTypeSuccessful(t *testing.T, ociSpec CompatOCISpec, expected v
} }
func TestContainerTypePodSandbox(t *testing.T) { func TestContainerTypePodSandbox(t *testing.T) {
var ociSpec CompatOCISpec var ociSpec specs.Spec
ociSpec.Annotations = map[string]string{ ociSpec.Annotations = map[string]string{
annotations.ContainerType: annotations.ContainerTypeSandbox, annotations.ContainerType: annotations.ContainerTypeSandbox,
@ -508,7 +509,7 @@ func TestContainerTypePodSandbox(t *testing.T) {
} }
func TestContainerTypePodContainer(t *testing.T) { func TestContainerTypePodContainer(t *testing.T) {
var ociSpec CompatOCISpec var ociSpec specs.Spec
ociSpec.Annotations = map[string]string{ ociSpec.Annotations = map[string]string{
annotations.ContainerType: annotations.ContainerTypeContainer, annotations.ContainerType: annotations.ContainerTypeContainer,
@ -518,11 +519,11 @@ func TestContainerTypePodContainer(t *testing.T) {
} }
func TestContainerTypePodSandboxEmptyAnnotation(t *testing.T) { func TestContainerTypePodSandboxEmptyAnnotation(t *testing.T) {
testContainerTypeSuccessful(t, CompatOCISpec{}, vc.PodSandbox) testContainerTypeSuccessful(t, specs.Spec{}, vc.PodSandbox)
} }
func TestContainerTypeFailure(t *testing.T) { func TestContainerTypeFailure(t *testing.T) {
var ociSpec CompatOCISpec var ociSpec specs.Spec
expected := vc.UnknownContainerType expected := vc.UnknownContainerType
unknownType := "unknown_type" unknownType := "unknown_type"
assert := assert.New(t) assert := assert.New(t)
@ -531,13 +532,13 @@ func TestContainerTypeFailure(t *testing.T) {
annotations.ContainerType: unknownType, annotations.ContainerType: unknownType,
} }
containerType, err := ociSpec.ContainerType() containerType, err := ContainerType(ociSpec)
assert.Error(err) assert.Error(err)
assert.Equal(containerType, expected) assert.Equal(containerType, expected)
} }
func TestSandboxIDSuccessful(t *testing.T) { func TestSandboxIDSuccessful(t *testing.T) {
var ociSpec CompatOCISpec var ociSpec specs.Spec
testSandboxID := "testSandboxID" testSandboxID := "testSandboxID"
assert := assert.New(t) assert := assert.New(t)
@ -545,16 +546,16 @@ func TestSandboxIDSuccessful(t *testing.T) {
annotations.SandboxID: testSandboxID, annotations.SandboxID: testSandboxID,
} }
sandboxID, err := ociSpec.SandboxID() sandboxID, err := SandboxID(ociSpec)
assert.NoError(err) assert.NoError(err)
assert.Equal(sandboxID, testSandboxID) assert.Equal(sandboxID, testSandboxID)
} }
func TestSandboxIDFailure(t *testing.T) { func TestSandboxIDFailure(t *testing.T) {
var ociSpec CompatOCISpec var ociSpec specs.Spec
assert := assert.New(t) assert := assert.New(t)
sandboxID, err := ociSpec.SandboxID() sandboxID, err := SandboxID(ociSpec)
assert.Error(err) assert.Error(err)
assert.Empty(sandboxID) assert.Empty(sandboxID)
} }
@ -590,7 +591,7 @@ func TestAddKernelParamInvalid(t *testing.T) {
} }
func TestDeviceTypeFailure(t *testing.T) { func TestDeviceTypeFailure(t *testing.T) {
var ociSpec CompatOCISpec var ociSpec specs.Spec
invalidDeviceType := "f" invalidDeviceType := "f"
ociSpec.Linux = &specs.Linux{} ociSpec.Linux = &specs.Linux{}
@ -615,7 +616,7 @@ func TestContains(t *testing.T) {
} }
func TestDevicePathEmpty(t *testing.T) { func TestDevicePathEmpty(t *testing.T) {
var ociSpec CompatOCISpec var ociSpec specs.Spec
ociSpec.Linux = &specs.Linux{} ociSpec.Linux = &specs.Linux{}
ociSpec.Linux.Devices = []specs.LinuxDevice{ ociSpec.Linux.Devices = []specs.LinuxDevice{
@ -631,9 +632,9 @@ func TestDevicePathEmpty(t *testing.T) {
} }
func TestContainerCapabilities(t *testing.T) { func TestContainerCapabilities(t *testing.T) {
var ociSpec CompatOCISpec var ociSpec compatOCISpec
ociSpec.Process = &CompatOCIProcess{} ociSpec.Process = &compatOCIProcess{}
ociSpec.Process.Capabilities = map[string]interface{}{ ociSpec.Process.Capabilities = map[string]interface{}{
"bounding": []interface{}{"CAP_KILL"}, "bounding": []interface{}{"CAP_KILL"},
"effective": []interface{}{"CAP_KILL", "CAP_LEASE"}, "effective": []interface{}{"CAP_KILL", "CAP_LEASE"},
@ -642,7 +643,7 @@ func TestContainerCapabilities(t *testing.T) {
"ambient": []interface{}{""}, "ambient": []interface{}{""},
} }
c, err := ContainerCapabilities(ociSpec) c, err := containerCapabilities(ociSpec)
assert.Nil(t, err) assert.Nil(t, err)
assert.Equal(t, c.Bounding, []string{"CAP_KILL"}) assert.Equal(t, c.Bounding, []string{"CAP_KILL"})
assert.Equal(t, c.Effective, []string{"CAP_KILL", "CAP_LEASE"}) assert.Equal(t, c.Effective, []string{"CAP_KILL", "CAP_LEASE"})
@ -652,7 +653,7 @@ func TestContainerCapabilities(t *testing.T) {
ociSpec.Process.Capabilities = []interface{}{"CAP_LEASE", "CAP_SETUID"} ociSpec.Process.Capabilities = []interface{}{"CAP_LEASE", "CAP_SETUID"}
c, err = ContainerCapabilities(ociSpec) c, err = containerCapabilities(ociSpec)
assert.Nil(t, err) assert.Nil(t, err)
assert.Equal(t, c.Bounding, []string{"CAP_LEASE", "CAP_SETUID"}) assert.Equal(t, c.Bounding, []string{"CAP_LEASE", "CAP_SETUID"})
assert.Equal(t, c.Effective, []string{"CAP_LEASE", "CAP_SETUID"}) assert.Equal(t, c.Effective, []string{"CAP_LEASE", "CAP_SETUID"})
@ -662,7 +663,7 @@ func TestContainerCapabilities(t *testing.T) {
ociSpec.Process.Capabilities = nil ociSpec.Process.Capabilities = nil
c, err = ContainerCapabilities(ociSpec) c, err = containerCapabilities(ociSpec)
assert.Nil(t, err) assert.Nil(t, err)
assert.Equal(t, c.Bounding, []string(nil)) assert.Equal(t, c.Bounding, []string(nil))
assert.Equal(t, c.Effective, []string(nil)) assert.Equal(t, c.Effective, []string(nil))
@ -673,9 +674,9 @@ func TestContainerCapabilities(t *testing.T) {
// use specs.Spec to decode the spec, the content of capabilities is [] string // use specs.Spec to decode the spec, the content of capabilities is [] string
func TestCompatOCISpecWithArray(t *testing.T) { func TestCompatOCISpecWithArray(t *testing.T) {
compatOCISpec := CompatOCISpec{} compatOCISpec := compatOCISpec{}
err := json.Unmarshal([]byte(capabilitiesSpecArray), &compatOCISpec) err := json.Unmarshal([]byte(capabilitiesSpecArray), &compatOCISpec)
assert.Nil(t, err, "use CompatOCISpec to decode capabilitiesSpecArray failed") assert.Nil(t, err, "use compatOCISpec to decode capabilitiesSpecArray failed")
ociSpecJSON, err := json.Marshal(compatOCISpec) ociSpecJSON, err := json.Marshal(compatOCISpec)
assert.Nil(t, err, "encode compatOCISpec failed") assert.Nil(t, err, "encode compatOCISpec failed")
@ -686,7 +687,7 @@ func TestCompatOCISpecWithArray(t *testing.T) {
err = json.Unmarshal(ociSpecJSON, &ociSpec) err = json.Unmarshal(ociSpecJSON, &ociSpec)
assert.NotNil(t, err, "This test should fail") assert.NotNil(t, err, "This test should fail")
caps, err := ContainerCapabilities(compatOCISpec) caps, err := containerCapabilities(compatOCISpec)
assert.Nil(t, err, "decode capabilities failed") assert.Nil(t, err, "decode capabilities failed")
compatOCISpec.Process.Capabilities = caps compatOCISpec.Process.Capabilities = caps
@ -700,9 +701,9 @@ func TestCompatOCISpecWithArray(t *testing.T) {
// use specs.Spec to decode the spec, the content of capabilities is struct // use specs.Spec to decode the spec, the content of capabilities is struct
func TestCompatOCISpecWithStruct(t *testing.T) { func TestCompatOCISpecWithStruct(t *testing.T) {
compatOCISpec := CompatOCISpec{} compatOCISpec := compatOCISpec{}
err := json.Unmarshal([]byte(capabilitiesSpecStruct), &compatOCISpec) err := json.Unmarshal([]byte(capabilitiesSpecStruct), &compatOCISpec)
assert.Nil(t, err, "use CompatOCISpec to decode capabilitiesSpecStruct failed") assert.Nil(t, err, "use compatOCISpec to decode capabilitiesSpecStruct failed")
ociSpecJSON, err := json.Marshal(compatOCISpec) ociSpecJSON, err := json.Marshal(compatOCISpec)
assert.Nil(t, err, "encode compatOCISpec failed") assert.Nil(t, err, "encode compatOCISpec failed")
@ -810,10 +811,8 @@ func TestAddAssetAnnotations(t *testing.T) {
AgentConfig: vc.KataAgentConfig{}, AgentConfig: vc.KataAgentConfig{},
} }
ocispec := CompatOCISpec{ ocispec := spec.Spec{
Spec: spec.Spec{
Annotations: expectedAnnotations, Annotations: expectedAnnotations,
},
} }
addAssetAnnotations(ocispec, &config) addAssetAnnotations(ocispec, &config)

View File

@ -8,6 +8,8 @@ package types
import ( import (
"fmt" "fmt"
"strings" "strings"
"github.com/opencontainers/runtime-spec/specs-go"
) )
// StateString is a string representing a sandbox state. // StateString is a string representing a sandbox state.
@ -225,21 +227,6 @@ type EnvVar struct {
Value string Value string
} }
// LinuxCapabilities specify the capabilities to keep when executing
// the process inside the container.
type LinuxCapabilities struct {
// Bounding is the set of capabilities checked by the kernel.
Bounding []string
// Effective is the set of capabilities checked by the kernel.
Effective []string
// Inheritable is the capabilities preserved across execve.
Inheritable []string
// Permitted is the limiting superset for effective capabilities.
Permitted []string
// Ambient is the ambient set of capabilities that are kept.
Ambient []string
}
// Cmd represents a command to execute in a running container. // Cmd represents a command to execute in a running container.
type Cmd struct { type Cmd struct {
Args []string Args []string
@ -272,7 +259,7 @@ type Cmd struct {
PrimaryGroup string PrimaryGroup string
WorkDir string WorkDir string
Console string Console string
Capabilities LinuxCapabilities Capabilities *specs.LinuxCapabilities
Interactive bool Interactive bool
Detach bool Detach bool