Skip to content
This repository has been archived by the owner on May 12, 2021. It is now read-only.

Commit

Permalink
mount: Add check for k8s host empty directory
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
amshinde committed Mar 25, 2019
1 parent 70c1931 commit 3b33aaf
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 32 deletions.
2 changes: 1 addition & 1 deletion pkg/katautils/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
}
}
Expand Down
28 changes: 0 additions & 28 deletions pkg/katautils/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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) {
Expand Down
6 changes: 4 additions & 2 deletions virtcontainers/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -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" {
Expand Down
46 changes: 46 additions & 0 deletions virtcontainers/mount.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
42 changes: 41 additions & 1 deletion virtcontainers/mount_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import (
"bytes"
"context"
"fmt"
"github.com/stretchr/testify/assert"
"io/ioutil"
"os"
"os/exec"
"path/filepath"
Expand All @@ -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
Expand Down Expand Up @@ -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)
}

0 comments on commit 3b33aaf

Please sign in to comment.