mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-05-01 13:14:33 +00:00
runtime: optimize test code
This PR includes these optimize changes: - Remove the dependency on the container engine. The old code uses runc to generate config.json and Docker to export rootfs, that will be heavy and need additional dependency. Using a fixed config for busybox image can avoid the heavy processing above. - Moved duplicate code to pkg/katatestutils package Fixes: #2752 Signed-off-by: bin <bin@hyper.sh>
This commit is contained in:
parent
41c49a7bf5
commit
273a1a9ac6
@ -30,9 +30,6 @@ import (
|
|||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
)
|
)
|
||||||
|
|
||||||
// specConfig is the name of the file holding the containers configuration
|
|
||||||
const specConfig = "config.json"
|
|
||||||
|
|
||||||
// arch is the architecture for the running program
|
// arch is the architecture for the running program
|
||||||
const arch = goruntime.GOARCH
|
const arch = goruntime.GOARCH
|
||||||
|
|
||||||
|
@ -13,7 +13,6 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
|
||||||
"path"
|
"path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"regexp"
|
"regexp"
|
||||||
@ -22,9 +21,7 @@ import (
|
|||||||
|
|
||||||
ktu "github.com/kata-containers/kata-containers/src/runtime/pkg/katatestutils"
|
ktu "github.com/kata-containers/kata-containers/src/runtime/pkg/katatestutils"
|
||||||
"github.com/kata-containers/kata-containers/src/runtime/pkg/katautils"
|
"github.com/kata-containers/kata-containers/src/runtime/pkg/katautils"
|
||||||
"github.com/kata-containers/kata-containers/src/runtime/pkg/utils"
|
|
||||||
vc "github.com/kata-containers/kata-containers/src/runtime/virtcontainers"
|
vc "github.com/kata-containers/kata-containers/src/runtime/virtcontainers"
|
||||||
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/compatoci"
|
|
||||||
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/oci"
|
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/oci"
|
||||||
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/vcmock"
|
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/vcmock"
|
||||||
specs "github.com/opencontainers/runtime-spec/specs-go"
|
specs "github.com/opencontainers/runtime-spec/specs-go"
|
||||||
@ -38,19 +35,12 @@ const (
|
|||||||
testFileMode = os.FileMode(0640)
|
testFileMode = os.FileMode(0640)
|
||||||
testExeFileMode = os.FileMode(0750)
|
testExeFileMode = os.FileMode(0750)
|
||||||
|
|
||||||
// small docker image used to create root filesystems from
|
|
||||||
testDockerImage = "busybox"
|
|
||||||
|
|
||||||
testBundle = "bundle"
|
|
||||||
testConsole = "/dev/pts/999"
|
testConsole = "/dev/pts/999"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// package variables set by calling TestMain()
|
// package variables set by calling TestMain()
|
||||||
testDir = ""
|
tc ktu.TestConstraint
|
||||||
testBundleDir = ""
|
|
||||||
tc ktu.TestConstraint
|
|
||||||
ctrEngine = katautils.CtrEngine{}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// testingImpl is a concrete mock RVC implementation used for testing
|
// testingImpl is a concrete mock RVC implementation used for testing
|
||||||
@ -79,57 +69,6 @@ func init() {
|
|||||||
fmt.Printf("INFO: switching to fake virtcontainers implementation for testing\n")
|
fmt.Printf("INFO: switching to fake virtcontainers implementation for testing\n")
|
||||||
vci = testingImpl
|
vci = testingImpl
|
||||||
|
|
||||||
var err error
|
|
||||||
|
|
||||||
fmt.Printf("INFO: creating test directory\n")
|
|
||||||
testDir, err = ioutil.TempDir("", fmt.Sprintf("%s-", katautils.NAME))
|
|
||||||
if err != nil {
|
|
||||||
panic(fmt.Sprintf("ERROR: failed to create test directory: %v", err))
|
|
||||||
}
|
|
||||||
fmt.Printf("INFO: test directory is %v\n", testDir)
|
|
||||||
|
|
||||||
var output string
|
|
||||||
for _, name := range katautils.DockerLikeCtrEngines {
|
|
||||||
fmt.Printf("INFO: checking for container engine: %s\n", name)
|
|
||||||
|
|
||||||
output, err = ctrEngine.Init(name)
|
|
||||||
if err == nil {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ctrEngine.Name == "" {
|
|
||||||
panic(fmt.Sprintf("ERROR: Docker-like container engine not accessible to current user: %v (error %v)",
|
|
||||||
output, err))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Do this now to avoid hitting the test timeout value due to
|
|
||||||
// slow network response.
|
|
||||||
fmt.Printf("INFO: ensuring required container image (%v) is available\n", testDockerImage)
|
|
||||||
// Only hit the network if the image doesn't exist locally
|
|
||||||
_, err = ctrEngine.Inspect(testDockerImage)
|
|
||||||
if err == nil {
|
|
||||||
fmt.Printf("INFO: container image %v already exists locally\n", testDockerImage)
|
|
||||||
} else {
|
|
||||||
fmt.Printf("INFO: pulling container image %v\n", testDockerImage)
|
|
||||||
_, err = ctrEngine.Pull(testDockerImage)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
testBundleDir = filepath.Join(testDir, testBundle)
|
|
||||||
err = os.MkdirAll(testBundleDir, testDirMode)
|
|
||||||
if err != nil {
|
|
||||||
panic(fmt.Sprintf("ERROR: failed to create bundle directory %v: %v", testBundleDir, err))
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Printf("INFO: creating OCI bundle in %v for tests to use\n", testBundleDir)
|
|
||||||
err = realMakeOCIBundle(testBundleDir)
|
|
||||||
if err != nil {
|
|
||||||
panic(fmt.Sprintf("ERROR: failed to create OCI bundle: %v", err))
|
|
||||||
}
|
|
||||||
|
|
||||||
tc = ktu.NewTestConstraint(false)
|
tc = ktu.NewTestConstraint(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -143,8 +82,6 @@ func resetCLIGlobals() {
|
|||||||
func runUnitTests(m *testing.M) {
|
func runUnitTests(m *testing.M) {
|
||||||
ret := m.Run()
|
ret := m.Run()
|
||||||
|
|
||||||
os.RemoveAll(testDir)
|
|
||||||
|
|
||||||
os.Exit(ret)
|
os.Exit(ret)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -232,146 +169,6 @@ func newTestRuntimeConfig(dir, consolePath string, create bool) (oci.RuntimeConf
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// createOCIConfig creates an OCI configuration (spec) file in
|
|
||||||
// the bundle directory specified (which must exist).
|
|
||||||
func createOCIConfig(bundleDir string) error {
|
|
||||||
if bundleDir == "" {
|
|
||||||
return errors.New("BUG: Need bundle directory")
|
|
||||||
}
|
|
||||||
|
|
||||||
if !katautils.FileExists(bundleDir) {
|
|
||||||
return fmt.Errorf("BUG: Bundle directory %s does not exist", bundleDir)
|
|
||||||
}
|
|
||||||
|
|
||||||
var configCmd string
|
|
||||||
|
|
||||||
// Search for a suitable version of runc to use to generate
|
|
||||||
// the OCI config file.
|
|
||||||
for _, cmd := range []string{"docker-runc", "runc"} {
|
|
||||||
fullPath, err := exec.LookPath(cmd)
|
|
||||||
if err == nil {
|
|
||||||
configCmd = fullPath
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if configCmd == "" {
|
|
||||||
return errors.New("Cannot find command to generate OCI config file")
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err := utils.RunCommand([]string{configCmd, "spec", "--bundle", bundleDir})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
specFile := filepath.Join(bundleDir, specConfig)
|
|
||||||
if !katautils.FileExists(specFile) {
|
|
||||||
return fmt.Errorf("generated OCI config file does not exist: %v", specFile)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// createRootfs creates a minimal root filesystem below the specified
|
|
||||||
// directory.
|
|
||||||
func createRootfs(dir string) error {
|
|
||||||
err := os.MkdirAll(dir, testDirMode)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
container, err := ctrEngine.Create(testDockerImage)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = ctrEngine.GetRootfs(container, dir)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clean up
|
|
||||||
_, err = ctrEngine.Rm(container)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// realMakeOCIBundle will create an OCI bundle (including the "config.json"
|
|
||||||
// config file) in the directory specified (which must already exist).
|
|
||||||
//
|
|
||||||
// XXX: Note that tests should *NOT* call this function - they should
|
|
||||||
// XXX: instead call makeOCIBundle().
|
|
||||||
func realMakeOCIBundle(bundleDir string) error {
|
|
||||||
if bundleDir == "" {
|
|
||||||
return errors.New("BUG: Need bundle directory")
|
|
||||||
}
|
|
||||||
|
|
||||||
if !katautils.FileExists(bundleDir) {
|
|
||||||
return fmt.Errorf("BUG: Bundle directory %v does not exist", bundleDir)
|
|
||||||
}
|
|
||||||
|
|
||||||
err := createOCIConfig(bundleDir)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Note the unusual parameter (a directory, not the config
|
|
||||||
// file to parse!)
|
|
||||||
spec, err := compatoci.ParseConfigJSON(bundleDir)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Determine the rootfs directory name the OCI config refers to
|
|
||||||
ociRootPath := spec.Root.Path
|
|
||||||
|
|
||||||
rootfsDir := filepath.Join(bundleDir, ociRootPath)
|
|
||||||
|
|
||||||
if strings.HasPrefix(ociRootPath, "/") {
|
|
||||||
return fmt.Errorf("Cannot handle absolute rootfs as bundle must be unique to each test")
|
|
||||||
}
|
|
||||||
|
|
||||||
err = createRootfs(rootfsDir)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create an OCI bundle in the specified directory.
|
|
||||||
//
|
|
||||||
// Note that the directory will be created, but it's parent is expected to exist.
|
|
||||||
//
|
|
||||||
// This function works by copying the already-created test bundle. Ideally,
|
|
||||||
// the bundle would be recreated for each test, but createRootfs() uses
|
|
||||||
// docker which on some systems is too slow, resulting in the tests timing
|
|
||||||
// out.
|
|
||||||
func makeOCIBundle(bundleDir string) error {
|
|
||||||
from := testBundleDir
|
|
||||||
to := bundleDir
|
|
||||||
|
|
||||||
// only the basename of bundleDir needs to exist as bundleDir
|
|
||||||
// will get created by cp(1).
|
|
||||||
base := filepath.Dir(bundleDir)
|
|
||||||
|
|
||||||
for _, dir := range []string{from, base} {
|
|
||||||
if !katautils.FileExists(dir) {
|
|
||||||
return fmt.Errorf("BUG: directory %v should exist", dir)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
output, err := utils.RunCommandFull([]string{"cp", "-a", from, to}, true)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("failed to copy test OCI bundle from %v to %v: %v (output: %v)", from, to, err, output)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func createCLIContextWithApp(flagSet *flag.FlagSet, app *cli.App) *cli.Context {
|
func createCLIContextWithApp(flagSet *flag.FlagSet, app *cli.App) *cli.Context {
|
||||||
ctx := cli.NewContext(app, flagSet, nil)
|
ctx := cli.NewContext(app, flagSet, nil)
|
||||||
|
|
||||||
@ -390,69 +187,6 @@ func createCLIContext(flagset *flag.FlagSet) *cli.Context {
|
|||||||
return createCLIContextWithApp(flagset, cli.NewApp())
|
return createCLIContextWithApp(flagset, cli.NewApp())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMakeOCIBundle(t *testing.T) {
|
|
||||||
assert := assert.New(t)
|
|
||||||
|
|
||||||
tmpdir, err := ioutil.TempDir(testDir, "")
|
|
||||||
assert.NoError(err)
|
|
||||||
defer os.RemoveAll(tmpdir)
|
|
||||||
|
|
||||||
bundleDir := filepath.Join(tmpdir, "bundle")
|
|
||||||
|
|
||||||
err = makeOCIBundle(bundleDir)
|
|
||||||
assert.NoError(err)
|
|
||||||
|
|
||||||
specFile := filepath.Join(bundleDir, specConfig)
|
|
||||||
assert.True(katautils.FileExists(specFile))
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestCreateOCIConfig(t *testing.T) {
|
|
||||||
assert := assert.New(t)
|
|
||||||
|
|
||||||
tmpdir, err := ioutil.TempDir(testDir, "")
|
|
||||||
assert.NoError(err)
|
|
||||||
defer os.RemoveAll(tmpdir)
|
|
||||||
|
|
||||||
bundleDir := filepath.Join(tmpdir, "bundle")
|
|
||||||
|
|
||||||
err = createOCIConfig(bundleDir)
|
|
||||||
// ENOENT
|
|
||||||
assert.Error(err)
|
|
||||||
|
|
||||||
err = os.MkdirAll(bundleDir, testDirMode)
|
|
||||||
assert.NoError(err)
|
|
||||||
|
|
||||||
err = createOCIConfig(bundleDir)
|
|
||||||
assert.NoError(err)
|
|
||||||
|
|
||||||
specFile := filepath.Join(bundleDir, specConfig)
|
|
||||||
assert.True(katautils.FileExists(specFile))
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestCreateRootfs(t *testing.T) {
|
|
||||||
assert := assert.New(t)
|
|
||||||
|
|
||||||
tmpdir, err := ioutil.TempDir(testDir, "")
|
|
||||||
assert.NoError(err)
|
|
||||||
defer os.RemoveAll(tmpdir)
|
|
||||||
|
|
||||||
rootfsDir := filepath.Join(tmpdir, "rootfs")
|
|
||||||
assert.False(katautils.FileExists(rootfsDir))
|
|
||||||
|
|
||||||
err = createRootfs(rootfsDir)
|
|
||||||
assert.NoError(err)
|
|
||||||
|
|
||||||
// non-comprehensive list of expected directories
|
|
||||||
expectedDirs := []string{"bin", "dev", "etc", "usr", "var"}
|
|
||||||
|
|
||||||
assert.True(katautils.FileExists(rootfsDir))
|
|
||||||
|
|
||||||
for _, dir := range expectedDirs {
|
|
||||||
dirPath := filepath.Join(rootfsDir, dir)
|
|
||||||
assert.True(katautils.FileExists(dirPath))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestMainUserWantsUsage(t *testing.T) {
|
func TestMainUserWantsUsage(t *testing.T) {
|
||||||
assert := assert.New(t)
|
assert := assert.New(t)
|
||||||
|
|
||||||
@ -525,7 +259,7 @@ func TestMainBeforeSubCommands(t *testing.T) {
|
|||||||
func TestMainBeforeSubCommandsInvalidLogFile(t *testing.T) {
|
func TestMainBeforeSubCommandsInvalidLogFile(t *testing.T) {
|
||||||
assert := assert.New(t)
|
assert := assert.New(t)
|
||||||
|
|
||||||
tmpdir, err := ioutil.TempDir(testDir, "")
|
tmpdir, err := ioutil.TempDir("", "katatest")
|
||||||
assert.NoError(err)
|
assert.NoError(err)
|
||||||
defer os.RemoveAll(tmpdir)
|
defer os.RemoveAll(tmpdir)
|
||||||
|
|
||||||
@ -548,7 +282,7 @@ func TestMainBeforeSubCommandsInvalidLogFile(t *testing.T) {
|
|||||||
func TestMainBeforeSubCommandsInvalidLogFormat(t *testing.T) {
|
func TestMainBeforeSubCommandsInvalidLogFormat(t *testing.T) {
|
||||||
assert := assert.New(t)
|
assert := assert.New(t)
|
||||||
|
|
||||||
tmpdir, err := ioutil.TempDir(testDir, "")
|
tmpdir, err := ioutil.TempDir("", "katatest")
|
||||||
assert.NoError(err)
|
assert.NoError(err)
|
||||||
defer os.RemoveAll(tmpdir)
|
defer os.RemoveAll(tmpdir)
|
||||||
|
|
||||||
@ -577,7 +311,7 @@ func TestMainBeforeSubCommandsInvalidLogFormat(t *testing.T) {
|
|||||||
func TestMainBeforeSubCommandsLoadConfigurationFail(t *testing.T) {
|
func TestMainBeforeSubCommandsLoadConfigurationFail(t *testing.T) {
|
||||||
assert := assert.New(t)
|
assert := assert.New(t)
|
||||||
|
|
||||||
tmpdir, err := ioutil.TempDir(testDir, "")
|
tmpdir, err := ioutil.TempDir("", "katatest")
|
||||||
assert.NoError(err)
|
assert.NoError(err)
|
||||||
defer os.RemoveAll(tmpdir)
|
defer os.RemoveAll(tmpdir)
|
||||||
|
|
||||||
@ -612,7 +346,7 @@ func TestMainBeforeSubCommandsLoadConfigurationFail(t *testing.T) {
|
|||||||
func TestMainBeforeSubCommandsShowCCConfigPaths(t *testing.T) {
|
func TestMainBeforeSubCommandsShowCCConfigPaths(t *testing.T) {
|
||||||
assert := assert.New(t)
|
assert := assert.New(t)
|
||||||
|
|
||||||
tmpdir, err := ioutil.TempDir(testDir, "")
|
tmpdir, err := ioutil.TempDir("", "katatest")
|
||||||
assert.NoError(err)
|
assert.NoError(err)
|
||||||
defer os.RemoveAll(tmpdir)
|
defer os.RemoveAll(tmpdir)
|
||||||
|
|
||||||
@ -676,7 +410,7 @@ func TestMainBeforeSubCommandsShowCCConfigPaths(t *testing.T) {
|
|||||||
func TestMainFatal(t *testing.T) {
|
func TestMainFatal(t *testing.T) {
|
||||||
assert := assert.New(t)
|
assert := assert.New(t)
|
||||||
|
|
||||||
tmpdir, err := ioutil.TempDir(testDir, "")
|
tmpdir, err := ioutil.TempDir("", "katatest")
|
||||||
assert.NoError(err)
|
assert.NoError(err)
|
||||||
defer os.RemoveAll(tmpdir)
|
defer os.RemoveAll(tmpdir)
|
||||||
|
|
||||||
@ -900,7 +634,7 @@ func TestMainCreateRuntime(t *testing.T) {
|
|||||||
func TestMainVersionPrinter(t *testing.T) {
|
func TestMainVersionPrinter(t *testing.T) {
|
||||||
assert := assert.New(t)
|
assert := assert.New(t)
|
||||||
|
|
||||||
tmpdir, err := ioutil.TempDir("", "")
|
tmpdir, err := ioutil.TempDir("", "katatest")
|
||||||
assert.NoError(err)
|
assert.NoError(err)
|
||||||
defer os.RemoveAll(tmpdir)
|
defer os.RemoveAll(tmpdir)
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestFileExists(t *testing.T) {
|
func TestFileExists(t *testing.T) {
|
||||||
dir, err := ioutil.TempDir(testDir, "")
|
dir, err := ioutil.TempDir("", "katatest")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,6 @@ import (
|
|||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
"path/filepath"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/containerd/containerd/namespaces"
|
"github.com/containerd/containerd/namespaces"
|
||||||
@ -23,7 +22,6 @@ import (
|
|||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
|
||||||
ktu "github.com/kata-containers/kata-containers/src/runtime/pkg/katatestutils"
|
ktu "github.com/kata-containers/kata-containers/src/runtime/pkg/katatestutils"
|
||||||
"github.com/kata-containers/kata-containers/src/runtime/pkg/katautils"
|
|
||||||
vc "github.com/kata-containers/kata-containers/src/runtime/virtcontainers"
|
vc "github.com/kata-containers/kata-containers/src/runtime/virtcontainers"
|
||||||
vcAnnotations "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/annotations"
|
vcAnnotations "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/annotations"
|
||||||
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/compatoci"
|
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/compatoci"
|
||||||
@ -52,21 +50,12 @@ func TestCreateSandboxSuccess(t *testing.T) {
|
|||||||
testingImpl.CreateSandboxFunc = nil
|
testingImpl.CreateSandboxFunc = nil
|
||||||
}()
|
}()
|
||||||
|
|
||||||
tmpdir, err := ioutil.TempDir("", "")
|
tmpdir, bundlePath, ociConfigFile := ktu.SetupOCIConfigFile(t)
|
||||||
assert.NoError(err)
|
// defer os.RemoveAll(tmpdir)
|
||||||
defer os.RemoveAll(tmpdir)
|
|
||||||
|
|
||||||
runtimeConfig, err := newTestRuntimeConfig(tmpdir, testConsole, true)
|
runtimeConfig, err := newTestRuntimeConfig(tmpdir, testConsole, true)
|
||||||
assert.NoError(err)
|
assert.NoError(err)
|
||||||
|
|
||||||
bundlePath := filepath.Join(tmpdir, "bundle")
|
|
||||||
|
|
||||||
err = makeOCIBundle(bundlePath)
|
|
||||||
assert.NoError(err)
|
|
||||||
|
|
||||||
ociConfigFile := filepath.Join(bundlePath, "config.json")
|
|
||||||
assert.True(katautils.FileExists(ociConfigFile))
|
|
||||||
|
|
||||||
spec, err := compatoci.ParseConfigJSON(bundlePath)
|
spec, err := compatoci.ParseConfigJSON(bundlePath)
|
||||||
assert.NoError(err)
|
assert.NoError(err)
|
||||||
|
|
||||||
@ -82,7 +71,7 @@ func TestCreateSandboxSuccess(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Rewrite the file
|
// Rewrite the file
|
||||||
err = writeOCIConfigFile(spec, ociConfigFile)
|
err = ktu.WriteOCIConfigFile(spec, ociConfigFile)
|
||||||
assert.NoError(err)
|
assert.NoError(err)
|
||||||
|
|
||||||
s := &service{
|
s := &service{
|
||||||
@ -110,25 +99,16 @@ func TestCreateSandboxFail(t *testing.T) {
|
|||||||
|
|
||||||
assert := assert.New(t)
|
assert := assert.New(t)
|
||||||
|
|
||||||
tmpdir, err := ioutil.TempDir("", "")
|
tmpdir, bundlePath, ociConfigFile := ktu.SetupOCIConfigFile(t)
|
||||||
assert.NoError(err)
|
|
||||||
defer os.RemoveAll(tmpdir)
|
defer os.RemoveAll(tmpdir)
|
||||||
|
|
||||||
runtimeConfig, err := newTestRuntimeConfig(tmpdir, testConsole, true)
|
runtimeConfig, err := newTestRuntimeConfig(tmpdir, testConsole, true)
|
||||||
assert.NoError(err)
|
assert.NoError(err)
|
||||||
|
|
||||||
bundlePath := filepath.Join(tmpdir, "bundle")
|
|
||||||
|
|
||||||
err = makeOCIBundle(bundlePath)
|
|
||||||
assert.NoError(err)
|
|
||||||
|
|
||||||
ociConfigFile := filepath.Join(bundlePath, "config.json")
|
|
||||||
assert.True(katautils.FileExists(ociConfigFile))
|
|
||||||
|
|
||||||
spec, err := compatoci.ParseConfigJSON(bundlePath)
|
spec, err := compatoci.ParseConfigJSON(bundlePath)
|
||||||
assert.NoError(err)
|
assert.NoError(err)
|
||||||
|
|
||||||
err = writeOCIConfigFile(spec, ociConfigFile)
|
err = ktu.WriteOCIConfigFile(spec, ociConfigFile)
|
||||||
assert.NoError(err)
|
assert.NoError(err)
|
||||||
|
|
||||||
s := &service{
|
s := &service{
|
||||||
@ -157,21 +137,12 @@ func TestCreateSandboxConfigFail(t *testing.T) {
|
|||||||
|
|
||||||
assert := assert.New(t)
|
assert := assert.New(t)
|
||||||
|
|
||||||
tmpdir, err := ioutil.TempDir("", "")
|
tmpdir, bundlePath, _ := ktu.SetupOCIConfigFile(t)
|
||||||
assert.NoError(err)
|
|
||||||
defer os.RemoveAll(tmpdir)
|
defer os.RemoveAll(tmpdir)
|
||||||
|
|
||||||
runtimeConfig, err := newTestRuntimeConfig(tmpdir, testConsole, true)
|
runtimeConfig, err := newTestRuntimeConfig(tmpdir, testConsole, true)
|
||||||
assert.NoError(err)
|
assert.NoError(err)
|
||||||
|
|
||||||
bundlePath := filepath.Join(tmpdir, "bundle")
|
|
||||||
|
|
||||||
err = makeOCIBundle(bundlePath)
|
|
||||||
assert.NoError(err)
|
|
||||||
|
|
||||||
ociConfigFile := filepath.Join(bundlePath, "config.json")
|
|
||||||
assert.True(katautils.FileExists(ociConfigFile))
|
|
||||||
|
|
||||||
spec, err := compatoci.ParseConfigJSON(bundlePath)
|
spec, err := compatoci.ParseConfigJSON(bundlePath)
|
||||||
assert.NoError(err)
|
assert.NoError(err)
|
||||||
|
|
||||||
@ -216,21 +187,12 @@ func TestCreateContainerSuccess(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
tmpdir, err := ioutil.TempDir("", "")
|
tmpdir, bundlePath, ociConfigFile := ktu.SetupOCIConfigFile(t)
|
||||||
assert.NoError(err)
|
|
||||||
defer os.RemoveAll(tmpdir)
|
defer os.RemoveAll(tmpdir)
|
||||||
|
|
||||||
runtimeConfig, err := newTestRuntimeConfig(tmpdir, testConsole, true)
|
runtimeConfig, err := newTestRuntimeConfig(tmpdir, testConsole, true)
|
||||||
assert.NoError(err)
|
assert.NoError(err)
|
||||||
|
|
||||||
bundlePath := filepath.Join(tmpdir, "bundle")
|
|
||||||
|
|
||||||
err = makeOCIBundle(bundlePath)
|
|
||||||
assert.NoError(err)
|
|
||||||
|
|
||||||
ociConfigFile := filepath.Join(bundlePath, "config.json")
|
|
||||||
assert.True(katautils.FileExists(ociConfigFile))
|
|
||||||
|
|
||||||
spec, err := compatoci.ParseConfigJSON(bundlePath)
|
spec, err := compatoci.ParseConfigJSON(bundlePath)
|
||||||
assert.NoError(err)
|
assert.NoError(err)
|
||||||
|
|
||||||
@ -240,7 +202,7 @@ func TestCreateContainerSuccess(t *testing.T) {
|
|||||||
spec.Annotations[testSandboxIDAnnotation] = testSandboxID
|
spec.Annotations[testSandboxIDAnnotation] = testSandboxID
|
||||||
|
|
||||||
// rewrite file
|
// rewrite file
|
||||||
err = writeOCIConfigFile(spec, ociConfigFile)
|
err = ktu.WriteOCIConfigFile(spec, ociConfigFile)
|
||||||
assert.NoError(err)
|
assert.NoError(err)
|
||||||
|
|
||||||
s := &service{
|
s := &service{
|
||||||
@ -265,21 +227,12 @@ func TestCreateContainerSuccess(t *testing.T) {
|
|||||||
func TestCreateContainerFail(t *testing.T) {
|
func TestCreateContainerFail(t *testing.T) {
|
||||||
assert := assert.New(t)
|
assert := assert.New(t)
|
||||||
|
|
||||||
tmpdir, err := ioutil.TempDir("", "")
|
tmpdir, bundlePath, ociConfigFile := ktu.SetupOCIConfigFile(t)
|
||||||
assert.NoError(err)
|
|
||||||
defer os.RemoveAll(tmpdir)
|
defer os.RemoveAll(tmpdir)
|
||||||
|
|
||||||
runtimeConfig, err := newTestRuntimeConfig(tmpdir, testConsole, true)
|
runtimeConfig, err := newTestRuntimeConfig(tmpdir, testConsole, true)
|
||||||
assert.NoError(err)
|
assert.NoError(err)
|
||||||
|
|
||||||
bundlePath := filepath.Join(tmpdir, "bundle")
|
|
||||||
|
|
||||||
err = makeOCIBundle(bundlePath)
|
|
||||||
assert.NoError(err)
|
|
||||||
|
|
||||||
ociConfigFile := filepath.Join(bundlePath, "config.json")
|
|
||||||
assert.True(katautils.FileExists(ociConfigFile))
|
|
||||||
|
|
||||||
spec, err := compatoci.ParseConfigJSON(bundlePath)
|
spec, err := compatoci.ParseConfigJSON(bundlePath)
|
||||||
assert.NoError(err)
|
assert.NoError(err)
|
||||||
|
|
||||||
@ -287,7 +240,7 @@ func TestCreateContainerFail(t *testing.T) {
|
|||||||
spec.Annotations[testContainerTypeAnnotation] = testContainerTypeContainer
|
spec.Annotations[testContainerTypeAnnotation] = testContainerTypeContainer
|
||||||
spec.Annotations[testSandboxIDAnnotation] = testSandboxID
|
spec.Annotations[testSandboxIDAnnotation] = testSandboxID
|
||||||
|
|
||||||
err = writeOCIConfigFile(spec, ociConfigFile)
|
err = ktu.WriteOCIConfigFile(spec, ociConfigFile)
|
||||||
assert.NoError(err)
|
assert.NoError(err)
|
||||||
|
|
||||||
// doesn't create sandbox first
|
// doesn't create sandbox first
|
||||||
@ -325,21 +278,12 @@ func TestCreateContainerConfigFail(t *testing.T) {
|
|||||||
sandbox.CreateContainerFunc = nil
|
sandbox.CreateContainerFunc = nil
|
||||||
}()
|
}()
|
||||||
|
|
||||||
tmpdir, err := ioutil.TempDir("", "")
|
tmpdir, bundlePath, ociConfigFile := ktu.SetupOCIConfigFile(t)
|
||||||
assert.NoError(err)
|
|
||||||
defer os.RemoveAll(tmpdir)
|
defer os.RemoveAll(tmpdir)
|
||||||
|
|
||||||
runtimeConfig, err := newTestRuntimeConfig(tmpdir, testConsole, true)
|
runtimeConfig, err := newTestRuntimeConfig(tmpdir, testConsole, true)
|
||||||
assert.NoError(err)
|
assert.NoError(err)
|
||||||
|
|
||||||
bundlePath := filepath.Join(tmpdir, "bundle")
|
|
||||||
|
|
||||||
err = makeOCIBundle(bundlePath)
|
|
||||||
assert.NoError(err)
|
|
||||||
|
|
||||||
ociConfigFile := filepath.Join(bundlePath, "config.json")
|
|
||||||
assert.True(katautils.FileExists(ociConfigFile))
|
|
||||||
|
|
||||||
spec, err := compatoci.ParseConfigJSON(bundlePath)
|
spec, err := compatoci.ParseConfigJSON(bundlePath)
|
||||||
assert.NoError(err)
|
assert.NoError(err)
|
||||||
|
|
||||||
@ -348,7 +292,7 @@ func TestCreateContainerConfigFail(t *testing.T) {
|
|||||||
spec.Annotations[testContainerTypeAnnotation] = "errorType"
|
spec.Annotations[testContainerTypeAnnotation] = "errorType"
|
||||||
spec.Annotations[testSandboxIDAnnotation] = testSandboxID
|
spec.Annotations[testSandboxIDAnnotation] = testSandboxID
|
||||||
|
|
||||||
err = writeOCIConfigFile(spec, ociConfigFile)
|
err = ktu.WriteOCIConfigFile(spec, ociConfigFile)
|
||||||
assert.NoError(err)
|
assert.NoError(err)
|
||||||
|
|
||||||
s := &service{
|
s := &service{
|
||||||
|
@ -7,14 +7,13 @@
|
|||||||
package containerdshim
|
package containerdshim
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
taskAPI "github.com/containerd/containerd/runtime/v2/task"
|
taskAPI "github.com/containerd/containerd/runtime/v2/task"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
|
||||||
|
ktu "github.com/kata-containers/kata-containers/src/runtime/pkg/katatestutils"
|
||||||
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/compatoci"
|
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/compatoci"
|
||||||
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/vcmock"
|
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/vcmock"
|
||||||
)
|
)
|
||||||
@ -26,7 +25,7 @@ func TestDeleteContainerSuccessAndFail(t *testing.T) {
|
|||||||
MockID: testSandboxID,
|
MockID: testSandboxID,
|
||||||
}
|
}
|
||||||
|
|
||||||
rootPath, bundlePath := testConfigSetup(t)
|
rootPath, bundlePath, _ := ktu.SetupOCIConfigFile(t)
|
||||||
defer os.RemoveAll(rootPath)
|
defer os.RemoveAll(rootPath)
|
||||||
_, err := compatoci.ParseConfigJSON(bundlePath)
|
_, err := compatoci.ParseConfigJSON(bundlePath)
|
||||||
assert.NoError(err)
|
assert.NoError(err)
|
||||||
@ -43,19 +42,3 @@ func TestDeleteContainerSuccessAndFail(t *testing.T) {
|
|||||||
s.containers[testContainerID], err = newContainer(s, reqCreate, "", nil, true)
|
s.containers[testContainerID], err = newContainer(s, reqCreate, "", nil, true)
|
||||||
assert.NoError(err)
|
assert.NoError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func testConfigSetup(t *testing.T) (rootPath string, bundlePath string) {
|
|
||||||
assert := assert.New(t)
|
|
||||||
|
|
||||||
tmpdir, err := ioutil.TempDir("", "")
|
|
||||||
assert.NoError(err)
|
|
||||||
|
|
||||||
bundlePath = filepath.Join(tmpdir, "bundle")
|
|
||||||
err = os.MkdirAll(bundlePath, testDirMode)
|
|
||||||
assert.NoError(err)
|
|
||||||
|
|
||||||
err = createOCIConfig(bundlePath)
|
|
||||||
assert.NoError(err)
|
|
||||||
|
|
||||||
return tmpdir, bundlePath
|
|
||||||
}
|
|
||||||
|
@ -8,9 +8,7 @@ package containerdshim
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
@ -43,13 +41,9 @@ func TestServiceCreate(t *testing.T) {
|
|||||||
|
|
||||||
assert := assert.New(t)
|
assert := assert.New(t)
|
||||||
|
|
||||||
tmpdir, _ := ioutil.TempDir("", "")
|
tmpdir, bundleDir, _ := ktu.SetupOCIConfigFile(t)
|
||||||
defer os.RemoveAll(tmpdir)
|
defer os.RemoveAll(tmpdir)
|
||||||
|
|
||||||
bundleDir := filepath.Join(tmpdir, "bundle")
|
|
||||||
err := makeOCIBundle(bundleDir)
|
|
||||||
assert.NoError(err)
|
|
||||||
|
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
|
||||||
s, err := newService("foo")
|
s, err := newService("foo")
|
||||||
|
@ -9,6 +9,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"syscall"
|
"syscall"
|
||||||
"testing"
|
"testing"
|
||||||
@ -24,6 +25,11 @@ func TestNewTtyIOFifoReopen(t *testing.T) {
|
|||||||
var tty *ttyIO
|
var tty *ttyIO
|
||||||
assert := assert.New(t)
|
assert := assert.New(t)
|
||||||
ctx := context.TODO()
|
ctx := context.TODO()
|
||||||
|
|
||||||
|
testDir, err := ioutil.TempDir("", "kata-")
|
||||||
|
assert.NoError(err)
|
||||||
|
defer os.RemoveAll(testDir)
|
||||||
|
|
||||||
fifoPath, err := ioutil.TempDir(testDir, "fifo-path-")
|
fifoPath, err := ioutil.TempDir(testDir, "fifo-path-")
|
||||||
assert.NoError(err)
|
assert.NoError(err)
|
||||||
stdout := filepath.Join(fifoPath, "stdout")
|
stdout := filepath.Join(fifoPath, "stdout")
|
||||||
@ -100,6 +106,10 @@ func TestIoCopy(t *testing.T) {
|
|||||||
testBytes2 := []byte("Test2")
|
testBytes2 := []byte("Test2")
|
||||||
testBytes3 := []byte("Test3")
|
testBytes3 := []byte("Test3")
|
||||||
|
|
||||||
|
testDir, err := ioutil.TempDir("", "kata-")
|
||||||
|
assert.NoError(err)
|
||||||
|
defer os.RemoveAll(testDir)
|
||||||
|
|
||||||
fifoPath, err := ioutil.TempDir(testDir, "fifo-path-")
|
fifoPath, err := ioutil.TempDir(testDir, "fifo-path-")
|
||||||
assert.NoError(err)
|
assert.NoError(err)
|
||||||
dstStdoutPath := filepath.Join(fifoPath, "dststdout")
|
dstStdoutPath := filepath.Join(fifoPath, "dststdout")
|
||||||
|
@ -7,46 +7,28 @@
|
|||||||
package containerdshim
|
package containerdshim
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
sysExec "os/exec"
|
|
||||||
"path"
|
"path"
|
||||||
"path/filepath"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
|
||||||
"github.com/opencontainers/runtime-spec/specs-go"
|
|
||||||
|
|
||||||
ktu "github.com/kata-containers/kata-containers/src/runtime/pkg/katatestutils"
|
ktu "github.com/kata-containers/kata-containers/src/runtime/pkg/katatestutils"
|
||||||
"github.com/kata-containers/kata-containers/src/runtime/pkg/katautils"
|
|
||||||
"github.com/kata-containers/kata-containers/src/runtime/pkg/utils"
|
|
||||||
vc "github.com/kata-containers/kata-containers/src/runtime/virtcontainers"
|
vc "github.com/kata-containers/kata-containers/src/runtime/virtcontainers"
|
||||||
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/compatoci"
|
|
||||||
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/oci"
|
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/oci"
|
||||||
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/vcmock"
|
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/vcmock"
|
||||||
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// specConf is the name of the file holding the containers configuration
|
|
||||||
specConf = "config.json"
|
|
||||||
|
|
||||||
TestID = "container_test"
|
TestID = "container_test"
|
||||||
|
|
||||||
testDirMode = os.FileMode(0750)
|
|
||||||
testFileMode = os.FileMode(0640)
|
testFileMode = os.FileMode(0640)
|
||||||
// testExeFileMode = os.FileMode(0750)
|
|
||||||
|
|
||||||
// small docker image used to create root filesystems from
|
|
||||||
testDockerImage = "busybox"
|
|
||||||
|
|
||||||
testSandboxID = "777-77-77777777"
|
testSandboxID = "777-77-77777777"
|
||||||
testContainerID = "42"
|
testContainerID = "42"
|
||||||
testBundle = "bundle"
|
|
||||||
testConsole = "/dev/pts/888"
|
testConsole = "/dev/pts/888"
|
||||||
|
|
||||||
testContainerTypeAnnotation = "io.kubernetes.cri.container-type"
|
testContainerTypeAnnotation = "io.kubernetes.cri.container-type"
|
||||||
@ -57,10 +39,7 @@ const (
|
|||||||
|
|
||||||
var (
|
var (
|
||||||
// package variables set by calling TestMain()
|
// package variables set by calling TestMain()
|
||||||
testDir = ""
|
tc ktu.TestConstraint
|
||||||
testBundleDir = ""
|
|
||||||
tc ktu.TestConstraint
|
|
||||||
ctrEngine = katautils.CtrEngine{}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// testingImpl is a concrete mock RVC implementation used for testing
|
// testingImpl is a concrete mock RVC implementation used for testing
|
||||||
@ -73,57 +52,6 @@ func init() {
|
|||||||
fmt.Printf("INFO: switching to fake virtcontainers implementation for testing\n")
|
fmt.Printf("INFO: switching to fake virtcontainers implementation for testing\n")
|
||||||
vci = testingImpl
|
vci = testingImpl
|
||||||
|
|
||||||
var err error
|
|
||||||
|
|
||||||
fmt.Printf("INFO: creating test directory\n")
|
|
||||||
testDir, err = ioutil.TempDir("", "shimV2-")
|
|
||||||
if err != nil {
|
|
||||||
panic(fmt.Sprintf("ERROR: failed to create test directory: %v", err))
|
|
||||||
}
|
|
||||||
fmt.Printf("INFO: test directory is %v\n", testDir)
|
|
||||||
|
|
||||||
var output string
|
|
||||||
for _, name := range katautils.DockerLikeCtrEngines {
|
|
||||||
fmt.Printf("INFO: checking for container engine: %s\n", name)
|
|
||||||
|
|
||||||
output, err = ctrEngine.Init(name)
|
|
||||||
if err == nil {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ctrEngine.Name == "" {
|
|
||||||
panic(fmt.Sprintf("ERROR: Docker-like container engine not accessible to current user: %v (error %v)",
|
|
||||||
output, err))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Do this now to avoid hitting the test timeout value due to
|
|
||||||
// slow network response.
|
|
||||||
fmt.Printf("INFO: ensuring required container image (%v) is available\n", testDockerImage)
|
|
||||||
// Only hit the network if the image doesn't exist locally
|
|
||||||
_, err = ctrEngine.Inspect(testDockerImage)
|
|
||||||
if err == nil {
|
|
||||||
fmt.Printf("INFO: container image %v already exists locally\n", testDockerImage)
|
|
||||||
} else {
|
|
||||||
fmt.Printf("INFO: pulling container image %v\n", testDockerImage)
|
|
||||||
_, err = ctrEngine.Pull(testDockerImage)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
testBundleDir = filepath.Join(testDir, testBundle)
|
|
||||||
err = os.MkdirAll(testBundleDir, testDirMode)
|
|
||||||
if err != nil {
|
|
||||||
panic(fmt.Sprintf("ERROR: failed to create bundle directory %v: %v", testBundleDir, err))
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Printf("INFO: creating OCI bundle in %v for tests to use\n", testBundleDir)
|
|
||||||
err = realMakeOCIBundle(testBundleDir)
|
|
||||||
if err != nil {
|
|
||||||
panic(fmt.Sprintf("ERROR: failed to create OCI bundle: %v", err))
|
|
||||||
}
|
|
||||||
|
|
||||||
tc = ktu.NewTestConstraint(false)
|
tc = ktu.NewTestConstraint(false)
|
||||||
|
|
||||||
// disable shim management server.
|
// disable shim management server.
|
||||||
@ -131,46 +59,6 @@ func init() {
|
|||||||
defaultStartManagementServerFunc = nil
|
defaultStartManagementServerFunc = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// createOCIConfig creates an OCI configuration (spec) file in
|
|
||||||
// the bundle directory specified (which must exist).
|
|
||||||
func createOCIConfig(bundleDir string) error {
|
|
||||||
if bundleDir == "" {
|
|
||||||
return errors.New("BUG: Need bundle directory")
|
|
||||||
}
|
|
||||||
|
|
||||||
if !katautils.FileExists(bundleDir) {
|
|
||||||
return fmt.Errorf("BUG: Bundle directory %s does not exist", bundleDir)
|
|
||||||
}
|
|
||||||
|
|
||||||
var configCmd string
|
|
||||||
|
|
||||||
// Search for a suitable version of runc to use to generate
|
|
||||||
// the OCI config file.
|
|
||||||
for _, cmd := range []string{"docker-runc", "runc"} {
|
|
||||||
fullPath, err := sysExec.LookPath(cmd)
|
|
||||||
if err == nil {
|
|
||||||
configCmd = fullPath
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if configCmd == "" {
|
|
||||||
return errors.New("Cannot find command to generate OCI config file")
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err := utils.RunCommand([]string{configCmd, "spec", "--bundle", bundleDir})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
specFile := filepath.Join(bundleDir, specConf)
|
|
||||||
if !katautils.FileExists(specFile) {
|
|
||||||
return fmt.Errorf("generated OCI config file does not exist: %v", specFile)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func createEmptyFile(path string) (err error) {
|
func createEmptyFile(path string) (err error) {
|
||||||
return ioutil.WriteFile(path, []byte(""), testFileMode)
|
return ioutil.WriteFile(path, []byte(""), testFileMode)
|
||||||
}
|
}
|
||||||
@ -221,119 +109,6 @@ func newTestRuntimeConfig(dir, consolePath string, create bool) (oci.RuntimeConf
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// realMakeOCIBundle will create an OCI bundle (including the "config.json"
|
|
||||||
// config file) in the directory specified (which must already exist).
|
|
||||||
//
|
|
||||||
// XXX: Note that tests should *NOT* call this function - they should
|
|
||||||
// XXX: instead call makeOCIBundle().
|
|
||||||
func realMakeOCIBundle(bundleDir string) error {
|
|
||||||
if bundleDir == "" {
|
|
||||||
return errors.New("BUG: Need bundle directory")
|
|
||||||
}
|
|
||||||
|
|
||||||
if !katautils.FileExists(bundleDir) {
|
|
||||||
return fmt.Errorf("BUG: Bundle directory %v does not exist", bundleDir)
|
|
||||||
}
|
|
||||||
|
|
||||||
err := createOCIConfig(bundleDir)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Note the unusual parameter (a directory, not the config
|
|
||||||
// file to parse!)
|
|
||||||
spec, err := compatoci.ParseConfigJSON(bundleDir)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Determine the rootfs directory name the OCI config refers to
|
|
||||||
ociRootPath := spec.Root.Path
|
|
||||||
|
|
||||||
rootfsDir := filepath.Join(bundleDir, ociRootPath)
|
|
||||||
|
|
||||||
if strings.HasPrefix(ociRootPath, "/") {
|
|
||||||
return fmt.Errorf("Cannot handle absolute rootfs as bundle must be unique to each test")
|
|
||||||
}
|
|
||||||
|
|
||||||
err = createRootfs(rootfsDir)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create an OCI bundle in the specified directory.
|
|
||||||
//
|
|
||||||
// Note that the directory will be created, but it's parent is expected to exist.
|
|
||||||
//
|
|
||||||
// This function works by copying the already-created test bundle. Ideally,
|
|
||||||
// the bundle would be recreated for each test, but createRootfs() uses
|
|
||||||
// docker which on some systems is too slow, resulting in the tests timing
|
|
||||||
// out.
|
|
||||||
func makeOCIBundle(bundleDir string) error {
|
|
||||||
from := testBundleDir
|
|
||||||
to := bundleDir
|
|
||||||
|
|
||||||
// only the basename of bundleDir needs to exist as bundleDir
|
|
||||||
// will get created by cp(1).
|
|
||||||
base := filepath.Dir(bundleDir)
|
|
||||||
|
|
||||||
for _, dir := range []string{from, base} {
|
|
||||||
if !katautils.FileExists(dir) {
|
|
||||||
return fmt.Errorf("BUG: directory %v should exist", dir)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
output, err := utils.RunCommandFull([]string{"cp", "-a", from, to}, true)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("failed to copy test OCI bundle from %v to %v: %v (output: %v)", from, to, err, output)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// createRootfs creates a minimal root filesystem below the specified
|
|
||||||
// directory.
|
|
||||||
func createRootfs(dir string) error {
|
|
||||||
err := os.MkdirAll(dir, testDirMode)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
container, err := ctrEngine.Create(testDockerImage)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = ctrEngine.GetRootfs(container, dir)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clean up
|
|
||||||
_, err = ctrEngine.Rm(container)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func writeOCIConfigFile(spec specs.Spec, configPath string) error {
|
|
||||||
if configPath == "" {
|
|
||||||
return errors.New("BUG: need config file path")
|
|
||||||
}
|
|
||||||
|
|
||||||
bytes, err := json.MarshalIndent(spec, "", "\t")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return ioutil.WriteFile(configPath, bytes, testFileMode)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestNoNeedForOutput(t *testing.T) {
|
func TestNoNeedForOutput(t *testing.T) {
|
||||||
assert := assert.New(t)
|
assert := assert.New(t)
|
||||||
|
|
||||||
|
@ -21,7 +21,6 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
testFileMode = os.FileMode(0640)
|
|
||||||
invalidOperator = 1234
|
invalidOperator = 1234
|
||||||
|
|
||||||
skipUnknownDistroName = "skipping test as cannot determine distro name"
|
skipUnknownDistroName = "skipping test as cannot determine distro name"
|
||||||
|
@ -7,8 +7,203 @@
|
|||||||
package katatestutils
|
package katatestutils
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
|
"path/filepath"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/opencontainers/runtime-spec/specs-go"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
testDirMode = os.FileMode(0750)
|
||||||
|
testFileMode = os.FileMode(0640)
|
||||||
|
|
||||||
|
busyboxConfigJson = `
|
||||||
|
{
|
||||||
|
"ociVersion": "1.0.1-dev",
|
||||||
|
"process": {
|
||||||
|
"terminal": true,
|
||||||
|
"user": {
|
||||||
|
"uid": 0,
|
||||||
|
"gid": 0
|
||||||
|
},
|
||||||
|
"args": [
|
||||||
|
"sh"
|
||||||
|
],
|
||||||
|
"env": [
|
||||||
|
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
|
||||||
|
"TERM=xterm"
|
||||||
|
],
|
||||||
|
"cwd": "/",
|
||||||
|
"capabilities": {
|
||||||
|
"bounding": [
|
||||||
|
"CAP_AUDIT_WRITE",
|
||||||
|
"CAP_KILL",
|
||||||
|
"CAP_NET_BIND_SERVICE"
|
||||||
|
],
|
||||||
|
"effective": [
|
||||||
|
"CAP_AUDIT_WRITE",
|
||||||
|
"CAP_KILL",
|
||||||
|
"CAP_NET_BIND_SERVICE"
|
||||||
|
],
|
||||||
|
"inheritable": [
|
||||||
|
"CAP_AUDIT_WRITE",
|
||||||
|
"CAP_KILL",
|
||||||
|
"CAP_NET_BIND_SERVICE"
|
||||||
|
],
|
||||||
|
"permitted": [
|
||||||
|
"CAP_AUDIT_WRITE",
|
||||||
|
"CAP_KILL",
|
||||||
|
"CAP_NET_BIND_SERVICE"
|
||||||
|
],
|
||||||
|
"ambient": [
|
||||||
|
"CAP_AUDIT_WRITE",
|
||||||
|
"CAP_KILL",
|
||||||
|
"CAP_NET_BIND_SERVICE"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"rlimits": [
|
||||||
|
{
|
||||||
|
"type": "RLIMIT_NOFILE",
|
||||||
|
"hard": 1024,
|
||||||
|
"soft": 1024
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"noNewPrivileges": true
|
||||||
|
},
|
||||||
|
"root": {
|
||||||
|
"path": "rootfs",
|
||||||
|
"readonly": true
|
||||||
|
},
|
||||||
|
"hostname": "runc",
|
||||||
|
"mounts": [
|
||||||
|
{
|
||||||
|
"destination": "/proc",
|
||||||
|
"type": "proc",
|
||||||
|
"source": "proc"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"destination": "/dev",
|
||||||
|
"type": "tmpfs",
|
||||||
|
"source": "tmpfs",
|
||||||
|
"options": [
|
||||||
|
"nosuid",
|
||||||
|
"strictatime",
|
||||||
|
"mode=755",
|
||||||
|
"size=65536k"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"destination": "/dev/pts",
|
||||||
|
"type": "devpts",
|
||||||
|
"source": "devpts",
|
||||||
|
"options": [
|
||||||
|
"nosuid",
|
||||||
|
"noexec",
|
||||||
|
"newinstance",
|
||||||
|
"ptmxmode=0666",
|
||||||
|
"mode=0620",
|
||||||
|
"gid=5"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"destination": "/dev/shm",
|
||||||
|
"type": "tmpfs",
|
||||||
|
"source": "shm",
|
||||||
|
"options": [
|
||||||
|
"nosuid",
|
||||||
|
"noexec",
|
||||||
|
"nodev",
|
||||||
|
"mode=1777",
|
||||||
|
"size=65536k"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"destination": "/dev/mqueue",
|
||||||
|
"type": "mqueue",
|
||||||
|
"source": "mqueue",
|
||||||
|
"options": [
|
||||||
|
"nosuid",
|
||||||
|
"noexec",
|
||||||
|
"nodev"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"destination": "/sys",
|
||||||
|
"type": "sysfs",
|
||||||
|
"source": "sysfs",
|
||||||
|
"options": [
|
||||||
|
"nosuid",
|
||||||
|
"noexec",
|
||||||
|
"nodev",
|
||||||
|
"ro"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"destination": "/sys/fs/cgroup",
|
||||||
|
"type": "cgroup",
|
||||||
|
"source": "cgroup",
|
||||||
|
"options": [
|
||||||
|
"nosuid",
|
||||||
|
"noexec",
|
||||||
|
"nodev",
|
||||||
|
"relatime",
|
||||||
|
"ro"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"linux": {
|
||||||
|
"resources": {
|
||||||
|
"devices": [
|
||||||
|
{
|
||||||
|
"allow": false,
|
||||||
|
"access": "rwm"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"namespaces": [
|
||||||
|
{
|
||||||
|
"type": "pid"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "network"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "ipc"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "uts"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "mount"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"maskedPaths": [
|
||||||
|
"/proc/acpi",
|
||||||
|
"/proc/asound",
|
||||||
|
"/proc/kcore",
|
||||||
|
"/proc/keys",
|
||||||
|
"/proc/latency_stats",
|
||||||
|
"/proc/timer_list",
|
||||||
|
"/proc/timer_stats",
|
||||||
|
"/proc/sched_debug",
|
||||||
|
"/sys/firmware",
|
||||||
|
"/proc/scsi"
|
||||||
|
],
|
||||||
|
"readonlyPaths": [
|
||||||
|
"/proc/bus",
|
||||||
|
"/proc/fs",
|
||||||
|
"/proc/irq",
|
||||||
|
"/proc/sys",
|
||||||
|
"/proc/sysrq-trigger"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}`
|
||||||
)
|
)
|
||||||
|
|
||||||
type RuntimeConfigOptions struct {
|
type RuntimeConfigOptions struct {
|
||||||
@ -154,3 +349,34 @@ func IsInGitHubActions() bool {
|
|||||||
// https://docs.github.com/en/actions/reference/environment-variables#default-environment-variables
|
// https://docs.github.com/en/actions/reference/environment-variables#default-environment-variables
|
||||||
return os.Getenv("GITHUB_ACTIONS") == "true"
|
return os.Getenv("GITHUB_ACTIONS") == "true"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func SetupOCIConfigFile(t *testing.T) (rootPath string, bundlePath, ociConfigFile string) {
|
||||||
|
assert := assert.New(t)
|
||||||
|
|
||||||
|
tmpdir, err := ioutil.TempDir("", "katatest-")
|
||||||
|
assert.NoError(err)
|
||||||
|
|
||||||
|
bundlePath = filepath.Join(tmpdir, "bundle")
|
||||||
|
err = os.MkdirAll(bundlePath, testDirMode)
|
||||||
|
assert.NoError(err)
|
||||||
|
|
||||||
|
ociConfigFile = filepath.Join(bundlePath, "config.json")
|
||||||
|
err = ioutil.WriteFile(ociConfigFile, []byte(busyboxConfigJson), testFileMode)
|
||||||
|
assert.NoError(err)
|
||||||
|
|
||||||
|
return tmpdir, bundlePath, ociConfigFile
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteOCIConfigFile using spec to update OCI config file by path configPath
|
||||||
|
func WriteOCIConfigFile(spec specs.Spec, configPath string) error {
|
||||||
|
if configPath == "" {
|
||||||
|
return errors.New("BUG: need config file path")
|
||||||
|
}
|
||||||
|
|
||||||
|
bytes, err := json.MarshalIndent(spec, "", "\t")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return ioutil.WriteFile(configPath, bytes, testFileMode)
|
||||||
|
}
|
||||||
|
@ -1,77 +0,0 @@
|
|||||||
// Copyright (c) 2019 SUSE LLC
|
|
||||||
//
|
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
//
|
|
||||||
|
|
||||||
package katautils
|
|
||||||
|
|
||||||
import (
|
|
||||||
"os/exec"
|
|
||||||
|
|
||||||
"github.com/kata-containers/kata-containers/src/runtime/pkg/utils"
|
|
||||||
)
|
|
||||||
|
|
||||||
type CtrEngine struct {
|
|
||||||
Name string
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
DockerLikeCtrEngines = []string{"docker", "podman"}
|
|
||||||
)
|
|
||||||
|
|
||||||
func (e *CtrEngine) Init(name string) (string, error) {
|
|
||||||
var out string
|
|
||||||
out, err := utils.RunCommandFull([]string{name, "version"}, true)
|
|
||||||
if err != nil {
|
|
||||||
return out, err
|
|
||||||
}
|
|
||||||
|
|
||||||
e.Name = name
|
|
||||||
return out, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *CtrEngine) Inspect(image string) (string, error) {
|
|
||||||
// Only hit the network if the image doesn't exist locally
|
|
||||||
return utils.RunCommand([]string{e.Name, "inspect", "--type=image", image})
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *CtrEngine) Pull(image string) (string, error) {
|
|
||||||
return utils.RunCommand([]string{e.Name, "pull", image})
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *CtrEngine) Create(image string) (string, error) {
|
|
||||||
return utils.RunCommand([]string{e.Name, "create", image})
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *CtrEngine) Rm(ctrID string) (string, error) {
|
|
||||||
return utils.RunCommand([]string{e.Name, "rm", ctrID})
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *CtrEngine) GetRootfs(ctrID string, dir string) error {
|
|
||||||
cmd1 := exec.Command(e.Name, "export", ctrID)
|
|
||||||
cmd2 := exec.Command("tar", "-C", dir, "-xvf", "-")
|
|
||||||
|
|
||||||
cmd1Stdout, err := cmd1.StdoutPipe()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd2.Stdin = cmd1Stdout
|
|
||||||
|
|
||||||
err = cmd2.Start()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = cmd1.Run()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = cmd2.Wait()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
@ -8,7 +8,6 @@ package katautils
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
@ -20,7 +19,6 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
ktu "github.com/kata-containers/kata-containers/src/runtime/pkg/katatestutils"
|
ktu "github.com/kata-containers/kata-containers/src/runtime/pkg/katatestutils"
|
||||||
"github.com/kata-containers/kata-containers/src/runtime/pkg/utils"
|
|
||||||
vc "github.com/kata-containers/kata-containers/src/runtime/virtcontainers"
|
vc "github.com/kata-containers/kata-containers/src/runtime/virtcontainers"
|
||||||
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/compatoci"
|
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/compatoci"
|
||||||
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/oci"
|
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/oci"
|
||||||
@ -37,8 +35,6 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
testBundleDir = ""
|
|
||||||
|
|
||||||
// testingImpl is a concrete mock RVC implementation used for testing
|
// testingImpl is a concrete mock RVC implementation used for testing
|
||||||
testingImpl = &vcmock.VCMock{}
|
testingImpl = &vcmock.VCMock{}
|
||||||
// mock sandbox
|
// mock sandbox
|
||||||
@ -53,49 +49,6 @@ func init() {
|
|||||||
tc = ktu.NewTestConstraint(false)
|
tc = ktu.NewTestConstraint(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
func writeOCIConfigFile(spec specs.Spec, configPath string) error {
|
|
||||||
if configPath == "" {
|
|
||||||
return errors.New("BUG: need config file path")
|
|
||||||
}
|
|
||||||
|
|
||||||
bytes, err := json.MarshalIndent(spec, "", "\t")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return ioutil.WriteFile(configPath, bytes, testFileMode)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create an OCI bundle in the specified directory.
|
|
||||||
//
|
|
||||||
// Note that the directory will be created, but it's parent is expected to exist.
|
|
||||||
//
|
|
||||||
// This function works by copying the already-created test bundle. Ideally,
|
|
||||||
// the bundle would be recreated for each test, but createRootfs() uses
|
|
||||||
// docker which on some systems is too slow, resulting in the tests timing
|
|
||||||
// out.
|
|
||||||
func makeOCIBundle(bundleDir string) error {
|
|
||||||
from := testBundleDir
|
|
||||||
to := bundleDir
|
|
||||||
|
|
||||||
// only the basename of bundleDir needs to exist as bundleDir
|
|
||||||
// will get created by cp(1).
|
|
||||||
base := filepath.Dir(bundleDir)
|
|
||||||
|
|
||||||
for _, dir := range []string{from, base} {
|
|
||||||
if !FileExists(dir) {
|
|
||||||
return fmt.Errorf("BUG: directory %v should exist", dir)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
output, err := utils.RunCommandFull([]string{"cp", "-a", from, to}, true)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("failed to copy test OCI bundle from %v to %v: %v (output: %v)", from, to, err, output)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// newTestRuntimeConfig creates a new RuntimeConfig
|
// newTestRuntimeConfig creates a new RuntimeConfig
|
||||||
func newTestRuntimeConfig(dir, consolePath string, create bool) (oci.RuntimeConfig, error) {
|
func newTestRuntimeConfig(dir, consolePath string, create bool) (oci.RuntimeConfig, error) {
|
||||||
if dir == "" {
|
if dir == "" {
|
||||||
@ -262,21 +215,12 @@ func TestSetKernelParamsUserOptionTakesPriority(t *testing.T) {
|
|||||||
func TestCreateSandboxConfigFail(t *testing.T) {
|
func TestCreateSandboxConfigFail(t *testing.T) {
|
||||||
assert := assert.New(t)
|
assert := assert.New(t)
|
||||||
|
|
||||||
tmpdir, err := ioutil.TempDir("", "")
|
tmpdir, bundlePath, _ := ktu.SetupOCIConfigFile(t)
|
||||||
assert.NoError(err)
|
|
||||||
defer os.RemoveAll(tmpdir)
|
defer os.RemoveAll(tmpdir)
|
||||||
|
|
||||||
runtimeConfig, err := newTestRuntimeConfig(tmpdir, testConsole, true)
|
runtimeConfig, err := newTestRuntimeConfig(tmpdir, testConsole, true)
|
||||||
assert.NoError(err)
|
assert.NoError(err)
|
||||||
|
|
||||||
bundlePath := filepath.Join(tmpdir, "bundle")
|
|
||||||
|
|
||||||
err = makeOCIBundle(bundlePath)
|
|
||||||
assert.NoError(err)
|
|
||||||
|
|
||||||
ociConfigFile := filepath.Join(bundlePath, "config.json")
|
|
||||||
assert.True(FileExists(ociConfigFile))
|
|
||||||
|
|
||||||
spec, err := compatoci.ParseConfigJSON(bundlePath)
|
spec, err := compatoci.ParseConfigJSON(bundlePath)
|
||||||
assert.NoError(err)
|
assert.NoError(err)
|
||||||
|
|
||||||
@ -305,21 +249,12 @@ func TestCreateSandboxFail(t *testing.T) {
|
|||||||
|
|
||||||
assert := assert.New(t)
|
assert := assert.New(t)
|
||||||
|
|
||||||
tmpdir, err := ioutil.TempDir("", "")
|
tmpdir, bundlePath, _ := ktu.SetupOCIConfigFile(t)
|
||||||
assert.NoError(err)
|
|
||||||
defer os.RemoveAll(tmpdir)
|
defer os.RemoveAll(tmpdir)
|
||||||
|
|
||||||
runtimeConfig, err := newTestRuntimeConfig(tmpdir, testConsole, true)
|
runtimeConfig, err := newTestRuntimeConfig(tmpdir, testConsole, true)
|
||||||
assert.NoError(err)
|
assert.NoError(err)
|
||||||
|
|
||||||
bundlePath := filepath.Join(tmpdir, "bundle")
|
|
||||||
|
|
||||||
err = makeOCIBundle(bundlePath)
|
|
||||||
assert.NoError(err)
|
|
||||||
|
|
||||||
ociConfigFile := filepath.Join(bundlePath, "config.json")
|
|
||||||
assert.True(FileExists(ociConfigFile))
|
|
||||||
|
|
||||||
spec, err := compatoci.ParseConfigJSON(bundlePath)
|
spec, err := compatoci.ParseConfigJSON(bundlePath)
|
||||||
assert.NoError(err)
|
assert.NoError(err)
|
||||||
|
|
||||||
@ -375,18 +310,9 @@ func TestCheckForFips(t *testing.T) {
|
|||||||
func TestCreateContainerContainerConfigFail(t *testing.T) {
|
func TestCreateContainerContainerConfigFail(t *testing.T) {
|
||||||
assert := assert.New(t)
|
assert := assert.New(t)
|
||||||
|
|
||||||
tmpdir, err := ioutil.TempDir("", "")
|
tmpdir, bundlePath, ociConfigFile := ktu.SetupOCIConfigFile(t)
|
||||||
assert.NoError(err)
|
|
||||||
defer os.RemoveAll(tmpdir)
|
defer os.RemoveAll(tmpdir)
|
||||||
|
|
||||||
bundlePath := filepath.Join(tmpdir, "bundle")
|
|
||||||
|
|
||||||
err = makeOCIBundle(bundlePath)
|
|
||||||
assert.NoError(err)
|
|
||||||
|
|
||||||
ociConfigFile := filepath.Join(bundlePath, "config.json")
|
|
||||||
assert.True(FileExists(ociConfigFile))
|
|
||||||
|
|
||||||
spec, err := compatoci.ParseConfigJSON(bundlePath)
|
spec, err := compatoci.ParseConfigJSON(bundlePath)
|
||||||
assert.NoError(err)
|
assert.NoError(err)
|
||||||
|
|
||||||
@ -396,7 +322,7 @@ func TestCreateContainerContainerConfigFail(t *testing.T) {
|
|||||||
spec.Annotations[testContainerTypeAnnotation] = containerType
|
spec.Annotations[testContainerTypeAnnotation] = containerType
|
||||||
|
|
||||||
// rewrite file
|
// rewrite file
|
||||||
err = writeOCIConfigFile(spec, ociConfigFile)
|
err = ktu.WriteOCIConfigFile(spec, ociConfigFile)
|
||||||
assert.NoError(err)
|
assert.NoError(err)
|
||||||
|
|
||||||
rootFs := vc.RootFs{Mounted: true}
|
rootFs := vc.RootFs{Mounted: true}
|
||||||
@ -412,18 +338,9 @@ func TestCreateContainerContainerConfigFail(t *testing.T) {
|
|||||||
func TestCreateContainerFail(t *testing.T) {
|
func TestCreateContainerFail(t *testing.T) {
|
||||||
assert := assert.New(t)
|
assert := assert.New(t)
|
||||||
|
|
||||||
tmpdir, err := ioutil.TempDir("", "")
|
tmpdir, bundlePath, ociConfigFile := ktu.SetupOCIConfigFile(t)
|
||||||
assert.NoError(err)
|
|
||||||
defer os.RemoveAll(tmpdir)
|
defer os.RemoveAll(tmpdir)
|
||||||
|
|
||||||
bundlePath := filepath.Join(tmpdir, "bundle")
|
|
||||||
|
|
||||||
err = makeOCIBundle(bundlePath)
|
|
||||||
assert.NoError(err)
|
|
||||||
|
|
||||||
ociConfigFile := filepath.Join(bundlePath, "config.json")
|
|
||||||
assert.True(FileExists(ociConfigFile))
|
|
||||||
|
|
||||||
spec, err := compatoci.ParseConfigJSON(bundlePath)
|
spec, err := compatoci.ParseConfigJSON(bundlePath)
|
||||||
assert.NoError(err)
|
assert.NoError(err)
|
||||||
|
|
||||||
@ -433,7 +350,7 @@ func TestCreateContainerFail(t *testing.T) {
|
|||||||
spec.Annotations[testSandboxIDAnnotation] = testSandboxID
|
spec.Annotations[testSandboxIDAnnotation] = testSandboxID
|
||||||
|
|
||||||
// rewrite file
|
// rewrite file
|
||||||
err = writeOCIConfigFile(spec, ociConfigFile)
|
err = ktu.WriteOCIConfigFile(spec, ociConfigFile)
|
||||||
assert.NoError(err)
|
assert.NoError(err)
|
||||||
|
|
||||||
rootFs := vc.RootFs{Mounted: true}
|
rootFs := vc.RootFs{Mounted: true}
|
||||||
@ -456,18 +373,9 @@ func TestCreateContainer(t *testing.T) {
|
|||||||
mockSandbox.CreateContainerFunc = nil
|
mockSandbox.CreateContainerFunc = nil
|
||||||
}()
|
}()
|
||||||
|
|
||||||
tmpdir, err := ioutil.TempDir("", "")
|
tmpdir, bundlePath, ociConfigFile := ktu.SetupOCIConfigFile(t)
|
||||||
assert.NoError(err)
|
|
||||||
defer os.RemoveAll(tmpdir)
|
defer os.RemoveAll(tmpdir)
|
||||||
|
|
||||||
bundlePath := filepath.Join(tmpdir, "bundle")
|
|
||||||
|
|
||||||
err = makeOCIBundle(bundlePath)
|
|
||||||
assert.NoError(err)
|
|
||||||
|
|
||||||
ociConfigFile := filepath.Join(bundlePath, "config.json")
|
|
||||||
assert.True(FileExists(ociConfigFile))
|
|
||||||
|
|
||||||
spec, err := compatoci.ParseConfigJSON(bundlePath)
|
spec, err := compatoci.ParseConfigJSON(bundlePath)
|
||||||
assert.NoError(err)
|
assert.NoError(err)
|
||||||
|
|
||||||
@ -477,7 +385,7 @@ func TestCreateContainer(t *testing.T) {
|
|||||||
spec.Annotations[testSandboxIDAnnotation] = testSandboxID
|
spec.Annotations[testSandboxIDAnnotation] = testSandboxID
|
||||||
|
|
||||||
// rewrite file
|
// rewrite file
|
||||||
err = writeOCIConfigFile(spec, ociConfigFile)
|
err = ktu.WriteOCIConfigFile(spec, ociConfigFile)
|
||||||
assert.NoError(err)
|
assert.NoError(err)
|
||||||
|
|
||||||
rootFs := vc.RootFs{Mounted: true}
|
rootFs := vc.RootFs{Mounted: true}
|
||||||
|
@ -7,20 +7,15 @@
|
|||||||
package katautils
|
package katautils
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
|
||||||
"path"
|
"path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
|
||||||
"syscall"
|
"syscall"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
ktu "github.com/kata-containers/kata-containers/src/runtime/pkg/katatestutils"
|
ktu "github.com/kata-containers/kata-containers/src/runtime/pkg/katatestutils"
|
||||||
"github.com/kata-containers/kata-containers/src/runtime/pkg/utils"
|
|
||||||
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/compatoci"
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -28,173 +23,14 @@ const (
|
|||||||
testDirMode = os.FileMode(0750)
|
testDirMode = os.FileMode(0750)
|
||||||
testFileMode = os.FileMode(0640)
|
testFileMode = os.FileMode(0640)
|
||||||
|
|
||||||
// small docker image used to create root filesystems from
|
|
||||||
testDockerImage = "busybox"
|
|
||||||
|
|
||||||
testSandboxID = "99999999-9999-9999-99999999999999999"
|
testSandboxID = "99999999-9999-9999-99999999999999999"
|
||||||
testContainerID = "1"
|
testContainerID = "1"
|
||||||
testBundle = "bundle"
|
|
||||||
specConfig = "config.json"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
testDir = ""
|
testDir = ""
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
|
||||||
var err error
|
|
||||||
|
|
||||||
fmt.Printf("INFO: creating test directory\n")
|
|
||||||
testDir, err = ioutil.TempDir("", fmt.Sprintf("%s-", NAME))
|
|
||||||
if err != nil {
|
|
||||||
panic(fmt.Sprintf("ERROR: failed to create test directory: %v", err))
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Printf("INFO: test directory is %v\n", testDir)
|
|
||||||
|
|
||||||
testBundleDir = filepath.Join(testDir, testBundle)
|
|
||||||
err = os.MkdirAll(testBundleDir, testDirMode)
|
|
||||||
if err != nil {
|
|
||||||
panic(fmt.Sprintf("ERROR: failed to create bundle directory %v: %v", testBundleDir, err))
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Printf("INFO: creating OCI bundle in %v for tests to use\n", testBundleDir)
|
|
||||||
err = realMakeOCIBundle(testBundleDir)
|
|
||||||
if err != nil {
|
|
||||||
panic(fmt.Sprintf("ERROR: failed to create OCI bundle: %v", err))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// createOCIConfig creates an OCI configuration (spec) file in
|
|
||||||
// the bundle directory specified (which must exist).
|
|
||||||
func createOCIConfig(bundleDir string) error {
|
|
||||||
if bundleDir == "" {
|
|
||||||
return errors.New("BUG: Need bundle directory")
|
|
||||||
}
|
|
||||||
|
|
||||||
if !FileExists(bundleDir) {
|
|
||||||
return fmt.Errorf("BUG: Bundle directory %s does not exist", bundleDir)
|
|
||||||
}
|
|
||||||
|
|
||||||
var configCmd string
|
|
||||||
|
|
||||||
// Search for a suitable version of runc to use to generate
|
|
||||||
// the OCI config file.
|
|
||||||
for _, cmd := range []string{"docker-runc", "runc"} {
|
|
||||||
fullPath, err := exec.LookPath(cmd)
|
|
||||||
if err == nil {
|
|
||||||
configCmd = fullPath
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if configCmd == "" {
|
|
||||||
return errors.New("Cannot find command to generate OCI config file")
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err := utils.RunCommand([]string{configCmd, "spec", "--bundle", bundleDir})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
specFile := filepath.Join(bundleDir, specConfig)
|
|
||||||
if !FileExists(specFile) {
|
|
||||||
return fmt.Errorf("generated OCI config file does not exist: %v", specFile)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// realMakeOCIBundle will create an OCI bundle (including the "config.json"
|
|
||||||
// config file) in the directory specified (which must already exist).
|
|
||||||
//
|
|
||||||
// XXX: Note that tests should *NOT* call this function - they should
|
|
||||||
// XXX: instead call makeOCIBundle().
|
|
||||||
func realMakeOCIBundle(bundleDir string) error {
|
|
||||||
if bundleDir == "" {
|
|
||||||
return errors.New("BUG: Need bundle directory")
|
|
||||||
}
|
|
||||||
|
|
||||||
if !FileExists(bundleDir) {
|
|
||||||
return fmt.Errorf("BUG: Bundle directory %v does not exist", bundleDir)
|
|
||||||
}
|
|
||||||
|
|
||||||
err := createOCIConfig(bundleDir)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Note the unusual parameter (a directory, not the config
|
|
||||||
// file to parse!)
|
|
||||||
spec, err := compatoci.ParseConfigJSON(bundleDir)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Determine the rootfs directory name the OCI config refers to
|
|
||||||
ociRootPath := spec.Root.Path
|
|
||||||
|
|
||||||
rootfsDir := filepath.Join(bundleDir, ociRootPath)
|
|
||||||
|
|
||||||
if strings.HasPrefix(ociRootPath, "/") {
|
|
||||||
return fmt.Errorf("Cannot handle absolute rootfs as bundle must be unique to each test")
|
|
||||||
}
|
|
||||||
|
|
||||||
err = createRootfs(rootfsDir)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// createRootfs creates a minimal root filesystem below the specified
|
|
||||||
// directory.
|
|
||||||
func createRootfs(dir string) error {
|
|
||||||
var (
|
|
||||||
output string
|
|
||||||
err error
|
|
||||||
)
|
|
||||||
|
|
||||||
ctrEngine := CtrEngine{}
|
|
||||||
for _, name := range DockerLikeCtrEngines {
|
|
||||||
fmt.Printf("INFO: checking for container engine: %s\n", name)
|
|
||||||
|
|
||||||
output, err = ctrEngine.Init(name)
|
|
||||||
if err == nil {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ctrEngine.Name == "" {
|
|
||||||
panic(fmt.Sprintf("ERROR: Docker-like container engine not accessible to current user: %v (error %v)",
|
|
||||||
output, err))
|
|
||||||
}
|
|
||||||
|
|
||||||
err = os.MkdirAll(dir, testDirMode)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
container, err := ctrEngine.Create(testDockerImage)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = ctrEngine.GetRootfs(container, dir)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clean up
|
|
||||||
_, err = ctrEngine.Rm(container)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func createFile(file, contents string) error {
|
func createFile(file, contents string) error {
|
||||||
return ioutil.WriteFile(file, []byte(contents), testFileMode)
|
return ioutil.WriteFile(file, []byte(contents), testFileMode)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user