mirror of
https://github.com/aljazceru/kata-containers.git
synced 2025-12-25 10:04:20 +01:00
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>
724 lines
18 KiB
Go
724 lines
18 KiB
Go
// Copyright (c) 2017 Intel Corporation
|
|
//
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
//
|
|
|
|
package main
|
|
|
|
import (
|
|
"context"
|
|
"flag"
|
|
"fmt"
|
|
"io/ioutil"
|
|
"os"
|
|
"path/filepath"
|
|
"regexp"
|
|
"testing"
|
|
|
|
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/vcmock"
|
|
specs "github.com/opencontainers/runtime-spec/specs-go"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/urfave/cli"
|
|
)
|
|
|
|
const (
|
|
testPID = 100
|
|
testConsole = "/dev/pts/999"
|
|
testContainerTypeAnnotation = "io.kubernetes.cri-o.ContainerType"
|
|
testContainerTypeSandbox = "sandbox"
|
|
testContainerTypeContainer = "container"
|
|
)
|
|
|
|
var (
|
|
testStrPID = fmt.Sprintf("%d", testPID)
|
|
ctrsMapTreePath = "/var/run/kata-containers/containers-mapping"
|
|
)
|
|
|
|
func TestCreatePIDFileSuccessful(t *testing.T) {
|
|
pidDirPath, err := ioutil.TempDir(testDir, "pid-path-")
|
|
if err != nil {
|
|
t.Fatalf("Could not create temporary PID directory: %s", err)
|
|
}
|
|
|
|
pidFilePath := filepath.Join(pidDirPath, "pid-file-path")
|
|
if err := createPIDFile(context.Background(), pidFilePath, testPID); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
fileBytes, err := ioutil.ReadFile(pidFilePath)
|
|
if err != nil {
|
|
os.RemoveAll(pidFilePath)
|
|
t.Fatalf("Could not read %q: %s", pidFilePath, err)
|
|
}
|
|
|
|
if string(fileBytes) != testStrPID {
|
|
os.RemoveAll(pidFilePath)
|
|
t.Fatalf("PID %s read from %q different from expected PID %s", string(fileBytes), pidFilePath, testStrPID)
|
|
}
|
|
|
|
os.RemoveAll(pidFilePath)
|
|
}
|
|
|
|
func TestCreatePIDFileEmptyPathSuccessful(t *testing.T) {
|
|
file := ""
|
|
if err := createPIDFile(context.Background(), file, testPID); err != nil {
|
|
t.Fatalf("This test should not fail (pidFilePath %q, pid %d)", file, testPID)
|
|
}
|
|
}
|
|
|
|
func TestCreatePIDFileUnableToRemove(t *testing.T) {
|
|
if tc.NotValid(ktu.NeedNonRoot()) {
|
|
// The os.FileMode(0000) trick doesn't work for root.
|
|
t.Skip(ktu.TestDisabledNeedNonRoot)
|
|
}
|
|
|
|
assert := assert.New(t)
|
|
|
|
tmpdir, err := ioutil.TempDir("", "")
|
|
assert.NoError(err)
|
|
defer os.RemoveAll(tmpdir)
|
|
|
|
subdir := filepath.Join(tmpdir, "dir")
|
|
file := filepath.Join(subdir, "pidfile")
|
|
|
|
// stop non-root user from removing the directory later
|
|
err = os.MkdirAll(subdir, os.FileMode(0000))
|
|
assert.NoError(err)
|
|
|
|
err = createPIDFile(context.Background(), file, testPID)
|
|
assert.Error(err)
|
|
|
|
// let it be deleted
|
|
os.Chmod(subdir, testDirMode)
|
|
}
|
|
|
|
func TestCreatePIDFileUnableToCreate(t *testing.T) {
|
|
assert := assert.New(t)
|
|
|
|
tmpdir, err := ioutil.TempDir("", "")
|
|
assert.NoError(err)
|
|
defer os.RemoveAll(tmpdir)
|
|
|
|
subdir := filepath.Join(tmpdir, "dir")
|
|
file := filepath.Join(subdir, "pidfile")
|
|
|
|
err = createPIDFile(context.Background(), file, testPID)
|
|
|
|
// subdir doesn't exist
|
|
assert.Error(err)
|
|
os.Chmod(subdir, testDirMode)
|
|
}
|
|
|
|
func TestCreateCLIFunctionNoRuntimeConfig(t *testing.T) {
|
|
assert := assert.New(t)
|
|
|
|
ctx := createCLIContext(nil)
|
|
ctx.App.Name = "foo"
|
|
ctx.App.Metadata["foo"] = "bar"
|
|
|
|
fn, ok := createCLICommand.Action.(func(context *cli.Context) error)
|
|
assert.True(ok)
|
|
|
|
err := fn(ctx)
|
|
|
|
// no runtime config in the Metadata
|
|
assert.Error(err)
|
|
}
|
|
|
|
func TestCreateCLIFunctionSetupConsoleFail(t *testing.T) {
|
|
assert := assert.New(t)
|
|
|
|
tmpdir, err := ioutil.TempDir("", "")
|
|
assert.NoError(err)
|
|
defer os.RemoveAll(tmpdir)
|
|
|
|
runtimeConfig, err := newTestRuntimeConfig(tmpdir, testConsole, true)
|
|
assert.NoError(err)
|
|
|
|
subdir := filepath.Join(tmpdir, "dir")
|
|
|
|
// does not exist
|
|
consoleSocketPath := filepath.Join(subdir, "console")
|
|
|
|
set := flag.NewFlagSet("", 0)
|
|
|
|
set.String("console-socket", consoleSocketPath, "")
|
|
|
|
ctx := createCLIContext(set)
|
|
ctx.App.Name = "foo"
|
|
|
|
ctx.App.Metadata["runtimeConfig"] = runtimeConfig
|
|
|
|
fn, ok := createCLICommand.Action.(func(context *cli.Context) error)
|
|
assert.True(ok)
|
|
|
|
err = fn(ctx)
|
|
|
|
// failed to setup console
|
|
assert.Error(err)
|
|
}
|
|
|
|
func TestCreateCLIFunctionCreateFail(t *testing.T) {
|
|
assert := assert.New(t)
|
|
|
|
tmpdir, err := ioutil.TempDir("", "")
|
|
assert.NoError(err)
|
|
defer os.RemoveAll(tmpdir)
|
|
|
|
runtimeConfig, err := newTestRuntimeConfig(tmpdir, testConsole, true)
|
|
assert.NoError(err)
|
|
|
|
set := flag.NewFlagSet("", 0)
|
|
|
|
set.String("console-socket", "", "")
|
|
|
|
ctx := createCLIContext(set)
|
|
ctx.App.Name = "foo"
|
|
|
|
ctx.App.Metadata["runtimeConfig"] = runtimeConfig
|
|
|
|
fn, ok := createCLICommand.Action.(func(context *cli.Context) error)
|
|
assert.True(ok)
|
|
|
|
err = fn(ctx)
|
|
|
|
// create() failed
|
|
assert.Error(err)
|
|
}
|
|
|
|
func TestCreateInvalidArgs(t *testing.T) {
|
|
assert := assert.New(t)
|
|
|
|
sandbox := &vcmock.Sandbox{
|
|
MockID: testSandboxID,
|
|
MockContainers: []*vcmock.Container{
|
|
{MockID: testContainerID},
|
|
{MockID: testContainerID},
|
|
{MockID: testContainerID},
|
|
},
|
|
}
|
|
|
|
testingImpl.CreateSandboxFunc = func(ctx context.Context, sandboxConfig vc.SandboxConfig) (vc.VCSandbox, error) {
|
|
return sandbox, nil
|
|
}
|
|
|
|
path, err := ioutil.TempDir("", "containers-mapping")
|
|
assert.NoError(err)
|
|
defer os.RemoveAll(path)
|
|
ctrsMapTreePath = path
|
|
katautils.SetCtrsMapTreePath(ctrsMapTreePath)
|
|
|
|
defer func() {
|
|
testingImpl.CreateSandboxFunc = nil
|
|
}()
|
|
|
|
tmpdir, err := ioutil.TempDir("", "")
|
|
assert.NoError(err)
|
|
defer os.RemoveAll(tmpdir)
|
|
|
|
runtimeConfig, err := newTestRuntimeConfig(tmpdir, testConsole, true)
|
|
assert.NoError(err)
|
|
|
|
bundlePath := filepath.Join(tmpdir, "bundle")
|
|
|
|
err = makeOCIBundle(bundlePath)
|
|
assert.NoError(err)
|
|
|
|
pidFilePath := filepath.Join(tmpdir, "pidfile.txt")
|
|
|
|
type testData struct {
|
|
containerID string
|
|
bundlePath string
|
|
console string
|
|
pidFilePath string
|
|
detach bool
|
|
systemdCgroup bool
|
|
runtimeConfig oci.RuntimeConfig
|
|
}
|
|
|
|
data := []testData{
|
|
{"", "", "", "", false, false, oci.RuntimeConfig{}},
|
|
{"", "", "", "", true, true, oci.RuntimeConfig{}},
|
|
{"foo", "", "", "", true, false, oci.RuntimeConfig{}},
|
|
{testContainerID, bundlePath, testConsole, pidFilePath, false, false, runtimeConfig},
|
|
{testContainerID, bundlePath, testConsole, pidFilePath, true, true, runtimeConfig},
|
|
}
|
|
|
|
for i, d := range data {
|
|
err := create(context.Background(), d.containerID, d.bundlePath, d.console, d.pidFilePath, d.detach, d.systemdCgroup, d.runtimeConfig)
|
|
assert.Errorf(err, "test %d (%+v)", i, d)
|
|
}
|
|
}
|
|
|
|
func TestCreateInvalidConfigJSON(t *testing.T) {
|
|
assert := assert.New(t)
|
|
|
|
path, err := ioutil.TempDir("", "containers-mapping")
|
|
assert.NoError(err)
|
|
defer os.RemoveAll(path)
|
|
ctrsMapTreePath = path
|
|
katautils.SetCtrsMapTreePath(ctrsMapTreePath)
|
|
|
|
tmpdir, err := ioutil.TempDir("", "")
|
|
assert.NoError(err)
|
|
defer os.RemoveAll(tmpdir)
|
|
|
|
runtimeConfig, err := newTestRuntimeConfig(tmpdir, testConsole, true)
|
|
assert.NoError(err)
|
|
|
|
bundlePath := filepath.Join(tmpdir, "bundle")
|
|
|
|
err = makeOCIBundle(bundlePath)
|
|
assert.NoError(err)
|
|
|
|
pidFilePath := filepath.Join(tmpdir, "pidfile.txt")
|
|
|
|
ociConfigFile := filepath.Join(bundlePath, "config.json")
|
|
assert.True(katautils.FileExists(ociConfigFile))
|
|
|
|
f, err := os.OpenFile(ociConfigFile, os.O_APPEND|os.O_WRONLY, testFileMode)
|
|
assert.NoError(err)
|
|
|
|
// invalidate the JSON
|
|
_, err = f.WriteString("{")
|
|
assert.NoError(err)
|
|
f.Close()
|
|
|
|
for detach := range []bool{true, false} {
|
|
err := create(context.Background(), testContainerID, bundlePath, testConsole, pidFilePath, true, true, runtimeConfig)
|
|
assert.Errorf(err, "%+v", detach)
|
|
assert.False(vcmock.IsMockError(err))
|
|
os.RemoveAll(path)
|
|
}
|
|
}
|
|
|
|
func TestCreateInvalidContainerType(t *testing.T) {
|
|
assert := assert.New(t)
|
|
|
|
path, err := ioutil.TempDir("", "containers-mapping")
|
|
assert.NoError(err)
|
|
defer os.RemoveAll(path)
|
|
ctrsMapTreePath = path
|
|
katautils.SetCtrsMapTreePath(ctrsMapTreePath)
|
|
|
|
tmpdir, err := ioutil.TempDir("", "")
|
|
assert.NoError(err)
|
|
defer os.RemoveAll(tmpdir)
|
|
|
|
runtimeConfig, err := newTestRuntimeConfig(tmpdir, testConsole, true)
|
|
assert.NoError(err)
|
|
|
|
bundlePath := filepath.Join(tmpdir, "bundle")
|
|
|
|
err = makeOCIBundle(bundlePath)
|
|
assert.NoError(err)
|
|
|
|
pidFilePath := filepath.Join(tmpdir, "pidfile.txt")
|
|
|
|
ociConfigFile := filepath.Join(bundlePath, "config.json")
|
|
assert.True(katautils.FileExists(ociConfigFile))
|
|
|
|
spec, err := oci.ParseConfigJSON(bundlePath)
|
|
assert.NoError(err)
|
|
|
|
// Force an invalid container type
|
|
spec.Annotations = make(map[string]string)
|
|
spec.Annotations[testContainerTypeAnnotation] = "I-am-not-a-valid-container-type"
|
|
|
|
// rewrite the file
|
|
err = writeOCIConfigFile(spec, ociConfigFile)
|
|
assert.NoError(err)
|
|
|
|
for detach := range []bool{true, false} {
|
|
err := create(context.Background(), testContainerID, bundlePath, testConsole, pidFilePath, true, true, runtimeConfig)
|
|
assert.Errorf(err, "%+v", detach)
|
|
assert.False(vcmock.IsMockError(err))
|
|
os.RemoveAll(path)
|
|
}
|
|
}
|
|
|
|
func TestCreateContainerInvalid(t *testing.T) {
|
|
assert := assert.New(t)
|
|
|
|
path, err := ioutil.TempDir("", "containers-mapping")
|
|
assert.NoError(err)
|
|
defer os.RemoveAll(path)
|
|
ctrsMapTreePath = path
|
|
katautils.SetCtrsMapTreePath(ctrsMapTreePath)
|
|
|
|
tmpdir, err := ioutil.TempDir("", "")
|
|
assert.NoError(err)
|
|
defer os.RemoveAll(tmpdir)
|
|
|
|
runtimeConfig, err := newTestRuntimeConfig(tmpdir, testConsole, true)
|
|
assert.NoError(err)
|
|
|
|
bundlePath := filepath.Join(tmpdir, "bundle")
|
|
|
|
err = makeOCIBundle(bundlePath)
|
|
assert.NoError(err)
|
|
|
|
pidFilePath := filepath.Join(tmpdir, "pidfile.txt")
|
|
|
|
ociConfigFile := filepath.Join(bundlePath, "config.json")
|
|
assert.True(katautils.FileExists(ociConfigFile))
|
|
|
|
spec, err := oci.ParseConfigJSON(bundlePath)
|
|
|
|
assert.NoError(err)
|
|
|
|
// Force createContainer() to be called.
|
|
spec.Annotations = make(map[string]string)
|
|
spec.Annotations[testContainerTypeAnnotation] = testContainerTypeContainer
|
|
|
|
// rewrite the file
|
|
err = writeOCIConfigFile(spec, ociConfigFile)
|
|
assert.NoError(err)
|
|
|
|
for detach := range []bool{true, false} {
|
|
err := create(context.Background(), testContainerID, bundlePath, testConsole, pidFilePath, true, true, runtimeConfig)
|
|
assert.Errorf(err, "%+v", detach)
|
|
assert.False(vcmock.IsMockError(err))
|
|
os.RemoveAll(path)
|
|
}
|
|
}
|
|
|
|
func TestCreateProcessCgroupsPathSuccessful(t *testing.T) {
|
|
if tc.NotValid(ktu.NeedRoot()) {
|
|
t.Skip(ktu.TestDisabledNeedRoot)
|
|
}
|
|
|
|
assert := assert.New(t)
|
|
|
|
sandbox := &vcmock.Sandbox{
|
|
MockID: testSandboxID,
|
|
MockContainers: []*vcmock.Container{
|
|
{MockID: testContainerID},
|
|
},
|
|
}
|
|
|
|
path, err := ioutil.TempDir("", "containers-mapping")
|
|
assert.NoError(err)
|
|
defer os.RemoveAll(path)
|
|
ctrsMapTreePath = path
|
|
katautils.SetCtrsMapTreePath(ctrsMapTreePath)
|
|
|
|
testingImpl.CreateSandboxFunc = func(ctx context.Context, sandboxConfig vc.SandboxConfig) (vc.VCSandbox, error) {
|
|
return sandbox, nil
|
|
}
|
|
|
|
defer func() {
|
|
testingImpl.CreateSandboxFunc = nil
|
|
}()
|
|
|
|
tmpdir, err := ioutil.TempDir("", "")
|
|
assert.NoError(err)
|
|
defer os.RemoveAll(tmpdir)
|
|
|
|
runtimeConfig, err := newTestRuntimeConfig(tmpdir, testConsole, true)
|
|
assert.NoError(err)
|
|
|
|
bundlePath := filepath.Join(tmpdir, "bundle")
|
|
|
|
err = makeOCIBundle(bundlePath)
|
|
assert.NoError(err)
|
|
|
|
pidFilePath := filepath.Join(tmpdir, "pidfile.txt")
|
|
|
|
ociConfigFile := filepath.Join(bundlePath, "config.json")
|
|
assert.True(katautils.FileExists(ociConfigFile))
|
|
|
|
spec, err := oci.ParseConfigJSON(bundlePath)
|
|
assert.NoError(err)
|
|
|
|
// Force sandbox-type container
|
|
spec.Annotations = make(map[string]string)
|
|
spec.Annotations[testContainerTypeAnnotation] = testContainerTypeSandbox
|
|
|
|
// Set a limit to ensure processCgroupsPath() considers the
|
|
// cgroup part of the spec
|
|
limit := int64(1024 * 1024)
|
|
spec.Linux.Resources.Memory = &specs.LinuxMemory{
|
|
Limit: &limit,
|
|
}
|
|
|
|
// Set an absolute path
|
|
spec.Linux.CgroupsPath = "/this/is/a/cgroup/path"
|
|
|
|
var mounts []specs.Mount
|
|
foundMount := false
|
|
|
|
// Replace the standard cgroup destination with a temporary one.
|
|
for _, mount := range spec.Mounts {
|
|
if mount.Type == "cgroup" {
|
|
foundMount = true
|
|
cgroupDir, err := ioutil.TempDir("", "cgroup")
|
|
assert.NoError(err)
|
|
|
|
defer os.RemoveAll(cgroupDir)
|
|
mount.Destination = cgroupDir
|
|
}
|
|
|
|
mounts = append(mounts, mount)
|
|
}
|
|
|
|
assert.True(foundMount)
|
|
|
|
// Replace mounts with the newly created one.
|
|
spec.Mounts = mounts
|
|
|
|
// Rewrite the file
|
|
err = writeOCIConfigFile(spec, ociConfigFile)
|
|
assert.NoError(err)
|
|
|
|
err = create(context.Background(), testContainerID, "", testConsole, pidFilePath, false, true, runtimeConfig)
|
|
assert.Error(err, "bundle path not set")
|
|
|
|
re := regexp.MustCompile("config.json.*no such file or directory")
|
|
matches := re.FindAllStringSubmatch(err.Error(), -1)
|
|
assert.NotEmpty(matches)
|
|
|
|
for _, detach := range []bool{true, false} {
|
|
err := create(context.Background(), testContainerID, bundlePath, testConsole, pidFilePath, detach, true, runtimeConfig)
|
|
assert.NoError(err, "detached: %+v", detach)
|
|
os.RemoveAll(path)
|
|
}
|
|
}
|
|
|
|
func TestCreateCreateCgroupsFilesFail(t *testing.T) {
|
|
if tc.NotValid(ktu.NeedNonRoot()) {
|
|
// The os.FileMode(0000) trick doesn't work for root.
|
|
t.Skip(ktu.TestDisabledNeedNonRoot)
|
|
}
|
|
|
|
assert := assert.New(t)
|
|
|
|
sandbox := &vcmock.Sandbox{
|
|
MockID: testSandboxID,
|
|
MockContainers: []*vcmock.Container{
|
|
{MockID: testContainerID},
|
|
},
|
|
}
|
|
|
|
path, err := ioutil.TempDir("", "containers-mapping")
|
|
assert.NoError(err)
|
|
defer os.RemoveAll(path)
|
|
ctrsMapTreePath = path
|
|
katautils.SetCtrsMapTreePath(ctrsMapTreePath)
|
|
|
|
testingImpl.CreateSandboxFunc = func(ctx context.Context, sandboxConfig vc.SandboxConfig) (vc.VCSandbox, error) {
|
|
return sandbox, nil
|
|
}
|
|
|
|
defer func() {
|
|
testingImpl.CreateSandboxFunc = nil
|
|
}()
|
|
|
|
tmpdir, err := ioutil.TempDir("", "")
|
|
assert.NoError(err)
|
|
defer os.RemoveAll(tmpdir)
|
|
|
|
runtimeConfig, err := newTestRuntimeConfig(tmpdir, testConsole, true)
|
|
assert.NoError(err)
|
|
|
|
bundlePath := filepath.Join(tmpdir, "bundle")
|
|
|
|
err = makeOCIBundle(bundlePath)
|
|
assert.NoError(err)
|
|
|
|
pidFilePath := filepath.Join(tmpdir, "pidfile.txt")
|
|
|
|
ociConfigFile := filepath.Join(bundlePath, "config.json")
|
|
assert.True(katautils.FileExists(ociConfigFile))
|
|
|
|
spec, err := oci.ParseConfigJSON(bundlePath)
|
|
assert.NoError(err)
|
|
|
|
// Force sandbox-type container
|
|
spec.Annotations = make(map[string]string)
|
|
spec.Annotations[testContainerTypeAnnotation] = testContainerTypeSandbox
|
|
|
|
// Set a limit to ensure processCgroupsPath() considers the
|
|
// cgroup part of the spec
|
|
limit := int64(1024 * 1024)
|
|
spec.Linux.Resources.Memory = &specs.LinuxMemory{
|
|
Limit: &limit,
|
|
}
|
|
|
|
// Override
|
|
cgroupsDirPath = filepath.Join(tmpdir, "cgroups")
|
|
err = os.MkdirAll(cgroupsDirPath, testDirMode)
|
|
assert.NoError(err)
|
|
|
|
// Set a relative path
|
|
spec.Linux.CgroupsPath = "./a/relative/path"
|
|
|
|
dir := filepath.Join(cgroupsDirPath, "memory")
|
|
|
|
// Stop directory from being created
|
|
err = os.MkdirAll(dir, os.FileMode(0000))
|
|
assert.NoError(err)
|
|
|
|
// Rewrite the file
|
|
err = writeOCIConfigFile(spec, ociConfigFile)
|
|
assert.NoError(err)
|
|
|
|
for detach := range []bool{true, false} {
|
|
err := create(context.Background(), testContainerID, bundlePath, testConsole, pidFilePath, true, true, runtimeConfig)
|
|
assert.Errorf(err, "%+v", detach)
|
|
assert.False(vcmock.IsMockError(err))
|
|
os.RemoveAll(path)
|
|
}
|
|
}
|
|
|
|
func TestCreateCreateCreatePidFileFail(t *testing.T) {
|
|
if tc.NotValid(ktu.NeedNonRoot()) {
|
|
// The os.FileMode(0000) trick doesn't work for root.
|
|
t.Skip(ktu.TestDisabledNeedNonRoot)
|
|
}
|
|
|
|
assert := assert.New(t)
|
|
|
|
sandbox := &vcmock.Sandbox{
|
|
MockID: testSandboxID,
|
|
MockContainers: []*vcmock.Container{
|
|
{MockID: testContainerID},
|
|
},
|
|
}
|
|
|
|
path, err := ioutil.TempDir("", "containers-mapping")
|
|
assert.NoError(err)
|
|
defer os.RemoveAll(path)
|
|
ctrsMapTreePath = path
|
|
katautils.SetCtrsMapTreePath(ctrsMapTreePath)
|
|
|
|
testingImpl.CreateSandboxFunc = func(ctx context.Context, sandboxConfig vc.SandboxConfig) (vc.VCSandbox, error) {
|
|
return sandbox, nil
|
|
}
|
|
|
|
defer func() {
|
|
testingImpl.CreateSandboxFunc = nil
|
|
}()
|
|
|
|
tmpdir, err := ioutil.TempDir("", "")
|
|
assert.NoError(err)
|
|
defer os.RemoveAll(tmpdir)
|
|
|
|
runtimeConfig, err := newTestRuntimeConfig(tmpdir, testConsole, true)
|
|
assert.NoError(err)
|
|
|
|
bundlePath := filepath.Join(tmpdir, "bundle")
|
|
|
|
err = makeOCIBundle(bundlePath)
|
|
assert.NoError(err)
|
|
|
|
pidDir := filepath.Join(tmpdir, "pid")
|
|
pidFilePath := filepath.Join(pidDir, "pidfile.txt")
|
|
|
|
ociConfigFile := filepath.Join(bundlePath, "config.json")
|
|
assert.True(katautils.FileExists(ociConfigFile))
|
|
|
|
spec, err := oci.ParseConfigJSON(bundlePath)
|
|
assert.NoError(err)
|
|
|
|
// Force sandbox-type container
|
|
spec.Annotations = make(map[string]string)
|
|
spec.Annotations[testContainerTypeAnnotation] = testContainerTypeSandbox
|
|
|
|
// Set a limit to ensure processCgroupsPath() considers the
|
|
// cgroup part of the spec
|
|
limit := int64(1024 * 1024)
|
|
spec.Linux.Resources.Memory = &specs.LinuxMemory{
|
|
Limit: &limit,
|
|
}
|
|
|
|
// Rewrite the file
|
|
err = writeOCIConfigFile(spec, ociConfigFile)
|
|
assert.NoError(err)
|
|
|
|
// stop the pidfile from being created
|
|
err = os.MkdirAll(pidDir, os.FileMode(0000))
|
|
assert.NoError(err)
|
|
|
|
for detach := range []bool{true, false} {
|
|
err := create(context.Background(), testContainerID, bundlePath, testConsole, pidFilePath, true, true, runtimeConfig)
|
|
assert.Errorf(err, "%+v", detach)
|
|
assert.False(vcmock.IsMockError(err))
|
|
os.RemoveAll(path)
|
|
}
|
|
}
|
|
|
|
func TestCreate(t *testing.T) {
|
|
if tc.NotValid(ktu.NeedRoot()) {
|
|
t.Skip(ktu.TestDisabledNeedRoot)
|
|
}
|
|
|
|
assert := assert.New(t)
|
|
|
|
sandbox := &vcmock.Sandbox{
|
|
MockID: testSandboxID,
|
|
MockContainers: []*vcmock.Container{
|
|
{MockID: testContainerID},
|
|
},
|
|
}
|
|
|
|
path, err := ioutil.TempDir("", "containers-mapping")
|
|
assert.NoError(err)
|
|
defer os.RemoveAll(path)
|
|
ctrsMapTreePath = path
|
|
katautils.SetCtrsMapTreePath(ctrsMapTreePath)
|
|
|
|
testingImpl.CreateSandboxFunc = func(ctx context.Context, sandboxConfig vc.SandboxConfig) (vc.VCSandbox, error) {
|
|
return sandbox, nil
|
|
}
|
|
|
|
defer func() {
|
|
testingImpl.CreateSandboxFunc = nil
|
|
}()
|
|
|
|
tmpdir, err := ioutil.TempDir("", "")
|
|
assert.NoError(err)
|
|
defer os.RemoveAll(tmpdir)
|
|
|
|
runtimeConfig, err := newTestRuntimeConfig(tmpdir, testConsole, true)
|
|
assert.NoError(err)
|
|
|
|
bundlePath := filepath.Join(tmpdir, "bundle")
|
|
|
|
err = makeOCIBundle(bundlePath)
|
|
assert.NoError(err)
|
|
|
|
pidFilePath := filepath.Join(tmpdir, "pidfile.txt")
|
|
|
|
ociConfigFile := filepath.Join(bundlePath, "config.json")
|
|
assert.True(katautils.FileExists(ociConfigFile))
|
|
|
|
spec, err := oci.ParseConfigJSON(bundlePath)
|
|
assert.NoError(err)
|
|
|
|
// Force sandbox-type container
|
|
spec.Annotations = make(map[string]string)
|
|
spec.Annotations[testContainerTypeAnnotation] = testContainerTypeSandbox
|
|
|
|
// Set a limit to ensure processCgroupsPath() considers the
|
|
// cgroup part of the spec
|
|
limit := int64(1024 * 1024)
|
|
spec.Linux.Resources.Memory = &specs.LinuxMemory{
|
|
Limit: &limit,
|
|
}
|
|
|
|
// Rewrite the file
|
|
err = writeOCIConfigFile(spec, ociConfigFile)
|
|
assert.NoError(err)
|
|
|
|
for detach := range []bool{true, false} {
|
|
err := create(context.Background(), testContainerID, bundlePath, testConsole, pidFilePath, true, true, runtimeConfig)
|
|
assert.NoError(err, "%+v", detach)
|
|
os.RemoveAll(path)
|
|
}
|
|
}
|