support storage class in Cinder provisioner

Signed-off-by: Huamin Chen <hchen@redhat.com>
This commit is contained in:
Huamin Chen 2016-08-17 15:24:53 -04:00
parent cfe7a4391a
commit 259bce370e
7 changed files with 47 additions and 8 deletions

View File

@ -105,6 +105,22 @@ parameters:
* `restuser` : Gluster REST service user who has access to create volumes in the Gluster Trusted Pool. * `restuser` : Gluster REST service user who has access to create volumes in the Gluster Trusted Pool.
* `restuserkey` : Gluster REST service user's password which will be used for authentication to the REST server. * `restuserkey` : Gluster REST service user's password which will be used for authentication to the REST server.
#### OpenStack Cinder
```yaml
kind: StorageClass
apiVersion: extensions/v1beta1
metadata:
name: gold
provisioner: kubernetes.io/cinder
parameters:
type: fast
availability: nova
```
* `type`: [VolumeType](http://docs.openstack.org/admin-guide/dashboard-manage-volumes.html) created in Cinder. Default is empty.
* `availability`: Availability Zone. Default is empty.
### User provisioning requests ### User provisioning requests
Users request dynamically provisioned storage by including a storage class in their `PersistentVolumeClaim`. Users request dynamically provisioned storage by including a storage class in their `PersistentVolumeClaim`.

View File

@ -268,7 +268,7 @@ func TestVolumes(t *testing.T) {
tags := map[string]string{ tags := map[string]string{
"test": "value", "test": "value",
} }
vol, err := os.CreateVolume("kubernetes-test-volume-"+rand.String(10), 1, &tags) vol, err := os.CreateVolume("kubernetes-test-volume-"+rand.String(10), 1, "", "", &tags)
if err != nil { if err != nil {
t.Fatalf("Cannot create a new Cinder volume: %v", err) t.Fatalf("Cannot create a new Cinder volume: %v", err)
} }

View File

@ -136,7 +136,7 @@ func (os *OpenStack) getVolume(diskName string) (volumes.Volume, error) {
} }
// Create a volume of given size (in GiB) // Create a volume of given size (in GiB)
func (os *OpenStack) CreateVolume(name string, size int, tags *map[string]string) (volumeName string, err error) { func (os *OpenStack) CreateVolume(name string, size int, vtype, availability string, tags *map[string]string) (volumeName string, err error) {
sClient, err := openstack.NewBlockStorageV1(os.provider, gophercloud.EndpointOpts{ sClient, err := openstack.NewBlockStorageV1(os.provider, gophercloud.EndpointOpts{
Region: os.region, Region: os.region,
@ -148,8 +148,10 @@ func (os *OpenStack) CreateVolume(name string, size int, tags *map[string]string
} }
opts := volumes.CreateOpts{ opts := volumes.CreateOpts{
Name: name, Name: name,
Size: size, Size: size,
VolumeType: vtype,
Availability: availability,
} }
if tags != nil { if tags != nil {
opts.Metadata = *tags opts.Metadata = *tags

View File

@ -475,7 +475,7 @@ func (os *Rackspace) GetZone() (cloudprovider.Zone, error) {
} }
// Create a volume of given size (in GiB) // Create a volume of given size (in GiB)
func (rs *Rackspace) CreateVolume(name string, size int, tags *map[string]string) (volumeName string, err error) { func (rs *Rackspace) CreateVolume(name string, size int, vtype, availability string, tags *map[string]string) (volumeName string, err error) {
return "", errors.New("unimplemented") return "", errors.New("unimplemented")
} }

View File

@ -391,7 +391,7 @@ func (testcase *testcase) GetAttachmentDiskPath(instanceID string, diskName stri
return expected.retPath, expected.ret return expected.retPath, expected.ret
} }
func (testcase *testcase) CreateVolume(name string, size int, tags *map[string]string) (volumeName string, err error) { func (testcase *testcase) CreateVolume(name string, size int, vtype, availability string, tags *map[string]string) (volumeName string, err error) {
return "", errors.New("Not implemented") return "", errors.New("Not implemented")
} }

View File

@ -45,7 +45,7 @@ type CinderProvider interface {
AttachDisk(instanceID string, diskName string) (string, error) AttachDisk(instanceID string, diskName string) (string, error)
DetachDisk(instanceID string, partialDiskId string) error DetachDisk(instanceID string, partialDiskId string) error
DeleteVolume(volumeName string) error DeleteVolume(volumeName string) error
CreateVolume(name string, size int, tags *map[string]string) (volumeName string, err error) CreateVolume(name string, size int, vtype, availability string, tags *map[string]string) (volumeName string, err error)
GetDevicePath(diskId string) string GetDevicePath(diskId string) string
InstanceID() (string, error) InstanceID() (string, error)
GetAttachmentDiskPath(instanceID string, diskName string) (string, error) GetAttachmentDiskPath(instanceID string, diskName string) (string, error)

View File

@ -18,7 +18,9 @@ package cinder
import ( import (
"errors" "errors"
"fmt"
"os" "os"
"strings"
"time" "time"
"github.com/golang/glog" "github.com/golang/glog"
@ -139,7 +141,26 @@ func (util *CinderDiskUtil) CreateVolume(c *cinderVolumeProvisioner) (volumeID s
// Cinder works with gigabytes, convert to GiB with rounding up // Cinder works with gigabytes, convert to GiB with rounding up
volSizeGB := int(volume.RoundUpSize(volSizeBytes, 1024*1024*1024)) volSizeGB := int(volume.RoundUpSize(volSizeBytes, 1024*1024*1024))
name := volume.GenerateVolumeName(c.options.ClusterName, c.options.PVName, 255) // Cinder volume name can have up to 255 characters name := volume.GenerateVolumeName(c.options.ClusterName, c.options.PVName, 255) // Cinder volume name can have up to 255 characters
name, err = cloud.CreateVolume(name, volSizeGB, c.options.CloudTags) vtype := ""
availability := ""
// Apply ProvisionerParameters (case-insensitive). We leave validation of
// the values to the cloud provider.
for k, v := range c.options.Parameters {
switch strings.ToLower(k) {
case "type":
vtype = v
case "availability":
availability = v
default:
return "", 0, fmt.Errorf("invalid option %q for volume plugin %s", k, c.plugin.GetPluginName())
}
}
// TODO: implement c.options.ProvisionerSelector parsing
if c.options.Selector != nil {
return "", 0, fmt.Errorf("claim.Spec.Selector is not supported for dynamic provisioning on Cinder")
}
name, err = cloud.CreateVolume(name, volSizeGB, vtype, availability, c.options.CloudTags)
if err != nil { if err != nil {
glog.V(2).Infof("Error creating cinder volume: %v", err) glog.V(2).Infof("Error creating cinder volume: %v", err)
return "", 0, err return "", 0, err