From e39a8e33ce5e637ad7a09ac2c21167652224707f Mon Sep 17 00:00:00 2001 From: Paul Morie Date: Wed, 8 Apr 2015 22:54:23 +0800 Subject: [PATCH 1/2] Add mount test image --- contrib/for-tests/mount-tester/Dockerfile | 17 +++ contrib/for-tests/mount-tester/Makefile | 15 +++ contrib/for-tests/mount-tester/mt.go | 145 ++++++++++++++++++++++ 3 files changed, 177 insertions(+) create mode 100644 contrib/for-tests/mount-tester/Dockerfile create mode 100644 contrib/for-tests/mount-tester/Makefile create mode 100644 contrib/for-tests/mount-tester/mt.go diff --git a/contrib/for-tests/mount-tester/Dockerfile b/contrib/for-tests/mount-tester/Dockerfile new file mode 100644 index 00000000000..e2485a12ef8 --- /dev/null +++ b/contrib/for-tests/mount-tester/Dockerfile @@ -0,0 +1,17 @@ +# Copyright 2015 Google Inc. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +FROM scratch +ADD mt mt +ENTRYPOINT ["/mt"] diff --git a/contrib/for-tests/mount-tester/Makefile b/contrib/for-tests/mount-tester/Makefile new file mode 100644 index 00000000000..c11ef5fcd5d --- /dev/null +++ b/contrib/for-tests/mount-tester/Makefile @@ -0,0 +1,15 @@ +all: push + +TAG = 0.1 + +mt: mt.go + CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -ldflags '-w' ./mt.go + +image: mt + sudo docker build -t kubernetes/mounttest:$(TAG) . + +push: image + sudo docker push kubernetes/mounttest:$(TAG) + +clean: + rm -f mt diff --git a/contrib/for-tests/mount-tester/mt.go b/contrib/for-tests/mount-tester/mt.go new file mode 100644 index 00000000000..be2fa484df4 --- /dev/null +++ b/contrib/for-tests/mount-tester/mt.go @@ -0,0 +1,145 @@ +/* +Copyright 2015 Google Inc. All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package main + +import ( + "flag" + "fmt" + "io/ioutil" + "os" + "syscall" +) + +var ( + fsTypePath = "" + fileModePath = "" + readFileContentPath = "" + readWriteNewFilePath = "" +) + +func init() { + flag.StringVar(&fsTypePath, "fs_type", "", "Path to print the fs type for") + flag.StringVar(&fileModePath, "file_mode", "", "Path to print the filemode of") + flag.StringVar(&readFileContentPath, "file_content", "", "Path to read the file content from") + flag.StringVar(&readWriteNewFilePath, "rw_new_file", "", "Path to write to and read from") +} + +// This program performs some tests on the filesystem as dictated by the +// flags passed by the user. +func main() { + flag.Parse() + + var ( + err error + errs = []error{} + ) + + err = fsType(fsTypePath) + if err != nil { + errs = append(errs, err) + } + + err = readWriteNewFile(readWriteNewFilePath) + if err != nil { + errs = append(errs, err) + } + + err = fileMode(fileModePath) + if err != nil { + errs = append(errs, err) + } + + err = readFileContent(readFileContentPath) + if err != nil { + errs = append(errs, err) + } + + if len(errs) != 0 { + os.Exit(1) + } + + os.Exit(0) +} + +// Defined by Linux (sys/statfs.h) - the type number for tmpfs mounts. +const linuxTmpfsMagic = 0x01021994 + +func fsType(path string) error { + if path == "" { + return nil + } + + buf := syscall.Statfs_t{} + if err := syscall.Statfs(path, &buf); err != nil { + fmt.Printf("error from statfs(%q): %v", path, err) + return err + } + + if buf.Type == linuxTmpfsMagic { + fmt.Printf("mount type of %q: tmpfs\n", path) + } else { + fmt.Printf("mount type of %q: %v\n", path, buf.Type) + } + + return nil +} + +func fileMode(path string) error { + if path == "" { + return nil + } + + fileinfo, err := os.Lstat(path) + if err != nil { + fmt.Printf("error from Lstat(%q): %v\n", path, err) + return err + } + + fmt.Printf("mode of file %q: %v\n", path, fileinfo.Mode()) + return nil +} + +func readFileContent(path string) error { + if path == "" { + return nil + } + + contentBytes, err := ioutil.ReadFile(path) + if err != nil { + fmt.Printf("error reading file content for %q: %v\n", path, err) + return err + } + + fmt.Printf("content of file %q: %v\n", path, string(contentBytes)) + + return nil +} + +func readWriteNewFile(path string) error { + if path == "" { + return nil + } + + content := "mount-tester new file\n" + err := ioutil.WriteFile(path, []byte(content), 0644) + if err != nil { + fmt.Printf("error writing new file %q: %v\n", path, err) + return err + } + + return readFileContent(path) +} From 6f80df8ea16d46c8b3422964a4b575703d0b909d Mon Sep 17 00:00:00 2001 From: yaoguo Date: Wed, 8 Apr 2015 22:56:09 +0800 Subject: [PATCH 2/2] Add e2e test for emptyDir --- test/e2e/empty_dir.go | 119 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 test/e2e/empty_dir.go diff --git a/test/e2e/empty_dir.go b/test/e2e/empty_dir.go new file mode 100644 index 00000000000..679caaf5044 --- /dev/null +++ b/test/e2e/empty_dir.go @@ -0,0 +1,119 @@ +/* +Copyright 2015 Google Inc. All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package e2e + +import ( + "fmt" + "path" + + "github.com/GoogleCloudPlatform/kubernetes/pkg/api" + "github.com/GoogleCloudPlatform/kubernetes/pkg/client" + "github.com/GoogleCloudPlatform/kubernetes/pkg/util" + + . "github.com/onsi/ginkgo" +) + +var _ = Describe("emptyDir", func() { + var ( + c *client.Client + podClient client.PodInterface + ) + + BeforeEach(func() { + var err error + c, err = loadClient() + expectNoError(err) + + podClient = c.Pods(api.NamespaceDefault) + }) + + It("volume on tmpfs should have the correct mode", func() { + volumePath := "/test-volume" + source := &api.EmptyDirVolumeSource{ + Medium: api.StorageTypeMemory, + } + pod := testPodWithVolume(volumePath, source) + + pod.Spec.Containers[0].Args = []string{ + fmt.Sprintf("--fs_type=%v", volumePath), + fmt.Sprintf("--file_mode=%v", volumePath), + } + testContainerOutput("emptydir r/w on tmpfs", c, pod, []string{ + "mount type of \"/test-volume\": tmpfs", + "mode of file \"/test-volume\": dtrwxrwxrwx", // we expect the sticky bit (mode flag t) to be set for the dir + }) + }) + + It("should support r/w on tmpfs", func() { + volumePath := "/test-volume" + filePath := path.Join(volumePath, "test-file") + source := &api.EmptyDirVolumeSource{ + Medium: api.StorageTypeMemory, + } + pod := testPodWithVolume(volumePath, source) + + pod.Spec.Containers[0].Args = []string{ + fmt.Sprintf("--fs_type=%v", volumePath), + fmt.Sprintf("--rw_new_file=%v", filePath), + fmt.Sprintf("--file_mode=%v", filePath), + } + testContainerOutput("emptydir r/w on tmpfs", c, pod, []string{ + "mount type of \"/test-volume\": tmpfs", + "mode of file \"/test-volume/test-file\": -rw-r--r--", + "content of file \"/test-volume/test-file\": mount-tester new file", + }) + }) +}) + +const containerName = "test-container" +const volumeName = "test-volume" + +func testPodWithVolume(path string, source *api.EmptyDirVolumeSource) *api.Pod { + podName := "pod-" + string(util.NewUUID()) + + return &api.Pod{ + TypeMeta: api.TypeMeta{ + Kind: "Pod", + APIVersion: "v1beta1", + }, + ObjectMeta: api.ObjectMeta{ + Name: podName, + }, + Spec: api.PodSpec{ + Containers: []api.Container{ + { + Name: containerName, + Image: "kubernetes/mounttest:0.1", + VolumeMounts: []api.VolumeMount{ + { + Name: volumeName, + MountPath: path, + }, + }, + }, + }, + Volumes: []api.Volume{ + { + Name: volumeName, + VolumeSource: api.VolumeSource{ + EmptyDir: source, + }, + }, + }, + }, + } +}