Add more volume types in e2e and fix part of them.

- Add dir-link/dir-bindmounted/dir-link-bindmounted/blockfs volume types for e2e
tests.
- Return error if we cannot resolve volume path.
- Add GetFSGroup/GetMountRefs methods for mount.Interface.
- Fix fsGroup related e2e tests partially.
This commit is contained in:
Yecheng Fu 2018-04-20 15:26:31 +08:00
parent 44ede98e94
commit 3748197876
20 changed files with 331 additions and 43 deletions

View File

@ -19,6 +19,7 @@ limitations under the License.
package cm
import (
"errors"
"fmt"
"io/ioutil"
"os"
@ -107,6 +108,14 @@ func (mi *fakeMountInterface) SafeMakeDir(_, _ string, _ os.FileMode) error {
return nil
}
func (mi *fakeMountInterface) GetMountRefs(pathname string) ([]string, error) {
return nil, errors.New("not implemented")
}
func (mi *fakeMountInterface) GetFSGroup(pathname string) (int64, error) {
return -1, errors.New("not implemented")
}
func fakeContainerMgrMountInt() mount.Interface {
return &fakeMountInterface{
[]mount.MountPoint{

View File

@ -151,3 +151,11 @@ func (m *execMounter) CleanSubPaths(podDir string, volumeName string) error {
func (m *execMounter) SafeMakeDir(pathname string, base string, perm os.FileMode) error {
return m.wrappedMounter.SafeMakeDir(pathname, base, perm)
}
func (m *execMounter) GetMountRefs(pathname string) ([]string, error) {
return m.wrappedMounter.GetMountRefs(pathname)
}
func (m *execMounter) GetFSGroup(pathname string) (int64, error) {
return m.wrappedMounter.GetFSGroup(pathname)
}

View File

@ -19,6 +19,7 @@ limitations under the License.
package mount
import (
"errors"
"fmt"
"os"
"reflect"
@ -163,3 +164,11 @@ func (fm *fakeMounter) CleanSubPaths(podDir string, volumeName string) error {
func (fm *fakeMounter) SafeMakeDir(pathname string, base string, perm os.FileMode) error {
return nil
}
func (fm *fakeMounter) GetMountRefs(pathname string) ([]string, error) {
return nil, errors.New("not implemented")
}
func (fm *fakeMounter) GetFSGroup(pathname string) (int64, error) {
return -1, errors.New("not implemented")
}

View File

@ -98,3 +98,11 @@ func (mounter *execMounter) CleanSubPaths(podDir string, volumeName string) erro
func (mounter *execMounter) SafeMakeDir(pathname string, base string, perm os.FileMode) error {
return nil
}
func (mounter *execMounter) GetMountRefs(pathname string) ([]string, error) {
return nil, errors.New("not implemented")
}
func (mounter *execMounter) GetFSGroup(pathname string) (int64, error) {
return -1, errors.New("not implemented")
}

View File

@ -17,6 +17,7 @@ limitations under the License.
package mount
import (
"errors"
"os"
"path/filepath"
"sync"
@ -208,3 +209,16 @@ func (f *FakeMounter) CleanSubPaths(podDir string, volumeName string) error {
func (mounter *FakeMounter) SafeMakeDir(pathname string, base string, perm os.FileMode) error {
return nil
}
func (f *FakeMounter) GetMountRefs(pathname string) ([]string, error) {
realpath, err := filepath.EvalSymlinks(pathname)
if err != nil {
// Ignore error in FakeMounter, because we actually didn't create files.
realpath = pathname
}
return getMountRefsByDev(f, realpath)
}
func (f *FakeMounter) GetFSGroup(pathname string) (int64, error) {
return -1, errors.New("GetFSGroup not implemented")
}

View File

@ -108,6 +108,12 @@ type Interface interface {
// subpath starts. On the other hand, Interface.CleanSubPaths must be called
// when the pod finishes.
PrepareSafeSubpath(subPath Subpath) (newHostPath string, cleanupAction func(), err error)
// GetMountRefs finds all mount references to the path, returns a
// list of paths. Path could be a mountpoint path, device or a normal
// directory (for bind mount).
GetMountRefs(pathname string) ([]string, error)
// GetFSGroup returns FSGroup of the path.
GetFSGroup(pathname string) (int64, error)
}
type Subpath struct {
@ -166,22 +172,19 @@ func (mounter *SafeFormatAndMount) FormatAndMount(source string, target string,
return mounter.formatAndMount(source, target, fstype, options)
}
// GetMountRefsByDev finds all references to the device provided
// getMountRefsByDev finds all references to the device provided
// by mountPath; returns a list of paths.
func GetMountRefsByDev(mounter Interface, mountPath string) ([]string, error) {
// Note that mountPath should be path after the evaluation of any symblolic links.
func getMountRefsByDev(mounter Interface, mountPath string) ([]string, error) {
mps, err := mounter.List()
if err != nil {
return nil, err
}
slTarget, err := filepath.EvalSymlinks(mountPath)
if err != nil {
slTarget = mountPath
}
// Finding the device mounted to mountPath
diskDev := ""
for i := range mps {
if slTarget == mps[i].Path {
if mountPath == mps[i].Path {
diskDev = mps[i].Device
break
}
@ -190,8 +193,8 @@ func GetMountRefsByDev(mounter Interface, mountPath string) ([]string, error) {
// Find all references to the device.
var refs []string
for i := range mps {
if mps[i].Device == diskDev || mps[i].Device == slTarget {
if mps[i].Path != slTarget {
if mps[i].Device == diskDev || mps[i].Device == mountPath {
if mps[i].Path != mountPath {
refs = append(refs, mps[i].Path)
}
}

View File

@ -921,6 +921,31 @@ func (mounter *Mounter) SafeMakeDir(pathname string, base string, perm os.FileMo
return doSafeMakeDir(pathname, base, perm)
}
func (mounter *Mounter) GetMountRefs(pathname string) ([]string, error) {
realpath, err := filepath.EvalSymlinks(pathname)
if err != nil {
return nil, err
}
return getMountRefsByDev(mounter, realpath)
}
func (mounter *Mounter) GetFSGroup(pathname string) (int64, error) {
realpath, err := filepath.EvalSymlinks(pathname)
if err != nil {
return 0, err
}
return getFSGroup(realpath)
}
// This implementation is shared between Linux and NsEnterMounter
func getFSGroup(pathname string) (int64, error) {
info, err := os.Stat(pathname)
if err != nil {
return 0, err
}
return int64(info.Sys().(*syscall.Stat_t).Gid), nil
}
// This implementation is shared between Linux and NsEnterMounter
func doSafeMakeDir(pathname string, base string, perm os.FileMode) error {
glog.V(4).Infof("Creating directory %q within base %q", pathname, base)

View File

@ -203,7 +203,7 @@ func TestGetMountRefsByDev(t *testing.T) {
for i, test := range tests {
if refs, err := GetMountRefsByDev(fm, test.mountPath); err != nil || !setEquivalent(test.expectedRefs, refs) {
if refs, err := getMountRefsByDev(fm, test.mountPath); err != nil || !setEquivalent(test.expectedRefs, refs) {
t.Errorf("%d. getMountRefsByDev(%q) = %v, %v; expected %v, nil", i, test.mountPath, refs, err, test.expectedRefs)
}
}

View File

@ -126,3 +126,11 @@ func (mounter *Mounter) CleanSubPaths(podDir string, volumeName string) error {
func (mounter *Mounter) SafeMakeDir(pathname string, base string, perm os.FileMode) error {
return unsupportedErr
}
func (mounter *Mounter) GetMountRefs(pathname string) ([]string, error) {
return nil, errors.New("not implemented")
}
func (mounter *Mounter) GetFSGroup(pathname string) (int64, error) {
return -1, errors.New("not implemented")
}

View File

@ -438,6 +438,20 @@ func getAllParentLinks(path string) ([]string, error) {
return links, nil
}
func (mounter *Mounter) GetMountRefs(pathname string) ([]string, error) {
realpath, err := filepath.EvalSymlinks(pathname)
if err != nil {
return nil, err
}
return getMountRefsByDev(mounter, realpath)
}
// Note that on windows, it always returns 0. We actually don't set FSGroup on
// windows platform, see SetVolumeOwnership implementation.
func (mounter *Mounter) GetFSGroup(pathname string) (int64, error) {
return 0, nil
}
// SafeMakeDir makes sure that the created directory does not escape given base directory mis-using symlinks.
func (mounter *Mounter) SafeMakeDir(pathname string, base string, perm os.FileMode) error {
return doSafeMakeDir(pathname, base, perm)

View File

@ -323,3 +323,19 @@ func (mounter *NsenterMounter) PrepareSafeSubpath(subPath Subpath) (newHostPath
func (mounter *NsenterMounter) SafeMakeDir(pathname string, base string, perm os.FileMode) error {
return doSafeMakeDir(pathname, base, perm)
}
func (mounter *NsenterMounter) GetMountRefs(pathname string) ([]string, error) {
hostpath, err := mounter.ne.EvalSymlinks(pathname)
if err != nil {
return nil, err
}
return getMountRefsByDev(mounter, hostpath)
}
func (mounter *NsenterMounter) GetFSGroup(pathname string) (int64, error) {
kubeletpath, err := mounter.ne.KubeletPath(pathname)
if err != nil {
return 0, err
}
return getFSGroup(kubeletpath)
}

View File

@ -98,3 +98,11 @@ func (*NsenterMounter) PrepareSafeSubpath(subPath Subpath) (newHostPath string,
func (*NsenterMounter) CleanSubPaths(podDir string, volumeName string) error {
return nil
}
func (*NsenterMounter) GetMountRefs(pathname string) ([]string, error) {
return nil, errors.New("not implemented")
}
func (*NsenterMounter) GetFSGroup(pathname string) (int64, error) {
return -1, errors.New("not implemented")
}

View File

@ -22,6 +22,7 @@ import (
"fmt"
"os"
"path/filepath"
"strings"
"k8s.io/utils/exec"
@ -122,3 +123,25 @@ func (ne *Nsenter) SupportsSystemd() (string, bool) {
systemdRunPath, hasSystemd := ne.paths["systemd-run"]
return systemdRunPath, hasSystemd
}
// EvalSymlinks returns the path name on the host after evaluating symlinks on the
// host.
func (ne *Nsenter) EvalSymlinks(pathname string) (string, error) {
args := []string{"-m", pathname}
outBytes, err := ne.Exec("realpath", args).CombinedOutput()
if err != nil {
glog.Infof("failed to resolve symbolic links on %s: %v", pathname, err)
return "", err
}
return strings.TrimSpace(string(outBytes)), nil
}
// KubeletPath returns the path name that can be accessed by containerized
// kubelet, after evaluating symlinks on the host.
func (ne *Nsenter) KubeletPath(pathname string) (string, error) {
hostpath, err := ne.EvalSymlinks(pathname)
if err != nil {
return "", err
}
return filepath.Join(hostRootFsPath, hostpath), nil
}

View File

@ -91,6 +91,14 @@ func (mounter *fakeMounter) SafeMakeDir(_, _ string, _ os.FileMode) error {
return nil
}
func (mounter *fakeMounter) GetMountRefs(pathname string) ([]string, error) {
return nil, errors.New("not implemented")
}
func (mounter *fakeMounter) GetFSGroup(pathname string) (int64, error) {
return -1, errors.New("not implemented")
}
func (mounter *fakeMounter) IsLikelyNotMountPoint(file string) (bool, error) {
name := path.Base(file)
if strings.HasPrefix(name, "mount") {

View File

@ -17,6 +17,7 @@ limitations under the License.
package host_path
import (
"errors"
"fmt"
"os"
"testing"
@ -388,6 +389,14 @@ func (fftc *fakeFileTypeChecker) SafeMakeDir(_, _ string, _ os.FileMode) error {
return nil
}
func (fftc *fakeFileTypeChecker) GetMountRefs(pathname string) ([]string, error) {
return nil, errors.New("not implemented")
}
func (fftc *fakeFileTypeChecker) GetFSGroup(pathname string) (int64, error) {
return -1, errors.New("not implemented")
}
func setUp() error {
err := os.MkdirAll("/tmp/ExistingFolder", os.FileMode(0755))
if err != nil {

View File

@ -273,7 +273,7 @@ func (m *localVolumeMounter) SetUpAt(dir string, fsGroup *int64) error {
if !notMnt {
return nil
}
refs, err := mount.GetMountRefsByDev(m.mounter, m.globalPath)
refs, err := m.mounter.GetMountRefs(m.globalPath)
if fsGroup != nil {
if err != nil {
glog.Errorf("cannot collect mounting information: %s %v", m.globalPath, err)
@ -282,11 +282,11 @@ func (m *localVolumeMounter) SetUpAt(dir string, fsGroup *int64) error {
if len(refs) > 0 {
fsGroupNew := int64(*fsGroup)
fsGroupSame, fsGroupOld, err := volume.IsSameFSGroup(m.globalPath, fsGroupNew)
fsGroupOld, err := m.mounter.GetFSGroup(m.globalPath)
if err != nil {
return fmt.Errorf("failed to check fsGroup for %s (%v)", m.globalPath, err)
}
if !fsGroupSame {
if fsGroupNew != fsGroupOld {
m.plugin.recorder.Eventf(m.pod, v1.EventTypeWarning, events.WarnAlreadyMountedVolume, "The requested fsGroup is %d, but the volume %s has GID %d. The volume may not be shareable.", fsGroupNew, m.volName, fsGroupOld)
}
}

View File

@ -509,7 +509,7 @@ func (plugin *rbdPlugin) newUnmapperInternal(volName string, podUID types.UID, m
}
func (plugin *rbdPlugin) getDeviceNameFromOldMountPath(mounter mount.Interface, mountPath string) (string, error) {
refs, err := mount.GetMountRefsByDev(mounter, mountPath)
refs, err := mounter.GetMountRefs(mountPath)
if err != nil {
return "", err
}

View File

@ -89,17 +89,3 @@ func SetVolumeOwnership(mounter Mounter, fsGroup *int64) error {
return nil
})
}
// IsSameFSGroup is called only for requests to mount an already mounted
// volume. It checks if fsGroup of new mount request is the same or not.
// It returns false if it not the same. It also returns current Gid of a path
// provided for dir variable.
func IsSameFSGroup(dir string, fsGroup int64) (bool, int, error) {
info, err := os.Stat(dir)
if err != nil {
glog.Errorf("Error getting stats for %s (%v)", dir, err)
return false, 0, err
}
s := info.Sys().(*syscall.Stat_t)
return int(s.Gid) == int(fsGroup), int(s.Gid), nil
}

View File

@ -21,7 +21,3 @@ package volume
func SetVolumeOwnership(mounter Mounter, fsGroup *int64) error {
return nil
}
func IsSameFSGroup(dir string, fsGroup int64) (bool, int, error) {
return true, int(fsGroup), nil
}

View File

@ -63,26 +63,44 @@ type localVolumeType string
const (
// default local volume type, aka a directory
DirectoryLocalVolumeType localVolumeType = "dir"
// like DirectoryLocalVolumeType but it's a symbolic link to directory
DirectoryLinkLocalVolumeType localVolumeType = "dir-link"
// like DirectoryLocalVolumeType but bind mounted
DirectoryBindMountedLocalVolumeType localVolumeType = "dir-bindmounted"
// like DirectoryLocalVolumeType but it's a symbolic link to self bind mounted directory
// Note that bind mounting at symbolic link actually mounts at directory it
// links to.
DirectoryLinkBindMountedLocalVolumeType localVolumeType = "dir-link-bindmounted"
// creates a tmpfs and mounts it
TmpfsLocalVolumeType localVolumeType = "tmpfs"
// tests based on local ssd at /mnt/disks/by-uuid/
GCELocalSSDVolumeType localVolumeType = "gce-localssd-scsi-fs"
// Creates a local file, formats it, and maps it as a block device.
BlockLocalVolumeType localVolumeType = "block"
// Creates a local file, formats it, and mounts it to use as local volume.
BlockFsLocalVolumeType localVolumeType = "blockfs"
)
var setupLocalVolumeMap = map[localVolumeType]func(*localTestConfig, *v1.Node) *localTestVolume{
GCELocalSSDVolumeType: setupLocalVolumeGCELocalSSD,
TmpfsLocalVolumeType: setupLocalVolumeTmpfs,
DirectoryLocalVolumeType: setupLocalVolumeDirectory,
BlockLocalVolumeType: setupLocalVolumeBlock,
GCELocalSSDVolumeType: setupLocalVolumeGCELocalSSD,
TmpfsLocalVolumeType: setupLocalVolumeTmpfs,
DirectoryLocalVolumeType: setupLocalVolumeDirectory,
DirectoryLinkLocalVolumeType: setupLocalVolumeDirectoryLink,
DirectoryBindMountedLocalVolumeType: setupLocalVolumeDirectoryBindMounted,
DirectoryLinkBindMountedLocalVolumeType: setupLocalVolumeDirectoryLinkBindMounted,
BlockLocalVolumeType: setupLocalVolumeBlock,
BlockFsLocalVolumeType: setupLocalVolumeBlockFs,
}
var cleanupLocalVolumeMap = map[localVolumeType]func(*localTestConfig, *localTestVolume){
GCELocalSSDVolumeType: cleanupLocalVolumeGCELocalSSD,
TmpfsLocalVolumeType: cleanupLocalVolumeTmpfs,
DirectoryLocalVolumeType: cleanupLocalVolumeDirectory,
BlockLocalVolumeType: cleanupLocalVolumeBlock,
GCELocalSSDVolumeType: cleanupLocalVolumeGCELocalSSD,
TmpfsLocalVolumeType: cleanupLocalVolumeTmpfs,
DirectoryLocalVolumeType: cleanupLocalVolumeDirectory,
DirectoryLinkLocalVolumeType: cleanupLocalVolumeDirectoryLink,
DirectoryBindMountedLocalVolumeType: cleanupLocalVolumeDirectoryBindMounted,
DirectoryLinkBindMountedLocalVolumeType: cleanupLocalVolumeDirectoryLinkBindMounted,
BlockLocalVolumeType: cleanupLocalVolumeBlock,
BlockFsLocalVolumeType: cleanupLocalVolumeBlockFs,
}
type localTestVolume struct {
@ -186,8 +204,7 @@ var _ = utils.SIGDescribe("PersistentVolumes-local ", func() {
}
})
localVolumeTypes := []localVolumeType{DirectoryLocalVolumeType, TmpfsLocalVolumeType, GCELocalSSDVolumeType, BlockLocalVolumeType}
for _, tempTestVolType := range localVolumeTypes {
for tempTestVolType := range setupLocalVolumeMap {
// New variable required for gingko test closures
testVolType := tempTestVolType
@ -266,8 +283,21 @@ var _ = utils.SIGDescribe("PersistentVolumes-local ", func() {
})
Context("Set fsGroup for local volume", func() {
BeforeEach(func() {
if testVolType == BlockLocalVolumeType {
framework.Skipf("We don't set fsGroup on block device, skipped.")
}
})
It("should set fsGroup for one pod", func() {
skipTypes := sets.NewString(
string(DirectoryBindMountedLocalVolumeType),
string(DirectoryLinkBindMountedLocalVolumeType),
)
if skipTypes.Has(string(testVolType)) {
// TODO(cofyc): Test it when bug is fixed.
framework.Skipf("Skipped when volume type is %v", testVolType)
}
By("Checking fsGroup is set")
pod := createPodWithFsGroupTest(config, testVol, 1234, 1234)
By("Deleting pod")
@ -275,6 +305,14 @@ var _ = utils.SIGDescribe("PersistentVolumes-local ", func() {
})
It("should set same fsGroup for two pods simultaneously", func() {
skipTypes := sets.NewString(
string(DirectoryBindMountedLocalVolumeType),
string(DirectoryLinkBindMountedLocalVolumeType),
)
if skipTypes.Has(string(testVolType)) {
// TODO(cofyc): Test it when bug is fixed.
framework.Skipf("Skipped when volume type is %v", testVolType)
}
fsGroup := int64(1234)
By("Create first pod and check fsGroup is set")
pod1 := createPodWithFsGroupTest(config, testVol, fsGroup, fsGroup)
@ -287,6 +325,14 @@ var _ = utils.SIGDescribe("PersistentVolumes-local ", func() {
})
It("should set different fsGroup for second pod if first pod is deleted", func() {
skipTypes := sets.NewString(
string(DirectoryBindMountedLocalVolumeType),
string(DirectoryLinkBindMountedLocalVolumeType),
)
if skipTypes.Has(string(testVolType)) {
// TODO(cofyc): Test it when bug is fixed.
framework.Skipf("Skipped when volume type is %v", testVolType)
}
fsGroup1, fsGroup2 := int64(1234), int64(4321)
By("Create first pod and check fsGroup is set")
pod1 := createPodWithFsGroupTest(config, testVol, fsGroup1, fsGroup1)
@ -300,7 +346,13 @@ var _ = utils.SIGDescribe("PersistentVolumes-local ", func() {
})
It("should not set different fsGroups for two pods simultaneously", func() {
if testVolType == DirectoryLocalVolumeType {
skipTypes := sets.NewString(
string(DirectoryLocalVolumeType),
string(DirectoryLinkLocalVolumeType),
string(DirectoryBindMountedLocalVolumeType),
string(DirectoryLinkBindMountedLocalVolumeType),
)
if skipTypes.Has(string(testVolType)) {
// TODO(cofyc): Test it when bug is fixed.
framework.Skipf("Skipped when volume type is %v", testVolType)
}
@ -899,6 +951,39 @@ func setupLocalVolumeDirectory(config *localTestConfig, node *v1.Node) *localTes
return setupWriteTestFile(hostDir, config, DirectoryLocalVolumeType, node)
}
func setupLocalVolumeDirectoryLink(config *localTestConfig, node *v1.Node) *localTestVolume {
testDirName := "local-volume-test-" + string(uuid.NewUUID())
hostDir := filepath.Join(hostBase, testDirName)
hostDirBackend := hostDir + "-backend"
cmd := fmt.Sprintf("mkdir %s && ln -s %s %s", hostDirBackend, hostDirBackend, hostDir)
_, err := framework.IssueSSHCommandWithResult(cmd, framework.TestContext.Provider, node)
Expect(err).NotTo(HaveOccurred())
// Populate volume with testFile containing testFileContent.
return setupWriteTestFile(hostDir, config, DirectoryLinkLocalVolumeType, node)
}
func setupLocalVolumeDirectoryBindMounted(config *localTestConfig, node *v1.Node) *localTestVolume {
testDirName := "local-volume-test-" + string(uuid.NewUUID())
hostDir := filepath.Join(hostBase, testDirName)
cmd := fmt.Sprintf("mkdir %s && sudo mount --bind %s %s", hostDir, hostDir, hostDir)
_, err := framework.IssueSSHCommandWithResult(cmd, framework.TestContext.Provider, node)
Expect(err).NotTo(HaveOccurred())
// Populate volume with testFile containing testFileContent.
return setupWriteTestFile(hostDir, config, DirectoryBindMountedLocalVolumeType, node)
}
func setupLocalVolumeDirectoryLinkBindMounted(config *localTestConfig, node *v1.Node) *localTestVolume {
testDirName := "local-volume-test-" + string(uuid.NewUUID())
hostDir := filepath.Join(hostBase, testDirName)
hostDirBackend := hostDir + "-backend"
cmd := fmt.Sprintf("mkdir %s && sudo mount --bind %s %s && ln -s %s %s",
hostDirBackend, hostDirBackend, hostDirBackend, hostDirBackend, hostDir)
_, err := framework.IssueSSHCommandWithResult(cmd, framework.TestContext.Provider, node)
Expect(err).NotTo(HaveOccurred())
// Populate volume with testFile containing testFileContent.
return setupWriteTestFile(hostDir, config, DirectoryLinkBindMountedLocalVolumeType, node)
}
func setupLocalVolumeBlock(config *localTestConfig, node *v1.Node) *localTestVolume {
testDirName := "local-volume-test-" + string(uuid.NewUUID())
hostDir := filepath.Join(hostBase, testDirName)
@ -911,6 +996,23 @@ func setupLocalVolumeBlock(config *localTestConfig, node *v1.Node) *localTestVol
return volume
}
func setupLocalVolumeBlockFs(config *localTestConfig, node *v1.Node) *localTestVolume {
testDirName := "local-volume-test-" + string(uuid.NewUUID())
hostDir := filepath.Join(hostBase, testDirName)
createAndMapBlockLocalVolume(config, hostDir, node)
loopDev := getBlockLoopDev(hostDir, node)
// format and mount at hostDir
// give others rwx for read/write testing
cmd := fmt.Sprintf("sudo mkfs -t ext4 %s && sudo mount -t ext4 %s %s && sudo chmod o+rwx %s", loopDev, loopDev, hostDir, hostDir)
_, err := framework.IssueSSHCommandWithResult(cmd, framework.TestContext.Provider, node)
Expect(err).NotTo(HaveOccurred())
// Populate block volume with testFile containing testFileContent.
volume := setupWriteTestFile(hostDir, config, BlockFsLocalVolumeType, node)
volume.hostDir = hostDir
volume.loopDevDir = loopDev
return volume
}
// Determine the /dev/loopXXX device associated with this test, via its hostDir.
func getBlockLoopDev(hostDir string, node *v1.Node) string {
loopDevCmd := fmt.Sprintf("E2E_LOOP_DEV=$(sudo losetup | grep %s/file | awk '{ print $1 }') 2>&1 > /dev/null && echo ${E2E_LOOP_DEV}", hostDir)
@ -956,6 +1058,35 @@ func cleanupLocalVolumeDirectory(config *localTestConfig, volume *localTestVolum
Expect(err).NotTo(HaveOccurred())
}
// Deletes the PVC/PV, and launches a pod with hostpath volume to remove the test directory.
func cleanupLocalVolumeDirectoryLink(config *localTestConfig, volume *localTestVolume) {
By("Removing the test directory")
hostDir := volume.hostDir
hostDirBackend := hostDir + "-backend"
removeCmd := fmt.Sprintf("rm -r %s && rm -r %s", hostDir, hostDirBackend)
err := framework.IssueSSHCommand(removeCmd, framework.TestContext.Provider, volume.node)
Expect(err).NotTo(HaveOccurred())
}
// Deletes the PVC/PV, and launches a pod with hostpath volume to remove the test directory.
func cleanupLocalVolumeDirectoryBindMounted(config *localTestConfig, volume *localTestVolume) {
By("Removing the test directory")
hostDir := volume.hostDir
removeCmd := fmt.Sprintf("sudo umount %s && rm -r %s", hostDir, hostDir)
err := framework.IssueSSHCommand(removeCmd, framework.TestContext.Provider, volume.node)
Expect(err).NotTo(HaveOccurred())
}
// Deletes the PVC/PV, and launches a pod with hostpath volume to remove the test directory.
func cleanupLocalVolumeDirectoryLinkBindMounted(config *localTestConfig, volume *localTestVolume) {
By("Removing the test directory")
hostDir := volume.hostDir
hostDirBackend := hostDir + "-backend"
removeCmd := fmt.Sprintf("rm %s && sudo umount %s && rm -r %s", hostDir, hostDirBackend, hostDirBackend)
err := framework.IssueSSHCommand(removeCmd, framework.TestContext.Provider, volume.node)
Expect(err).NotTo(HaveOccurred())
}
// Deletes the PVC/PV and removes the test directory holding the block file.
func cleanupLocalVolumeBlock(config *localTestConfig, volume *localTestVolume) {
volume.hostDir = volume.loopDevDir
@ -966,6 +1097,19 @@ func cleanupLocalVolumeBlock(config *localTestConfig, volume *localTestVolume) {
Expect(err).NotTo(HaveOccurred())
}
// Deletes the PVC/PV and removes the test directory holding the block file.
func cleanupLocalVolumeBlockFs(config *localTestConfig, volume *localTestVolume) {
// umount first
By("Umount blockfs mountpoint")
umountCmd := fmt.Sprintf("sudo umount %s", volume.hostDir)
err := framework.IssueSSHCommand(umountCmd, framework.TestContext.Provider, volume.node)
unmapBlockLocalVolume(config, volume.hostDir, volume.node)
By("Removing the test directory")
removeCmd := fmt.Sprintf("rm -r %s", volume.hostDir)
err = framework.IssueSSHCommand(removeCmd, framework.TestContext.Provider, volume.node)
Expect(err).NotTo(HaveOccurred())
}
func makeLocalPVCConfig(config *localTestConfig, volumeType localVolumeType) framework.PersistentVolumeClaimConfig {
pvcConfig := framework.PersistentVolumeClaimConfig{
AccessModes: []v1.PersistentVolumeAccessMode{v1.ReadWriteOnce},