Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix for Support selection of datastore for dynamic provisioning in vS… #41113

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
62 changes: 31 additions & 31 deletions Godeps/Godeps.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

19 changes: 18 additions & 1 deletion examples/volumes/vsphere/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@
__Note: Here you don't need to create vmdk it is created for you.__
1. Create Storage Class.

See example:
Example 1:

```yaml
kind: StorageClass
Expand All @@ -216,6 +216,23 @@

[Download example](vsphere-volume-sc-fast.yaml?raw=true)

You can also specify the datastore in the Storageclass as shown in example 2. The volume will be created on the datastore specified in the storage class.
This field is optional. If not specified as shown in example 1, the volume will be created on the datastore specified in the vsphere config file used to initialize the vSphere Cloud Provider.

Example 2:

```yaml
kind: StorageClass
apiVersion: storage.k8s.io/v1beta1
metadata:
name: fast
provisioner: kubernetes.io/vsphere-volume
parameters:
diskformat: zeroedthick
datastore: VSANDatastore
```

[Download example](vsphere-volume-sc-with-datastore.yaml?raw=true)
Creating the storageclass:

``` bash
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
kind: StorageClass
apiVersion: storage.k8s.io/v1beta1
metadata:
name: fast
provisioner: kubernetes.io/vsphere-volume
parameters:
diskformat: zeroedthick
datastore: vsanDatastore
55 changes: 38 additions & 17 deletions pkg/cloudprovider/providers/vsphere/vsphere.go
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ type VolumeOptions struct {
Tags map[string]string
Name string
DiskFormat string
Datastore string
}

// Generates Valid Options for Diskformat
Expand Down Expand Up @@ -638,36 +639,30 @@ func (vs *VSphere) ScrubDNS(nameservers, searches []string) (nsOut, srchOut []st
}

