mirror of
https://github.com/aljazceru/kata-containers.git
synced 2026-01-19 14:24:26 +01:00
virtcontainers: change container's rootfs from string to mount alike struct
container's rootfs is a string type, which cannot represent a
block storage backed rootfs which hasn't been mounted.
Change it to a mount alike struct as below:
RootFs struct {
// Source specify the BlockDevice path
Source string
// Target specify where the rootfs is mounted if it has been mounted
Target string
// Type specifies the type of filesystem to mount.
Type string
// Options specifies zero or more fstab style mount options.
Options []string
// Mounted specifies whether the rootfs has be mounted or not
Mounted bool
}
If the container's rootfs has been mounted as before, then this struct can be
initialized as: RootFs{Target: <rootfs>, Mounted: true} to be compatible with
previous case.
Fixes:#1158
Signed-off-by: lifupan <lifupan@gmail.com>
This commit is contained in:
@@ -164,7 +164,7 @@ func SetEphemeralStorageType(ociSpec oci.CompatOCISpec) oci.CompatOCISpec {
|
||||
}
|
||||
|
||||
// CreateSandbox create a sandbox container
|
||||
func CreateSandbox(ctx context.Context, vci vc.VC, ociSpec oci.CompatOCISpec, runtimeConfig oci.RuntimeConfig,
|
||||
func CreateSandbox(ctx context.Context, vci vc.VC, ociSpec oci.CompatOCISpec, runtimeConfig oci.RuntimeConfig, rootFs vc.RootFs,
|
||||
containerID, bundlePath, console string, disableOutput, systemdCgroup, builtIn bool) (vc.VCSandbox, vc.Process, error) {
|
||||
span, ctx := Trace(ctx, "createSandbox")
|
||||
defer span.Finish()
|
||||
@@ -178,6 +178,17 @@ func CreateSandbox(ctx context.Context, vci vc.VC, ociSpec oci.CompatOCISpec, ru
|
||||
sandboxConfig.Stateful = true
|
||||
}
|
||||
|
||||
if !rootFs.Mounted && len(sandboxConfig.Containers) == 1 {
|
||||
if rootFs.Source != "" {
|
||||
realPath, err := ResolvePath(rootFs.Source)
|
||||
if err != nil {
|
||||
return nil, vc.Process{}, err
|
||||
}
|
||||
rootFs.Source = realPath
|
||||
}
|
||||
sandboxConfig.Containers[0].RootFs = rootFs
|
||||
}
|
||||
|
||||
// Important to create the network namespace before the sandbox is
|
||||
// created, because it is not responsible for the creation of the
|
||||
// netns if it does not exist.
|
||||
@@ -218,7 +229,7 @@ func CreateSandbox(ctx context.Context, vci vc.VC, ociSpec oci.CompatOCISpec, ru
|
||||
}
|
||||
|
||||
// CreateContainer create a container
|
||||
func CreateContainer(ctx context.Context, vci vc.VC, sandbox vc.VCSandbox, ociSpec oci.CompatOCISpec, containerID, bundlePath, console string, disableOutput, builtIn bool) (vc.Process, error) {
|
||||
func CreateContainer(ctx context.Context, vci vc.VC, sandbox vc.VCSandbox, ociSpec oci.CompatOCISpec, rootFs vc.RootFs, containerID, bundlePath, console string, disableOutput, builtIn bool) (vc.Process, error) {
|
||||
var c vc.VCContainer
|
||||
|
||||
span, ctx := Trace(ctx, "createContainer")
|
||||
@@ -231,6 +242,17 @@ func CreateContainer(ctx context.Context, vci vc.VC, sandbox vc.VCSandbox, ociSp
|
||||
return vc.Process{}, err
|
||||
}
|
||||
|
||||
if !rootFs.Mounted {
|
||||
if rootFs.Source != "" {
|
||||
realPath, err := ResolvePath(rootFs.Source)
|
||||
if err != nil {
|
||||
return vc.Process{}, err
|
||||
}
|
||||
rootFs.Source = realPath
|
||||
}
|
||||
contConfig.RootFs = rootFs
|
||||
}
|
||||
|
||||
sandboxID, err := ociSpec.SandboxID()
|
||||
if err != nil {
|
||||
return vc.Process{}, err
|
||||
|
||||
@@ -306,7 +306,9 @@ func TestCreateSandboxConfigFail(t *testing.T) {
|
||||
Quota: "a,
|
||||
}
|
||||
|
||||
_, _, err = CreateSandbox(context.Background(), testingImpl, spec, runtimeConfig, testContainerID, bundlePath, testConsole, true, true, false)
|
||||
rootFs := vc.RootFs{Mounted: true}
|
||||
|
||||
_, _, err = CreateSandbox(context.Background(), testingImpl, spec, runtimeConfig, rootFs, testContainerID, bundlePath, testConsole, true, true, false)
|
||||
assert.Error(err)
|
||||
}
|
||||
|
||||
@@ -340,7 +342,9 @@ func TestCreateSandboxFail(t *testing.T) {
|
||||
spec, err := readOCIConfigFile(ociConfigFile)
|
||||
assert.NoError(err)
|
||||
|
||||
_, _, err = CreateSandbox(context.Background(), testingImpl, spec, runtimeConfig, testContainerID, bundlePath, testConsole, true, true, false)
|
||||
rootFs := vc.RootFs{Mounted: true}
|
||||
|
||||
_, _, err = CreateSandbox(context.Background(), testingImpl, spec, runtimeConfig, rootFs, testContainerID, bundlePath, testConsole, true, true, false)
|
||||
assert.Error(err)
|
||||
assert.True(vcmock.IsMockError(err))
|
||||
}
|
||||
@@ -377,8 +381,10 @@ func TestCreateContainerContainerConfigFail(t *testing.T) {
|
||||
err = writeOCIConfigFile(spec, ociConfigFile)
|
||||
assert.NoError(err)
|
||||
|
||||
rootFs := vc.RootFs{Mounted: true}
|
||||
|
||||
for _, disableOutput := range []bool{true, false} {
|
||||
_, err = CreateContainer(context.Background(), testingImpl, nil, spec, testContainerID, bundlePath, testConsole, disableOutput, false)
|
||||
_, err = CreateContainer(context.Background(), testingImpl, nil, spec, rootFs, testContainerID, bundlePath, testConsole, disableOutput, false)
|
||||
assert.Error(err)
|
||||
assert.False(vcmock.IsMockError(err))
|
||||
assert.True(strings.Contains(err.Error(), containerType))
|
||||
@@ -418,8 +424,10 @@ func TestCreateContainerFail(t *testing.T) {
|
||||
err = writeOCIConfigFile(spec, ociConfigFile)
|
||||
assert.NoError(err)
|
||||
|
||||
rootFs := vc.RootFs{Mounted: true}
|
||||
|
||||
for _, disableOutput := range []bool{true, false} {
|
||||
_, err = CreateContainer(context.Background(), testingImpl, nil, spec, testContainerID, bundlePath, testConsole, disableOutput, false)
|
||||
_, err = CreateContainer(context.Background(), testingImpl, nil, spec, rootFs, testContainerID, bundlePath, testConsole, disableOutput, false)
|
||||
assert.Error(err)
|
||||
assert.True(vcmock.IsMockError(err))
|
||||
os.RemoveAll(path)
|
||||
@@ -466,8 +474,10 @@ func TestCreateContainer(t *testing.T) {
|
||||
err = writeOCIConfigFile(spec, ociConfigFile)
|
||||
assert.NoError(err)
|
||||
|
||||
rootFs := vc.RootFs{Mounted: true}
|
||||
|
||||
for _, disableOutput := range []bool{true, false} {
|
||||
_, err = CreateContainer(context.Background(), testingImpl, nil, spec, testContainerID, bundlePath, testConsole, disableOutput, false)
|
||||
_, err = CreateContainer(context.Background(), testingImpl, nil, spec, rootFs, testContainerID, bundlePath, testConsole, disableOutput, false)
|
||||
assert.NoError(err)
|
||||
os.RemoveAll(path)
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ package katautils
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"golang.org/x/sys/unix"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
@@ -78,6 +79,29 @@ func ResolvePath(path string) (string, error) {
|
||||
return resolved, nil
|
||||
}
|
||||
|
||||
// IsBlockDevice returns true if the give path is a block device
|
||||
func IsBlockDevice(filePath string) bool {
|
||||
var stat unix.Stat_t
|
||||
|
||||
if filePath == "" {
|
||||
return false
|
||||
}
|
||||
|
||||
devicePath, err := ResolvePath(filePath)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
if err := unix.Stat(devicePath, &stat); err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
if stat.Mode&unix.S_IFBLK == unix.S_IFBLK {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// fileSize returns the number of bytes in the specified file
|
||||
func fileSize(file string) (int64, error) {
|
||||
st := syscall.Stat_t{}
|
||||
|
||||
Reference in New Issue
Block a user