Merge pull request #39373 from apprenda/fix_configmap

Automatic merge from submit-queue (batch tested with PRs 39373, 41585, 41617, 41707, 39958)

Fix ConfigMaps for Windows

**What this PR does / why we need it**: ConfigMaps were broken for Windows as the existing code used linux specific file paths. Updated the code in `kubelet_getters.go` to use `path/filepath` to get the directories. Also reverted back the code in `secret.go` as updating `kubelet_getters.go` to use `path/filepath` also fixes `secrets`

**Which issue this PR fixes** *(optional, in `fixes #<issue number>(, fixes #<issue_number>, ...)` format, will close that issue when PR gets merged)*: fixes https://github.com/kubernetes/kubernetes/issues/39372

```release-note
Fix ConfigMap for Windows Containers.
```

cc: @pires
pull/6/head
Kubernetes Submit Queue 2017-02-19 13:50:37 -08:00 committed by GitHub
commit 7236af6162
5 changed files with 136 additions and 48 deletions

View File

@ -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

View File

@ -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)
}

View File

@ -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
}
}

View File

@ -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)
}

View File

@ -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 {