mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-09-29 04:25:40 +00:00
Fixes: #2023 We can get OCI spec config from bundle instead of annotations, so this field isn't necessary. Signed-off-by: Wei Zhang <weizhang555.zw@gmail.com>
725 lines
19 KiB
Go
725 lines
19 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/compatoci"
|
|
"github.com/kata-containers/runtime/virtcontainers/pkg/oci"
|
|
"github.com/kata-containers/runtime/virtcontainers/pkg/vcmock"
|
|
specs "github.com/opencontainers/runtime-spec/specs-go"
|
|
"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 := compatoci.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 := compatoci.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 := compatoci.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 := compatoci.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 := compatoci.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 := compatoci.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)
|
|
}
|
|
}
|