Merge pull request #80911 from pivotal-k8s/vsphere-windows-volumes

Add support for vSphere volume mount/attach on Windows
This commit is contained in:
Kubernetes Prow Robot 2019-08-27 19:37:10 -07:00 committed by GitHub
commit 77277d3abf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 142 additions and 16 deletions

View File

@ -14,6 +14,9 @@ go_library(
"vsphere_volume.go",
"vsphere_volume_block.go",
"vsphere_volume_util.go",
"vsphere_volume_util_linux.go",
"vsphere_volume_util_unsupported.go",
"vsphere_volume_util_windows.go",
],
importpath = "k8s.io/kubernetes/pkg/volume/vsphere_volume",
deps = [

View File

@ -22,6 +22,7 @@ import (
"fmt"
"os"
"path/filepath"
"runtime"
"time"
"k8s.io/api/core/v1"
@ -207,12 +208,17 @@ func (plugin *vsphereVolumePlugin) GetDeviceMountRefs(deviceMountPath string) ([
// MountDevice mounts device to global mount point.
func (attacher *vsphereVMDKAttacher) MountDevice(spec *volume.Spec, devicePath string, deviceMountPath string) error {
klog.Info("vsphere MountDevice", devicePath, deviceMountPath)
mounter := attacher.host.GetMounter(vsphereVolumePluginName)
notMnt, err := mounter.IsLikelyNotMountPoint(deviceMountPath)
if err != nil {
if os.IsNotExist(err) {
if err := os.MkdirAll(deviceMountPath, 0750); err != nil {
klog.Errorf("Failed to create directory at %#v. err: %s", deviceMountPath, err)
dir := deviceMountPath
if runtime.GOOS == "windows" {
dir = filepath.Dir(deviceMountPath)
}
if err := os.MkdirAll(dir, 0750); err != nil {
klog.Errorf("Failed to create directory at %#v. err: %s", dir, err)
return err
}
notMnt = true

View File

@ -22,6 +22,7 @@ import (
"fmt"
"os"
"path/filepath"
"runtime"
"strings"
"k8s.io/api/core/v1"
@ -241,9 +242,13 @@ func (b *vsphereVolumeMounter) SetUpAt(dir string, mounterArgs volume.MounterArg
return nil
}
if err := os.MkdirAll(dir, 0750); err != nil {
klog.V(4).Infof("Could not create directory %s: %v", dir, err)
return err
if runtime.GOOS != "windows" {
// On Windows, Mount will create the parent of dir and mklink (create a symbolic link) at dir later, so don't create a
// directory at dir now. Otherwise mklink will error: "Cannot create a file when that file already exists".
if err := os.MkdirAll(dir, 0750); err != nil {
klog.Errorf("Could not create directory %s: %v", dir, err)
return err
}
}
options := []string{"bind"}

View File

@ -29,7 +29,6 @@ import (
cloudprovider "k8s.io/cloud-provider"
volumehelpers "k8s.io/cloud-provider/volume/helpers"
"k8s.io/klog"
"k8s.io/kubernetes/pkg/util/mount"
"k8s.io/kubernetes/pkg/volume"
volumeutil "k8s.io/kubernetes/pkg/volume/util"
"k8s.io/legacy-cloud-providers/vsphere"
@ -77,16 +76,6 @@ type VolumeSpec struct {
Labels map[string]string
}
func verifyDevicePath(path string) (string, error) {
if pathExists, err := mount.PathExists(path); err != nil {
return "", fmt.Errorf("Error checking if path exists: %v", err)
} else if pathExists {
return path, nil
}
return "", nil
}
// CreateVolume creates a vSphere volume.
func (util *VsphereDiskUtil) CreateVolume(v *vsphereVolumeProvisioner, selectedNode *v1.Node, selectedZone []string) (volSpec *VolumeSpec, err error) {
var fstype string

View File

@ -0,0 +1,35 @@
// +build linux
/*
Copyright 2019 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 vsphere_volume
import (
"fmt"
"k8s.io/kubernetes/pkg/util/mount"
)
func verifyDevicePath(path string) (string, error) {
if pathExists, err := mount.PathExists(path); err != nil {
return "", fmt.Errorf("Error checking if path exists: %v", err)
} else if pathExists {
return path, nil
}
return "", nil
}

View File

@ -0,0 +1,25 @@
// +build !linux,!windows
/*
Copyright 2019 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 vsphere_volume
import "errors"
func verifyDevicePath(path string) (string, error) {
return "", errors.New("unsupported")
}

View File

@ -0,0 +1,63 @@
// +build windows
/*
Copyright 2019 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 vsphere_volume
import (
"encoding/json"
"fmt"
"os/exec"
"strings"
"k8s.io/klog"
)
type diskInfoResult struct {
Number json.Number
SerialNumber string
}
func verifyDevicePath(path string) (string, error) {
if !strings.Contains(path, diskByIDPath) {
// If this volume has already been mounted then
// its devicePath will have already been converted to a disk number
klog.V(4).Infof("Found vSphere disk attached with disk number %v", path)
return path, nil
}
cmd := exec.Command("powershell", "/c", "Get-Disk | Select Number, SerialNumber | ConvertTo-JSON")
output, err := cmd.Output()
if err != nil {
klog.Errorf("Get-Disk failed, error: %v, output: %q", err, string(output))
return "", err
}
var results []diskInfoResult
if err = json.Unmarshal(output, &results); err != nil {
klog.Errorf("Failed to unmarshal Get-Disk json, output: %q", string(output))
return "", err
}
serialNumber := strings.TrimPrefix(path, diskByIDPath+diskSCSIPrefix)
for _, v := range results {
if v.SerialNumber == serialNumber {
klog.V(4).Infof("Found vSphere disk attached with serial %v", serialNumber)
return v.Number.String(), nil
}
}
return "", fmt.Errorf("unable to find vSphere disk with serial %v", serialNumber)
}