mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-06-30 09:13:29 +00:00
mount: Add check for k8s host empty directory
k8s host empty-dir is equivalent to docker volumes. For this case, we should just use the host directory even for system directories. Move the isEphemeral function to virtcontainers to not introduce cyclic dependency. Fixes #1417 Signed-off-by: Archana Shinde <archana.m.shinde@intel.com>
This commit is contained in:
parent
70c193132d
commit
228d1512d9
@ -161,7 +161,7 @@ func HandleFactory(ctx context.Context, vci vc.VC, runtimeConfig *oci.RuntimeCon
|
||||
// of the same pod the already existing volume is reused.
|
||||
func SetEphemeralStorageType(ociSpec oci.CompatOCISpec) oci.CompatOCISpec {
|
||||
for idx, mnt := range ociSpec.Mounts {
|
||||
if IsEphemeralStorage(mnt.Source) {
|
||||
if vc.IsEphemeralStorage(mnt.Source) {
|
||||
ociSpec.Mounts[idx].Type = "ephemeral"
|
||||
}
|
||||
}
|
||||
|
@ -190,7 +190,7 @@ func TestSetEphemeralStorageType(t *testing.T) {
|
||||
}
|
||||
defer os.RemoveAll(dir)
|
||||
|
||||
ephePath := filepath.Join(dir, k8sEmptyDir, "tmp-volume")
|
||||
ephePath := filepath.Join(dir, vc.K8sEmptyDir, "tmp-volume")
|
||||
err = os.MkdirAll(ephePath, testDirMode)
|
||||
assert.Nil(err)
|
||||
|
||||
|
@ -14,12 +14,6 @@ import (
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"syscall"
|
||||
|
||||
vc "github.com/kata-containers/runtime/virtcontainers"
|
||||
)
|
||||
|
||||
const (
|
||||
k8sEmptyDir = "kubernetes.io~empty-dir"
|
||||
)
|
||||
|
||||
// FileExists test is a file exiting or not
|
||||
@ -31,28 +25,6 @@ func FileExists(path string) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// IsEphemeralStorage returns true if the given path
|
||||
// to the storage belongs to kubernetes ephemeral storage
|
||||
//
|
||||
// This method depends on a specific path used by k8s
|
||||
// to detect if it's of type ephemeral. As of now,
|
||||
// this is a very k8s specific solution that works
|
||||
// but in future there should be a better way for this
|
||||
// method to determine if the path is for ephemeral
|
||||
// volume type
|
||||
func IsEphemeralStorage(path string) bool {
|
||||
splitSourceSlice := strings.Split(path, "/")
|
||||
if len(splitSourceSlice) > 1 {
|
||||
storageType := splitSourceSlice[len(splitSourceSlice)-2]
|
||||
if storageType == k8sEmptyDir {
|
||||
if _, fsType, _ := vc.GetDevicePathAndFsType(path); fsType == "tmpfs" {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// ResolvePath returns the fully resolved and expanded value of the
|
||||
// specified path.
|
||||
func ResolvePath(path string) (string, error) {
|
||||
|
@ -366,34 +366,3 @@ func TestGetFileContents(t *testing.T) {
|
||||
assert.Equal(t, contents, d.contents)
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsEphemeralStorage(t *testing.T) {
|
||||
if os.Geteuid() != 0 {
|
||||
t.Skip(testDisabledNeedRoot)
|
||||
}
|
||||
|
||||
dir, err := ioutil.TempDir(testDir, "foo")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer os.RemoveAll(dir)
|
||||
|
||||
sampleEphePath := filepath.Join(dir, k8sEmptyDir, "tmp-volume")
|
||||
err = os.MkdirAll(sampleEphePath, testDirMode)
|
||||
assert.Nil(t, err)
|
||||
|
||||
err = syscall.Mount("tmpfs", sampleEphePath, "tmpfs", 0, "")
|
||||
assert.Nil(t, err)
|
||||
defer syscall.Unmount(sampleEphePath, 0)
|
||||
|
||||
isEphe := IsEphemeralStorage(sampleEphePath)
|
||||
if !isEphe {
|
||||
t.Fatalf("Unable to correctly determine volume type")
|
||||
}
|
||||
|
||||
sampleEphePath = "/var/lib/kubelet/pods/366c3a75-4869-11e8-b479-507b9ddd5ce4/volumes/cache-volume"
|
||||
isEphe = IsEphemeralStorage(sampleEphePath)
|
||||
if isEphe {
|
||||
t.Fatalf("Unable to correctly determine volume type")
|
||||
}
|
||||
}
|
||||
|
@ -477,9 +477,11 @@ func (c *Container) mountSharedDirMounts(hostSharedDir, guestSharedDir string) (
|
||||
var sharedDirMounts []Mount
|
||||
var ignoredMounts []Mount
|
||||
for idx, m := range c.mounts {
|
||||
if isSystemMount(m.Destination) && !IsDockerVolume(m.Source) {
|
||||
if isSystemMount(m.Destination) {
|
||||
if !(IsDockerVolume(m.Source) || Isk8sHostEmptyDir(m.Source)) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
if m.Type != "bind" {
|
||||
continue
|
||||
|
@ -342,3 +342,53 @@ func IsDockerVolume(path string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
const (
|
||||
// K8sEmptyDir is the k8s specific path for `empty-dir` volumes
|
||||
K8sEmptyDir = "kubernetes.io~empty-dir"
|
||||
)
|
||||
|
||||
// IsEphemeralStorage returns true if the given path
|
||||
// to the storage belongs to kubernetes ephemeral storage
|
||||
//
|
||||
// This method depends on a specific path used by k8s
|
||||
// to detect if it's of type ephemeral. As of now,
|
||||
// this is a very k8s specific solution that works
|
||||
// but in future there should be a better way for this
|
||||
// method to determine if the path is for ephemeral
|
||||
// volume type
|
||||
func IsEphemeralStorage(path string) bool {
|
||||
if !isEmptyDir(path) {
|
||||
return false
|
||||
}
|
||||
|
||||
if _, fsType, _ := GetDevicePathAndFsType(path); fsType == "tmpfs" {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// Isk8sHostEmptyDir returns true if the given path
|
||||
// to the storage belongs to kubernetes empty-dir of medium "default"
|
||||
// i.e volumes that are directories on the host.
|
||||
func Isk8sHostEmptyDir(path string) bool {
|
||||
if !isEmptyDir(path) {
|
||||
return false
|
||||
}
|
||||
|
||||
if _, fsType, _ := GetDevicePathAndFsType(path); fsType != "tmpfs" {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func isEmptyDir(path string) bool {
|
||||
splitSourceSlice := strings.Split(path, "/")
|
||||
if len(splitSourceSlice) > 1 {
|
||||
storageType := splitSourceSlice[len(splitSourceSlice)-2]
|
||||
if storageType == K8sEmptyDir {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
@ -9,6 +9,8 @@ import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
@ -18,6 +20,11 @@ import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
const (
|
||||
testDisabledNeedRoot = "Test disabled as requires root user"
|
||||
testDirMode = os.FileMode(0750)
|
||||
)
|
||||
|
||||
func TestIsSystemMount(t *testing.T) {
|
||||
tests := []struct {
|
||||
mnt string
|
||||
@ -289,6 +296,39 @@ func TestIsDockerVolume(t *testing.T) {
|
||||
assert.True(t, isDockerVolume)
|
||||
|
||||
path = "/var/lib/testdir"
|
||||
isDockerVolume := IsDockerVolume(path)
|
||||
isDockerVolume = IsDockerVolume(path)
|
||||
assert.False(t, isDockerVolume)
|
||||
}
|
||||
|
||||
func TestIsEphemeralStorage(t *testing.T) {
|
||||
if os.Geteuid() != 0 {
|
||||
t.Skip(testDisabledNeedRoot)
|
||||
}
|
||||
|
||||
dir, err := ioutil.TempDir(testDir, "foo")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer os.RemoveAll(dir)
|
||||
|
||||
sampleEphePath := filepath.Join(dir, k8sEmptyDir, "tmp-volume")
|
||||
err = os.MkdirAll(sampleEphePath, testDirMode)
|
||||
assert.Nil(t, err)
|
||||
|
||||
err = syscall.Mount("tmpfs", sampleEphePath, "tmpfs", 0, "")
|
||||
assert.Nil(t, err)
|
||||
defer syscall.Unmount(sampleEphePath, 0)
|
||||
|
||||
isEphe := IsEphemeralStorage(sampleEphePath)
|
||||
assert.True(t, isEphe)
|
||||
|
||||
isHostEmptyDir := Isk8sHostEmptyDir(sampleEphePath)
|
||||
assert.False(t, isHostEmptyDir)
|
||||
|
||||
sampleEphePath = "/var/lib/kubelet/pods/366c3a75-4869-11e8-b479-507b9ddd5ce4/volumes/cache-volume"
|
||||
isEphe = IsEphemeralStorage(sampleEphePath)
|
||||
assert.False(t, isEphe)
|
||||
|
||||
isHostEmptyDir = Isk8sHostEmptyDir(sampleEphePath)
|
||||
assert.False(t, isHostEmptyDir)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user