diff --git a/pkg/kubelet/kubelet_getters.go b/pkg/kubelet/kubelet_getters.go index d4e40621f7e..e7c3591d809 100644 --- a/pkg/kubelet/kubelet_getters.go +++ b/pkg/kubelet/kubelet_getters.go @@ -20,7 +20,7 @@ import ( "fmt" "io/ioutil" "net" - "path" + "path/filepath" "github.com/golang/glog" "k8s.io/apimachinery/pkg/types" @@ -44,7 +44,7 @@ func (kl *Kubelet) getRootDir() string { // getPodsDir returns the full path to the directory under which pod // directories are created. func (kl *Kubelet) getPodsDir() string { - return path.Join(kl.getRootDir(), options.DefaultKubeletPodsDirName) + return filepath.Join(kl.getRootDir(), options.DefaultKubeletPodsDirName) } // getPluginsDir returns the full path to the directory under which plugin @@ -52,14 +52,14 @@ func (kl *Kubelet) getPodsDir() string { // they need to persist. Plugins should create subdirectories under this named // after their own names. func (kl *Kubelet) getPluginsDir() string { - return path.Join(kl.getRootDir(), options.DefaultKubeletPluginsDirName) + return filepath.Join(kl.getRootDir(), options.DefaultKubeletPluginsDirName) } // getPluginDir returns a data directory name for a given plugin name. // Plugins can use these directories to store data that they need to persist. // For per-pod plugin data, see getPodPluginDir. func (kl *Kubelet) getPluginDir(pluginName string) string { - return path.Join(kl.getPluginsDir(), pluginName) + return filepath.Join(kl.getPluginsDir(), pluginName) } // GetPodDir returns the full path to the per-pod data directory for the @@ -77,9 +77,9 @@ func (kl *Kubelet) getPodDir(podUID types.UID) string { // !old && new = use new // old && !new = use old // old && new = use new (but warn) - oldPath := path.Join(kl.getRootDir(), string(podUID)) + oldPath := filepath.Join(kl.getRootDir(), string(podUID)) oldExists := dirExists(oldPath) - newPath := path.Join(kl.getPodsDir(), string(podUID)) + newPath := filepath.Join(kl.getPodsDir(), string(podUID)) newExists := dirExists(newPath) if oldExists && !newExists { return oldPath @@ -94,28 +94,28 @@ func (kl *Kubelet) getPodDir(podUID types.UID) string { // which volumes are created for the specified pod. This directory may not // exist if the pod does not exist. func (kl *Kubelet) getPodVolumesDir(podUID types.UID) string { - return path.Join(kl.getPodDir(podUID), options.DefaultKubeletVolumesDirName) + return filepath.Join(kl.getPodDir(podUID), options.DefaultKubeletVolumesDirName) } // getPodVolumeDir returns the full path to the directory which represents the // named volume under the named plugin for specified pod. This directory may not // exist if the pod does not exist. func (kl *Kubelet) getPodVolumeDir(podUID types.UID, pluginName string, volumeName string) string { - return path.Join(kl.getPodVolumesDir(podUID), pluginName, volumeName) + return filepath.Join(kl.getPodVolumesDir(podUID), pluginName, volumeName) } // getPodPluginsDir returns the full path to the per-pod data directory under // which plugins may store data for the specified pod. This directory may not // exist if the pod does not exist. func (kl *Kubelet) getPodPluginsDir(podUID types.UID) string { - return path.Join(kl.getPodDir(podUID), options.DefaultKubeletPluginsDirName) + return filepath.Join(kl.getPodDir(podUID), options.DefaultKubeletPluginsDirName) } // getPodPluginDir returns a data directory name for a given plugin name for a // given pod UID. Plugins can use these directories to store data that they // need to persist. For non-per-pod plugin data, see getPluginDir. func (kl *Kubelet) getPodPluginDir(podUID types.UID, pluginName string) string { - return path.Join(kl.getPodPluginsDir(podUID), pluginName) + return filepath.Join(kl.getPodPluginsDir(podUID), pluginName) } // getPodContainerDir returns the full path to the per-pod data directory under @@ -128,9 +128,9 @@ func (kl *Kubelet) getPodContainerDir(podUID types.UID, ctrName string) string { // !old && new = use new // old && !new = use old // old && new = use new (but warn) - oldPath := path.Join(kl.getPodDir(podUID), ctrName) + oldPath := filepath.Join(kl.getPodDir(podUID), ctrName) oldExists := dirExists(oldPath) - newPath := path.Join(kl.getPodDir(podUID), options.DefaultKubeletContainersDirName, ctrName) + newPath := filepath.Join(kl.getPodDir(podUID), options.DefaultKubeletContainersDirName, ctrName) newExists := dirExists(newPath) if oldExists && !newExists { return oldPath @@ -260,13 +260,13 @@ func (kl *Kubelet) getPodVolumePathListFromDisk(podUID types.UID) ([]string, err } for _, volumePluginDir := range volumePluginDirs { volumePluginName := volumePluginDir.Name() - volumePluginPath := path.Join(podVolDir, volumePluginName) + volumePluginPath := filepath.Join(podVolDir, volumePluginName) volumeDirs, err := util.ReadDirNoStat(volumePluginPath) if err != nil { return volumes, fmt.Errorf("Could not read directory %s: %v", volumePluginPath, err) } for _, volumeDir := range volumeDirs { - volumes = append(volumes, path.Join(volumePluginPath, volumeDir)) + volumes = append(volumes, filepath.Join(volumePluginPath, volumeDir)) } } return volumes, nil diff --git a/pkg/kubelet/kubelet_getters_test.go b/pkg/kubelet/kubelet_getters_test.go index c72145d9750..34169748392 100644 --- a/pkg/kubelet/kubelet_getters_test.go +++ b/pkg/kubelet/kubelet_getters_test.go @@ -19,7 +19,7 @@ package kubelet import ( "fmt" "os" - "path" + "path/filepath" "testing" ) @@ -32,55 +32,55 @@ func TestKubeletDirs(t *testing.T) { var exp, got string got = kubelet.getPodsDir() - exp = path.Join(root, "pods") + exp = filepath.Join(root, "pods") if got != exp { t.Errorf("expected %q', got %q", exp, got) } got = kubelet.getPluginsDir() - exp = path.Join(root, "plugins") + exp = filepath.Join(root, "plugins") if got != exp { t.Errorf("expected %q', got %q", exp, got) } got = kubelet.getPluginDir("foobar") - exp = path.Join(root, "plugins/foobar") + exp = filepath.Join(root, "plugins/foobar") if got != exp { t.Errorf("expected %q', got %q", exp, got) } got = kubelet.getPodDir("abc123") - exp = path.Join(root, "pods/abc123") + exp = filepath.Join(root, "pods/abc123") if got != exp { t.Errorf("expected %q', got %q", exp, got) } got = kubelet.getPodVolumesDir("abc123") - exp = path.Join(root, "pods/abc123/volumes") + exp = filepath.Join(root, "pods/abc123/volumes") if got != exp { t.Errorf("expected %q', got %q", exp, got) } got = kubelet.getPodVolumeDir("abc123", "plugin", "foobar") - exp = path.Join(root, "pods/abc123/volumes/plugin/foobar") + exp = filepath.Join(root, "pods/abc123/volumes/plugin/foobar") if got != exp { t.Errorf("expected %q', got %q", exp, got) } got = kubelet.getPodPluginsDir("abc123") - exp = path.Join(root, "pods/abc123/plugins") + exp = filepath.Join(root, "pods/abc123/plugins") if got != exp { t.Errorf("expected %q', got %q", exp, got) } got = kubelet.getPodPluginDir("abc123", "foobar") - exp = path.Join(root, "pods/abc123/plugins/foobar") + exp = filepath.Join(root, "pods/abc123/plugins/foobar") if got != exp { t.Errorf("expected %q', got %q", exp, got) } got = kubelet.getPodContainerDir("abc123", "def456") - exp = path.Join(root, "pods/abc123/containers/def456") + exp = filepath.Join(root, "pods/abc123/containers/def456") if got != exp { t.Errorf("expected %q', got %q", exp, got) } @@ -114,25 +114,25 @@ func TestKubeletDirsCompat(t *testing.T) { } got = kubelet.getPodDir("oldpod") - exp = path.Join(root, "oldpod") + exp = filepath.Join(root, "oldpod") if got != exp { t.Errorf("expected %q', got %q", exp, got) } got = kubelet.getPodDir("newpod") - exp = path.Join(root, "pods/newpod") + exp = filepath.Join(root, "pods/newpod") if got != exp { t.Errorf("expected %q', got %q", exp, got) } got = kubelet.getPodDir("bothpod") - exp = path.Join(root, "pods/bothpod") + exp = filepath.Join(root, "pods/bothpod") if got != exp { t.Errorf("expected %q', got %q", exp, got) } got = kubelet.getPodDir("neitherpod") - exp = path.Join(root, "pods/neitherpod") + exp = filepath.Join(root, "pods/neitherpod") if got != exp { t.Errorf("expected %q', got %q", exp, got) } @@ -156,25 +156,25 @@ func TestKubeletDirsCompat(t *testing.T) { } got = kubelet.getPodContainerDir("newpod", "oldctr") - exp = path.Join(root, "oldctr") + exp = filepath.Join(root, "oldctr") if got != exp { t.Errorf("expected %q', got %q", exp, got) } got = kubelet.getPodContainerDir("newpod", "newctr") - exp = path.Join(root, "containers/newctr") + exp = filepath.Join(root, "containers/newctr") if got != exp { t.Errorf("expected %q', got %q", exp, got) } got = kubelet.getPodContainerDir("newpod", "bothctr") - exp = path.Join(root, "containers/bothctr") + exp = filepath.Join(root, "containers/bothctr") if got != exp { t.Errorf("expected %q', got %q", exp, got) } got = kubelet.getPodContainerDir("newpod", "neitherctr") - exp = path.Join(root, "containers/neitherctr") + exp = filepath.Join(root, "containers/neitherctr") if got != exp { t.Errorf("expected %q', got %q", exp, got) } diff --git a/pkg/kubelet/kubelet_pods.go b/pkg/kubelet/kubelet_pods.go index 4529edd4c0a..cf3a0a83914 100644 --- a/pkg/kubelet/kubelet_pods.go +++ b/pkg/kubelet/kubelet_pods.go @@ -138,10 +138,10 @@ func makeMounts(pod *v1.Pod, podDir string, container *v1.Container, hostName, h // Docker Volume Mounts fail on Windows if it is not of the form C:/ containerPath := mount.MountPath if runtime.GOOS == "windows" { - if strings.HasPrefix(hostPath, "/") && !strings.Contains(hostPath, ":") { + if (strings.HasPrefix(hostPath, "/") || strings.HasPrefix(hostPath, "\\")) && !strings.Contains(hostPath, ":") { hostPath = "c:" + hostPath } - if strings.HasPrefix(containerPath, "/") && !strings.Contains(containerPath, ":") { + if (strings.HasPrefix(containerPath, "/") || strings.HasPrefix(containerPath, "\\")) && !strings.Contains(containerPath, ":") { containerPath = "c:" + containerPath } } diff --git a/pkg/kubelet/kubelet_pods_windows_test.go b/pkg/kubelet/kubelet_pods_windows_test.go new file mode 100644 index 00000000000..3b0d15afb57 --- /dev/null +++ b/pkg/kubelet/kubelet_pods_windows_test.go @@ -0,0 +1,100 @@ +// +build windows + +/* +Copyright 2017 The Kubernetes Authors. + +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 kubelet + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "k8s.io/kubernetes/pkg/api/v1" + kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" +) + +func TestMakeMountsWindows(t *testing.T) { + container := v1.Container{ + VolumeMounts: []v1.VolumeMount{ + { + MountPath: "c:/etc/hosts", + Name: "disk", + ReadOnly: false, + }, + { + MountPath: "c:/mnt/path3", + Name: "disk", + ReadOnly: true, + }, + { + MountPath: "c:/mnt/path4", + Name: "disk4", + ReadOnly: false, + }, + { + MountPath: "c:/mnt/path5", + Name: "disk5", + ReadOnly: false, + }, + }, + } + + podVolumes := kubecontainer.VolumeMap{ + "disk": kubecontainer.VolumeInfo{Mounter: &stubVolume{path: "c:/mnt/disk"}}, + "disk4": kubecontainer.VolumeInfo{Mounter: &stubVolume{path: "c:/mnt/host"}}, + "disk5": kubecontainer.VolumeInfo{Mounter: &stubVolume{path: "c:/var/lib/kubelet/podID/volumes/empty/disk5"}}, + } + + pod := v1.Pod{ + Spec: v1.PodSpec{ + HostNetwork: true, + }, + } + + mounts, _ := makeMounts(&pod, "/pod", &container, "fakepodname", "", "", podVolumes) + + expectedMounts := []kubecontainer.Mount{ + { + Name: "disk", + ContainerPath: "c:/etc/hosts", + HostPath: "c:/mnt/disk", + ReadOnly: false, + SELinuxRelabel: false, + }, + { + Name: "disk", + ContainerPath: "c:/mnt/path3", + HostPath: "c:/mnt/disk", + ReadOnly: true, + SELinuxRelabel: false, + }, + { + Name: "disk4", + ContainerPath: "c:/mnt/path4", + HostPath: "c:/mnt/host", + ReadOnly: false, + SELinuxRelabel: false, + }, + { + Name: "disk5", + ContainerPath: "c:/mnt/path5", + HostPath: "c:/var/lib/kubelet/podID/volumes/empty/disk5", + ReadOnly: false, + SELinuxRelabel: false, + }, + } + assert.Equal(t, expectedMounts, mounts, "mounts of container %+v", container) +} diff --git a/pkg/volume/secret/secret.go b/pkg/volume/secret/secret.go index f3af74dba46..983daba6f60 100644 --- a/pkg/volume/secret/secret.go +++ b/pkg/volume/secret/secret.go @@ -18,8 +18,6 @@ package secret import ( "fmt" - "path/filepath" - "runtime" "github.com/golang/glog" "k8s.io/apimachinery/pkg/api/errors" @@ -173,12 +171,7 @@ func (b *secretVolumeMounter) CanMount() error { } func (b *secretVolumeMounter) SetUp(fsGroup *int64) error { - // Update each Slash "/" character for Windows with seperator character - dir := b.GetPath() - if runtime.GOOS == "windows" { - dir = filepath.FromSlash(dir) - } - return b.SetUpAt(dir, fsGroup) + return b.SetUpAt(b.GetPath(), fsGroup) } func (b *secretVolumeMounter) SetUpAt(dir string, fsGroup *int64) error { @@ -297,12 +290,7 @@ type secretVolumeUnmounter struct { var _ volume.Unmounter = &secretVolumeUnmounter{} func (c *secretVolumeUnmounter) TearDown() error { - // Update each Slash "/" character for Windows with seperator character - dir := c.GetPath() - if runtime.GOOS == "windows" { - dir = filepath.FromSlash(dir) - } - return c.TearDownAt(dir) + return c.TearDownAt(c.GetPath()) } func (c *secretVolumeUnmounter) TearDownAt(dir string) error {