// Returns vSphere objects virtual machine, virtual device list, datastore and datacenter.
func getVirtualMachineDevices(ctx context.Context, cfg *VSphereConfig, c *govmomi.Client, name string) (*object.VirtualMachine, object.VirtualDeviceList, *object.Datastore, *object.Datacenter, error) {
func getVirtualMachineDevices(ctx context.Context, cfg *VSphereConfig, c *govmomi.Client, name string) (*object.VirtualMachine, object.VirtualDeviceList, *object.Datacenter, error) {
// Create a new finder
f := find.NewFinder(c.Client, true)

// Fetch and set data center
dc, err := f.Datacenter(ctx, cfg.Global.Datacenter)
if err != nil {
return nil, nil, nil, nil, err
return nil, nil, nil, err
}
f.SetDatacenter(dc)

// Find datastores
ds, err := f.Datastore(ctx, cfg.Global.Datastore)
if err != nil {
return nil, nil, nil, nil, err
}

vmRegex := cfg.Global.WorkingDir + name

vm, err := f.VirtualMachine(ctx, vmRegex)
if err != nil {
return nil, nil, nil, nil, err
return nil, nil, nil, err
}

// Get devices from VM
vmDevices, err := vm.Device(ctx)
if err != nil {
return nil, nil, nil, nil, err
return nil, nil, nil, err
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For named return, go allows to use just return. This will return the assigned return values or their defaults.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not needed for now.

}
return vm, vmDevices, ds, dc, nil
return vm, vmDevices, dc, nil
}

// Removes SCSI controller which is latest attached to VM.
Expand Down Expand Up @@ -710,7 +705,7 @@ func (vs *VSphere) AttachDisk(vmDiskPath string, nodeName k8stypes.NodeName) (di
}

// Get VM device list
vm, vmDevices, ds, dc, err := getVirtualMachineDevices(ctx, vs.cfg, vs.client, vSphereInstance)
vm, vmDevices, dc, err := getVirtualMachineDevices(ctx, vs.cfg, vs.client, vSphereInstance)
if err != nil {
return "", "", err
}
Expand Down Expand Up @@ -776,6 +771,23 @@ func (vs *VSphere) AttachDisk(vmDiskPath string, nodeName k8stypes.NodeName) (di
newSCSICreated = true
}

// Create a new finder
f := find.NewFinder(vs.client.Client, true)

// Set data center
f.SetDatacenter(dc)
datastorePathObj := new(object.DatastorePath)
isSuccess := datastorePathObj.FromString(vmDiskPath)
if !isSuccess {
glog.Errorf("Failed to parse vmDiskPath: %+q", vmDiskPath)
return "", "", errors.New("Failed to parse vmDiskPath")
}
ds, err := f.Datastore(ctx, datastorePathObj.Datastore)
if err != nil {
glog.Errorf("Failed while searching for datastore %+q. err %s", datastorePathObj.Datastore, err)
return "", "", err
}

disk := vmDevices.CreateDisk(scsiController, ds.Reference(), vmDiskPath)
unitNumber, err := getNextUnitNumber(vmDevices, scsiController)
if err != nil {
Expand Down Expand Up @@ -940,7 +952,7 @@ func (vs *VSphere) DiskIsAttached(volPath string, nodeName k8stypes.NodeName) (b
}

// Get VM device list
_, vmDevices, _, dc, err := getVirtualMachineDevices(ctx, vs.cfg, vs.client, vSphereInstance)
_, vmDevices, dc, err := getVirtualMachineDevices(ctx, vs.cfg, vs.client, vSphereInstance)
if err != nil {
glog.Errorf("Failed to get VM devices for VM %#q. err: %s", vSphereInstance, err)
return false, err
Expand Down Expand Up @@ -992,7 +1004,7 @@ func (vs *VSphere) DisksAreAttached(volPaths []string, nodeName k8stypes.NodeNam
}

// Get VM device list
_, vmDevices, _, dc, err := getVirtualMachineDevices(ctx, vs.cfg, vs.client, vSphereInstance)
_, vmDevices, dc, err := getVirtualMachineDevices(ctx, vs.cfg, vs.client, vSphereInstance)
if err != nil {
glog.Errorf("Failed to get VM devices for VM %#q. err: %s", vSphereInstance, err)
return attached, err
Expand Down Expand Up @@ -1154,7 +1166,8 @@ func (vs *VSphere) DetachDisk(volPath string, nodeName k8stypes.NodeName) error
vSphereInstance = nodeNameToVMName(nodeName)
}

vm, vmDevices, _, dc, err := getVirtualMachineDevices(ctx, vs.cfg, vs.client, vSphereInstance)
vm, vmDevices, dc, err := getVirtualMachineDevices(ctx, vs.cfg, vs.client, vSphereInstance)

if err != nil {
return err
}
Expand Down Expand Up @@ -1184,6 +1197,14 @@ func (vs *VSphere) DetachDisk(volPath string, nodeName k8stypes.NodeName) error
func (vs *VSphere) CreateVolume(volumeOptions *VolumeOptions) (volumePath string, err error) {

var diskFormat string
var datastore string

// Default datastore is the datastore in the vSphere config file that is used initialize vSphere cloud provider.
if volumeOptions.Datastore == "" {
datastore = vs.cfg.Global.Datastore
} else {
datastore = volumeOptions.Datastore
}

// Default diskformat as 'thin'
if volumeOptions.DiskFormat == "" {
Expand Down Expand Up @@ -1215,9 +1236,9 @@ func (vs *VSphere) CreateVolume(volumeOptions *VolumeOptions) (volumePath string
dc, err := f.Datacenter(ctx, vs.cfg.Global.Datacenter)
f.SetDatacenter(dc)

ds, err := f.Datastore(ctx, vs.cfg.Global.Datastore)
ds, err := f.Datastore(ctx, datastore)
if err != nil {
glog.Errorf("Failed while searching for datastore %+q. err %s", vs.cfg.Global.Datastore, err)
glog.Errorf("Failed while searching for datastore %+q. err %s", datastore, err)
return "", err
}

Expand Down
2 changes: 2 additions & 0 deletions pkg/volume/vsphere_volume/vsphere_volume_util.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ func (util *VsphereDiskUtil) CreateVolume(v *vsphereVolumeProvisioner) (vmDiskPa
switch strings.ToLower(parameter) {
case "diskformat":
volumeOptions.DiskFormat = value
case "datastore":
volumeOptions.Datastore = value
default:
return "", 0, fmt.Errorf("invalid option %q for volume plugin %s", parameter, v.plugin.GetPluginName())
}
Expand Down