mirror of https://github.com/k3s-io/k3s
fix host dir, to test volume r/w with different containers within a pod
Signed-off-by: He Simei <hesimei@zju.edu.cn>pull/6/head
parent
8a43bd621e
commit
faeb45d69f
|
@ -20,3 +20,5 @@ test_args
|
||||||
up_to
|
up_to
|
||||||
up_to
|
up_to
|
||||||
valid_flag
|
valid_flag
|
||||||
|
retry_time
|
||||||
|
file_content_in_loop
|
||||||
|
|
|
@ -242,3 +242,5 @@ user-whitelist
|
||||||
watch-only
|
watch-only
|
||||||
whitelist-override-label
|
whitelist-override-label
|
||||||
www-prefix
|
www-prefix
|
||||||
|
retry_time
|
||||||
|
file_content_in_loop
|
||||||
|
|
|
@ -18,21 +18,21 @@ package e2e
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"path"
|
|
||||||
|
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
"k8s.io/kubernetes/pkg/api/latest"
|
"k8s.io/kubernetes/pkg/api/latest"
|
||||||
"k8s.io/kubernetes/pkg/util"
|
"k8s.io/kubernetes/pkg/util"
|
||||||
|
"path"
|
||||||
|
|
||||||
. "github.com/onsi/ginkgo"
|
. "github.com/onsi/ginkgo"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
testImageRootUid = "gcr.io/google_containers/mounttest:0.3"
|
testImageRootUid = "gcr.io/google_containers/mounttest:0.4"
|
||||||
testImageNonRootUid = "gcr.io/google_containers/mounttest-user:0.1"
|
testImageNonRootUid = "gcr.io/google_containers/mounttest-user:0.2"
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ = Describe("EmptyDir volumes", func() {
|
var _ = Describe("EmptyDir volumes", func() {
|
||||||
|
|
||||||
f := NewFramework("emptydir")
|
f := NewFramework("emptydir")
|
||||||
|
|
||||||
It("volume on tmpfs should have the correct mode", func() {
|
It("volume on tmpfs should have the correct mode", func() {
|
||||||
|
@ -204,7 +204,6 @@ func formatMedium(medium api.StorageMedium) string {
|
||||||
|
|
||||||
func testPodWithVolume(image, path string, source *api.EmptyDirVolumeSource) *api.Pod {
|
func testPodWithVolume(image, path string, source *api.EmptyDirVolumeSource) *api.Pod {
|
||||||
podName := "pod-" + string(util.NewUUID())
|
podName := "pod-" + string(util.NewUUID())
|
||||||
|
|
||||||
return &api.Pod{
|
return &api.Pod{
|
||||||
TypeMeta: api.TypeMeta{
|
TypeMeta: api.TypeMeta{
|
||||||
Kind: "Pod",
|
Kind: "Pod",
|
||||||
|
|
|
@ -21,7 +21,6 @@ import (
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
"k8s.io/kubernetes/pkg/api/latest"
|
"k8s.io/kubernetes/pkg/api/latest"
|
||||||
client "k8s.io/kubernetes/pkg/client/unversioned"
|
client "k8s.io/kubernetes/pkg/client/unversioned"
|
||||||
"k8s.io/kubernetes/pkg/util"
|
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
|
|
||||||
|
@ -77,18 +76,24 @@ var _ = Describe("hostPath", func() {
|
||||||
It("should support r/w", func() {
|
It("should support r/w", func() {
|
||||||
volumePath := "/test-volume"
|
volumePath := "/test-volume"
|
||||||
filePath := path.Join(volumePath, "test-file")
|
filePath := path.Join(volumePath, "test-file")
|
||||||
|
retryDuration := 180
|
||||||
source := &api.HostPathVolumeSource{
|
source := &api.HostPathVolumeSource{
|
||||||
Path: "/tmp",
|
Path: "/tmp",
|
||||||
}
|
}
|
||||||
pod := testPodWithHostVol(volumePath, source)
|
pod := testPodWithHostVol(volumePath, source)
|
||||||
|
|
||||||
pod.Spec.Containers[0].Args = []string{
|
pod.Spec.Containers[0].Args = []string{
|
||||||
fmt.Sprintf("--fs_type=%v", volumePath),
|
fmt.Sprintf("--new_file_0644=%v", filePath),
|
||||||
fmt.Sprintf("--rw_new_file=%v", filePath),
|
|
||||||
fmt.Sprintf("--file_mode=%v", filePath),
|
fmt.Sprintf("--file_mode=%v", filePath),
|
||||||
}
|
}
|
||||||
testContainerOutputInNamespace("hostPath r/w", c, pod, 0, []string{
|
|
||||||
"mode of file \"/test-volume/test-file\": -rw-r--r--",
|
pod.Spec.Containers[1].Args = []string{
|
||||||
|
fmt.Sprintf("--file_content_in_loop=%v", filePath),
|
||||||
|
fmt.Sprintf("--retry_time=%d", retryDuration),
|
||||||
|
}
|
||||||
|
//Read the content of the file with the second container to
|
||||||
|
//verify volumes being shared properly among continers within the pod.
|
||||||
|
testContainerOutputInNamespace("hostPath r/w", c, pod, 1, []string{
|
||||||
"content of file \"/test-volume/test-file\": mount-tester new file",
|
"content of file \"/test-volume/test-file\": mount-tester new file",
|
||||||
}, namespace.Name,
|
}, namespace.Name,
|
||||||
)
|
)
|
||||||
|
@ -96,8 +101,9 @@ var _ = Describe("hostPath", func() {
|
||||||
})
|
})
|
||||||
|
|
||||||
//These constants are borrowed from the other test.
|
//These constants are borrowed from the other test.
|
||||||
//const containerName = "test-container"
|
|
||||||
//const volumeName = "test-volume"
|
//const volumeName = "test-volume"
|
||||||
|
const containerName1 = "test-container-1"
|
||||||
|
const containerName2 = "test-container-2"
|
||||||
|
|
||||||
func mount(source *api.HostPathVolumeSource) []api.Volume {
|
func mount(source *api.HostPathVolumeSource) []api.Volume {
|
||||||
return []api.Volume{
|
return []api.Volume{
|
||||||
|
@ -112,7 +118,7 @@ func mount(source *api.HostPathVolumeSource) []api.Volume {
|
||||||
|
|
||||||
//TODO: To merge this with the emptyDir tests, we can make source a lambda.
|
//TODO: To merge this with the emptyDir tests, we can make source a lambda.
|
||||||
func testPodWithHostVol(path string, source *api.HostPathVolumeSource) *api.Pod {
|
func testPodWithHostVol(path string, source *api.HostPathVolumeSource) *api.Pod {
|
||||||
podName := "pod-" + string(util.NewUUID())
|
podName := "pod-host-path-test"
|
||||||
|
|
||||||
return &api.Pod{
|
return &api.Pod{
|
||||||
TypeMeta: api.TypeMeta{
|
TypeMeta: api.TypeMeta{
|
||||||
|
@ -125,8 +131,18 @@ func testPodWithHostVol(path string, source *api.HostPathVolumeSource) *api.Pod
|
||||||
Spec: api.PodSpec{
|
Spec: api.PodSpec{
|
||||||
Containers: []api.Container{
|
Containers: []api.Container{
|
||||||
{
|
{
|
||||||
Name: containerName,
|
Name: containerName1,
|
||||||
Image: "gcr.io/google_containers/mounttest:0.2",
|
Image: "gcr.io/google_containers/mounttest:0.4",
|
||||||
|
VolumeMounts: []api.VolumeMount{
|
||||||
|
{
|
||||||
|
Name: volumeName,
|
||||||
|
MountPath: path,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: containerName2,
|
||||||
|
Image: "gcr.io/google_containers/mounttest:0.4",
|
||||||
VolumeMounts: []api.VolumeMount{
|
VolumeMounts: []api.VolumeMount{
|
||||||
{
|
{
|
||||||
Name: volumeName,
|
Name: volumeName,
|
||||||
|
|
|
@ -12,5 +12,5 @@
|
||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
FROM gcr.io/google_containers/mounttest:0.3
|
FROM gcr.io/google_containers/mounttest:0.4
|
||||||
USER 1001
|
USER 1001
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
all: push
|
all: push
|
||||||
|
|
||||||
TAG = 0.1
|
TAG = 0.2
|
||||||
|
|
||||||
image:
|
image:
|
||||||
sudo docker build -t gcr.io/google_containers/mounttest-user:$(TAG) .
|
sudo docker build -t gcr.io/google_containers/mounttest-user:$(TAG) .
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
all: push
|
all: push
|
||||||
|
|
||||||
TAG = 0.3
|
TAG = 0.4
|
||||||
|
|
||||||
mt: mt.go
|
mt: mt.go
|
||||||
CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -ldflags '-w' ./mt.go
|
CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -ldflags '-w' ./mt.go
|
||||||
|
|
|
@ -22,26 +22,31 @@ import (
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
fsTypePath = ""
|
fsTypePath = ""
|
||||||
fileModePath = ""
|
fileModePath = ""
|
||||||
filePermPath = ""
|
filePermPath = ""
|
||||||
readFileContentPath = ""
|
|
||||||
newFilePath0644 = ""
|
newFilePath0644 = ""
|
||||||
newFilePath0666 = ""
|
newFilePath0666 = ""
|
||||||
newFilePath0777 = ""
|
newFilePath0777 = ""
|
||||||
|
readFileContentPath = ""
|
||||||
|
readFileContentInLoopPath = ""
|
||||||
|
retryDuration = 180
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
flag.StringVar(&fsTypePath, "fs_type", "", "Path to print the fs type for")
|
flag.StringVar(&fsTypePath, "fs_type", "", "Path to print the fs type for")
|
||||||
flag.StringVar(&fileModePath, "file_mode", "", "Path to print the mode bits of")
|
flag.StringVar(&fileModePath, "file_mode", "", "Path to print the mode bits of")
|
||||||
flag.StringVar(&filePermPath, "file_perm", "", "Path to print the perms of")
|
flag.StringVar(&filePermPath, "file_perm", "", "Path to print the perms of")
|
||||||
flag.StringVar(&readFileContentPath, "file_content", "", "Path to read the file content from")
|
|
||||||
flag.StringVar(&newFilePath0644, "new_file_0644", "", "Path to write to and read from with perm 0644")
|
flag.StringVar(&newFilePath0644, "new_file_0644", "", "Path to write to and read from with perm 0644")
|
||||||
flag.StringVar(&newFilePath0666, "new_file_0666", "", "Path to write to and read from with perm 0666")
|
flag.StringVar(&newFilePath0666, "new_file_0666", "", "Path to write to and read from with perm 0666")
|
||||||
flag.StringVar(&newFilePath0777, "new_file_0777", "", "Path to write to and read from with perm 0777")
|
flag.StringVar(&newFilePath0777, "new_file_0777", "", "Path to write to and read from with perm 0777")
|
||||||
|
flag.StringVar(&readFileContentPath, "file_content", "", "Path to read the file content from")
|
||||||
|
flag.StringVar(&readFileContentInLoopPath, "file_content_in_loop", "", "Path to read the file content in loop from")
|
||||||
|
flag.IntVar(&retryDuration, "retry_time", 180, "Retry time during the loop")
|
||||||
}
|
}
|
||||||
|
|
||||||
// This program performs some tests on the filesystem as dictated by the
|
// This program performs some tests on the filesystem as dictated by the
|
||||||
|
@ -101,6 +106,11 @@ func main() {
|
||||||
errs = append(errs, err)
|
errs = append(errs, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
err = readFileContentInLoop(readFileContentInLoopPath, retryDuration)
|
||||||
|
if err != nil {
|
||||||
|
errs = append(errs, err)
|
||||||
|
}
|
||||||
|
|
||||||
if len(errs) != 0 {
|
if len(errs) != 0 {
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
@ -191,3 +201,40 @@ func readWriteNewFile(path string, perm os.FileMode) error {
|
||||||
|
|
||||||
return readFileContent(path)
|
return readFileContent(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func readFileContentInLoop(path string, retryDuration int) error {
|
||||||
|
if path == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
var content []byte
|
||||||
|
content = testFileContent(path, retryDuration)
|
||||||
|
|
||||||
|
fmt.Printf("content of file %q: %v\n", path, string(content))
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func testFileContent(filePath string, retryDuration int) []byte {
|
||||||
|
var (
|
||||||
|
contentBytes []byte
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
|
||||||
|
retryTime := time.Second * time.Duration(retryDuration)
|
||||||
|
for start := time.Now(); time.Since(start) < retryTime; time.Sleep(2 * time.Second) {
|
||||||
|
contentBytes, err = ioutil.ReadFile(filePath)
|
||||||
|
if err == nil {
|
||||||
|
//Expected content "mount-tester new file\n", length 22
|
||||||
|
if len(contentBytes) == 22 {
|
||||||
|
break
|
||||||
|
} else {
|
||||||
|
fmt.Printf("Unexpected length of file: found %d, expected %d.Retry", len(contentBytes), 22)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fmt.Printf("Error read file %s: %v, retry", filePath, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return contentBytes
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue