diff --git a/pkg/katautils/create.go b/pkg/katautils/create.go index 63fab5c859..630b32c991 100644 --- a/pkg/katautils/create.go +++ b/pkg/katautils/create.go @@ -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" } } diff --git a/pkg/katautils/utils.go b/pkg/katautils/utils.go index ae3ccecd36..12ab107fad 100644 --- a/pkg/katautils/utils.go +++ b/pkg/katautils/utils.go @@ -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) { diff --git a/virtcontainers/container.go b/virtcontainers/container.go index 75fcdc98f2..f77662beda 100644 --- a/virtcontainers/container.go +++ b/virtcontainers/container.go @@ -477,8 +477,10 @@ 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) { - continue + if isSystemMount(m.Destination) { + if !(IsDockerVolume(m.Source) || Isk8sHostEmptyDir(m.Source)) { + continue + } } if m.Type != "bind" { diff --git a/virtcontainers/mount.go b/virtcontainers/mount.go index 6dc6b62f38..73406b51af 100644 --- a/virtcontainers/mount.go +++ b/virtcontainers/mount.go @@ -342,3 +342,49 @@ func IsDockerVolume(path string) bool { return false } +const ( + 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 +} + +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 +} diff --git a/virtcontainers/mount_test.go b/virtcontainers/mount_test.go index f39fa3c489..7d0b3c4768 100644 --- a/virtcontainers/mount_test.go +++ b/virtcontainers/mount_test.go @@ -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) +}