mirror of https://github.com/k3s-io/k3s
Merge pull request #69484 from ddebroy/ddebroy-winpipe1
Correctly handle named pipe host mounts for Windowspull/58/head
commit
63a7e06eb5
|
@ -128,7 +128,6 @@ func (kl *Kubelet) makeBlockVolumes(pod *v1.Pod, container *v1.Container, podVol
|
|||
|
||||
// makeMounts determines the mount points for the given container.
|
||||
func makeMounts(pod *v1.Pod, podDir string, container *v1.Container, hostName, hostDomain, podIP string, podVolumes kubecontainer.VolumeMap, mounter mountutil.Interface, expandEnvs []kubecontainer.EnvVar) ([]kubecontainer.Mount, func(), error) {
|
||||
|
||||
// Kubernetes only mounts on /etc/hosts if:
|
||||
// - container is not an infrastructure (pause) container
|
||||
// - container is not already mounting on /etc/hosts
|
||||
|
@ -216,13 +215,13 @@ 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.HasPrefix(hostPath, "\\")) && !strings.Contains(hostPath, ":") {
|
||||
hostPath = "c:" + hostPath
|
||||
}
|
||||
if volumeutil.IsWindowsLocalPath(runtime.GOOS, hostPath) {
|
||||
hostPath = volumeutil.MakeAbsolutePath(runtime.GOOS, hostPath)
|
||||
}
|
||||
if !filepath.IsAbs(containerPath) {
|
||||
|
||||
containerPath := mount.MountPath
|
||||
// IsAbs returns false for UNC path/SMB shares/named pipes in Windows. So check for those specifically and skip MakeAbsolutePath
|
||||
if !volumeutil.IsWindowsUNCPath(runtime.GOOS, containerPath) && !filepath.IsAbs(containerPath) {
|
||||
containerPath = volumeutil.MakeAbsolutePath(runtime.GOOS, containerPath)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
// +build windows
|
||||
|
||||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
|
@ -50,6 +48,21 @@ func TestMakeMountsWindows(t *testing.T) {
|
|||
Name: "disk5",
|
||||
ReadOnly: false,
|
||||
},
|
||||
{
|
||||
MountPath: `\mnt\path6`,
|
||||
Name: "disk6",
|
||||
ReadOnly: false,
|
||||
},
|
||||
{
|
||||
MountPath: `/mnt/path7`,
|
||||
Name: "disk7",
|
||||
ReadOnly: false,
|
||||
},
|
||||
{
|
||||
MountPath: `\\.\pipe\pipe1`,
|
||||
Name: "pipe1",
|
||||
ReadOnly: false,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -57,6 +70,9 @@ func TestMakeMountsWindows(t *testing.T) {
|
|||
"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"}},
|
||||
"disk6": kubecontainer.VolumeInfo{Mounter: &stubVolume{path: `/mnt/disk6`}},
|
||||
"disk7": kubecontainer.VolumeInfo{Mounter: &stubVolume{path: `\mnt\disk7`}},
|
||||
"pipe1": kubecontainer.VolumeInfo{Mounter: &stubVolume{path: `\\.\pipe\pipe1`}},
|
||||
}
|
||||
|
||||
pod := v1.Pod{
|
||||
|
@ -97,6 +113,27 @@ func TestMakeMountsWindows(t *testing.T) {
|
|||
ReadOnly: false,
|
||||
SELinuxRelabel: false,
|
||||
},
|
||||
{
|
||||
Name: "disk6",
|
||||
ContainerPath: `c:\mnt\path6`,
|
||||
HostPath: `c:/mnt/disk6`,
|
||||
ReadOnly: false,
|
||||
SELinuxRelabel: false,
|
||||
},
|
||||
{
|
||||
Name: "disk7",
|
||||
ContainerPath: `c:/mnt/path7`,
|
||||
HostPath: `c:\mnt\disk7`,
|
||||
ReadOnly: false,
|
||||
SELinuxRelabel: false,
|
||||
},
|
||||
{
|
||||
Name: "pipe1",
|
||||
ContainerPath: `\\.\pipe\pipe1`,
|
||||
HostPath: `\\.\pipe\pipe1`,
|
||||
ReadOnly: false,
|
||||
SELinuxRelabel: false,
|
||||
},
|
||||
}
|
||||
assert.Equal(t, expectedMounts, mounts, "mounts of container %+v", container)
|
||||
}
|
||||
|
|
|
@ -947,6 +947,38 @@ func CheckPersistentVolumeClaimModeBlock(pvc *v1.PersistentVolumeClaim) bool {
|
|||
return utilfeature.DefaultFeatureGate.Enabled(features.BlockVolume) && pvc.Spec.VolumeMode != nil && *pvc.Spec.VolumeMode == v1.PersistentVolumeBlock
|
||||
}
|
||||
|
||||
// IsWindowsUNCPath checks if path is prefixed with \\
|
||||
// This can be used to skip any processing of paths
|
||||
// that point to SMB shares, local named pipes and local UNC path
|
||||
func IsWindowsUNCPath(goos, path string) bool {
|
||||
if goos != "windows" {
|
||||
return false
|
||||
}
|
||||
// Check for UNC prefix \\
|
||||
if strings.HasPrefix(path, `\\`) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// IsWindowsLocalPath checks if path is a local path
|
||||
// prefixed with "/" or "\" like "/foo/bar" or "\foo\bar"
|
||||
func IsWindowsLocalPath(goos, path string) bool {
|
||||
if goos != "windows" {
|
||||
return false
|
||||
}
|
||||
if IsWindowsUNCPath(goos, path) {
|
||||
return false
|
||||
}
|
||||
if strings.Contains(path, ":") {
|
||||
return false
|
||||
}
|
||||
if !(strings.HasPrefix(path, `/`) || strings.HasPrefix(path, `\`)) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// MakeAbsolutePath convert path to absolute path according to GOOS
|
||||
func MakeAbsolutePath(goos, path string) string {
|
||||
if goos != "windows" {
|
||||
|
|
|
@ -2373,6 +2373,148 @@ func TestGetWindowsPath(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestIsWindowsUNCPath(t *testing.T) {
|
||||
tests := []struct {
|
||||
goos string
|
||||
path string
|
||||
isUNCPath bool
|
||||
}{
|
||||
{
|
||||
goos: "linux",
|
||||
path: `/usr/bin`,
|
||||
isUNCPath: false,
|
||||
},
|
||||
{
|
||||
goos: "linux",
|
||||
path: `\\.\pipe\foo`,
|
||||
isUNCPath: false,
|
||||
},
|
||||
{
|
||||
goos: "windows",
|
||||
path: `C:\foo`,
|
||||
isUNCPath: false,
|
||||
},
|
||||
{
|
||||
goos: "windows",
|
||||
path: `\\server\share\foo`,
|
||||
isUNCPath: true,
|
||||
},
|
||||
{
|
||||
goos: "windows",
|
||||
path: `\\?\server\share`,
|
||||
isUNCPath: true,
|
||||
},
|
||||
{
|
||||
goos: "windows",
|
||||
path: `\\?\c:\`,
|
||||
isUNCPath: true,
|
||||
},
|
||||
{
|
||||
goos: "windows",
|
||||
path: `\\.\pipe\valid_pipe`,
|
||||
isUNCPath: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
result := IsWindowsUNCPath(test.goos, test.path)
|
||||
if result != test.isUNCPath {
|
||||
t.Errorf("IsWindowsUNCPath(%v) returned (%v), expected (%v)", test.path, result, test.isUNCPath)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsWindowsLocalPath(t *testing.T) {
|
||||
tests := []struct {
|
||||
goos string
|
||||
path string
|
||||
isWindowsLocalPath bool
|
||||
}{
|
||||
{
|
||||
goos: "linux",
|
||||
path: `/usr/bin`,
|
||||
isWindowsLocalPath: false,
|
||||
},
|
||||
{
|
||||
goos: "linux",
|
||||
path: `\\.\pipe\foo`,
|
||||
isWindowsLocalPath: false,
|
||||
},
|
||||
{
|
||||
goos: "windows",
|
||||
path: `C:\foo`,
|
||||
isWindowsLocalPath: false,
|
||||
},
|
||||
{
|
||||
goos: "windows",
|
||||
path: `:\foo`,
|
||||
isWindowsLocalPath: false,
|
||||
},
|
||||
{
|
||||
goos: "windows",
|
||||
path: `X:\foo`,
|
||||
isWindowsLocalPath: false,
|
||||
},
|
||||
{
|
||||
goos: "windows",
|
||||
path: `\\server\share\foo`,
|
||||
isWindowsLocalPath: false,
|
||||
},
|
||||
{
|
||||
goos: "windows",
|
||||
path: `\\?\server\share`,
|
||||
isWindowsLocalPath: false,
|
||||
},
|
||||
{
|
||||
goos: "windows",
|
||||
path: `\\?\c:\`,
|
||||
isWindowsLocalPath: false,
|
||||
},
|
||||
{
|
||||
goos: "windows",
|
||||
path: `\\.\pipe\valid_pipe`,
|
||||
isWindowsLocalPath: false,
|
||||
},
|
||||
{
|
||||
goos: "windows",
|
||||
path: `foo`,
|
||||
isWindowsLocalPath: false,
|
||||
},
|
||||
{
|
||||
goos: "windows",
|
||||
path: `:foo`,
|
||||
isWindowsLocalPath: false,
|
||||
},
|
||||
{
|
||||
goos: "windows",
|
||||
path: `\foo`,
|
||||
isWindowsLocalPath: true,
|
||||
},
|
||||
{
|
||||
goos: "windows",
|
||||
path: `\foo\bar`,
|
||||
isWindowsLocalPath: true,
|
||||
},
|
||||
{
|
||||
goos: "windows",
|
||||
path: `/foo`,
|
||||
isWindowsLocalPath: true,
|
||||
},
|
||||
{
|
||||
goos: "windows",
|
||||
path: `/foo/bar`,
|
||||
isWindowsLocalPath: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
result := IsWindowsLocalPath(test.goos, test.path)
|
||||
if result != test.isWindowsLocalPath {
|
||||
t.Errorf("isWindowsLocalPath(%v) returned (%v), expected (%v)", test.path, result, test.isWindowsLocalPath)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestMakeAbsolutePath(t *testing.T) {
|
||||
tests := []struct {
|
||||
goos string
|
||||
|
|
Loading…
Reference in New Issue