mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-11-04 04:08:16 +00:00 
			
		
		
		
	implement cinder resize
This commit is contained in:
		@@ -29,6 +29,7 @@ go_library(
 | 
			
		||||
        "//vendor/github.com/golang/glog:go_default_library",
 | 
			
		||||
        "//vendor/github.com/gophercloud/gophercloud:go_default_library",
 | 
			
		||||
        "//vendor/github.com/gophercloud/gophercloud/openstack:go_default_library",
 | 
			
		||||
        "//vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/extensions/volumeactions:go_default_library",
 | 
			
		||||
        "//vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v1/volumes:go_default_library",
 | 
			
		||||
        "//vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v2/volumes:go_default_library",
 | 
			
		||||
        "//vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/attachinterfaces:go_default_library",
 | 
			
		||||
@@ -51,6 +52,7 @@ go_library(
 | 
			
		||||
        "//vendor/github.com/prometheus/client_golang/prometheus:go_default_library",
 | 
			
		||||
        "//vendor/gopkg.in/gcfg.v1:go_default_library",
 | 
			
		||||
        "//vendor/k8s.io/api/core/v1:go_default_library",
 | 
			
		||||
        "//vendor/k8s.io/apimachinery/pkg/api/resource:go_default_library",
 | 
			
		||||
        "//vendor/k8s.io/apimachinery/pkg/types:go_default_library",
 | 
			
		||||
        "//vendor/k8s.io/apimachinery/pkg/util/net:go_default_library",
 | 
			
		||||
        "//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library",
 | 
			
		||||
 
 | 
			
		||||
@@ -24,9 +24,11 @@ import (
 | 
			
		||||
	"strings"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"k8s.io/apimachinery/pkg/api/resource"
 | 
			
		||||
	k8s_volume "k8s.io/kubernetes/pkg/volume"
 | 
			
		||||
 | 
			
		||||
	"github.com/gophercloud/gophercloud"
 | 
			
		||||
	volumeexpand "github.com/gophercloud/gophercloud/openstack/blockstorage/extensions/volumeactions"
 | 
			
		||||
	volumes_v1 "github.com/gophercloud/gophercloud/openstack/blockstorage/v1/volumes"
 | 
			
		||||
	volumes_v2 "github.com/gophercloud/gophercloud/openstack/blockstorage/v2/volumes"
 | 
			
		||||
	"github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/volumeattach"
 | 
			
		||||
@@ -39,6 +41,7 @@ type volumeService interface {
 | 
			
		||||
	createVolume(opts VolumeCreateOpts) (string, string, error)
 | 
			
		||||
	getVolume(volumeID string) (Volume, error)
 | 
			
		||||
	deleteVolume(volumeName string) error
 | 
			
		||||
	expandVolume(volumeID string, newSize int) error
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Volumes implementation for v1
 | 
			
		||||
@@ -64,6 +67,8 @@ type Volume struct {
 | 
			
		||||
	Name string
 | 
			
		||||
	// Current status of the volume.
 | 
			
		||||
	Status string
 | 
			
		||||
	// Volume size in GB
 | 
			
		||||
	Size int
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type VolumeCreateOpts struct {
 | 
			
		||||
@@ -139,6 +144,7 @@ func (volumes *VolumesV1) getVolume(volumeID string) (Volume, error) {
 | 
			
		||||
		ID:     volumeV1.ID,
 | 
			
		||||
		Name:   volumeV1.Name,
 | 
			
		||||
		Status: volumeV1.Status,
 | 
			
		||||
		Size:   volumeV1.Size,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if len(volumeV1.Attachments) > 0 && volumeV1.Attachments[0]["server_id"] != nil {
 | 
			
		||||
@@ -162,6 +168,7 @@ func (volumes *VolumesV2) getVolume(volumeID string) (Volume, error) {
 | 
			
		||||
		ID:     volumeV2.ID,
 | 
			
		||||
		Name:   volumeV2.Name,
 | 
			
		||||
		Status: volumeV2.Status,
 | 
			
		||||
		Size:   volumeV2.Size,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if len(volumeV2.Attachments) > 0 {
 | 
			
		||||
@@ -188,6 +195,30 @@ func (volumes *VolumesV2) deleteVolume(volumeID string) error {
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (volumes *VolumesV1) expandVolume(volumeID string, newSize int) error {
 | 
			
		||||
	startTime := time.Now()
 | 
			
		||||
	create_opts := volumeexpand.ExtendSizeOpts{
 | 
			
		||||
		NewSize: newSize,
 | 
			
		||||
	}
 | 
			
		||||
	err := volumeexpand.ExtendSize(volumes.blockstorage, volumeID, create_opts).ExtractErr()
 | 
			
		||||
	timeTaken := time.Since(startTime).Seconds()
 | 
			
		||||
	recordOpenstackOperationMetric("expand_volume", timeTaken, err)
 | 
			
		||||
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (volumes *VolumesV2) expandVolume(volumeID string, newSize int) error {
 | 
			
		||||
	startTime := time.Now()
 | 
			
		||||
	create_opts := volumeexpand.ExtendSizeOpts{
 | 
			
		||||
		NewSize: newSize,
 | 
			
		||||
	}
 | 
			
		||||
	err := volumeexpand.ExtendSize(volumes.blockstorage, volumeID, create_opts).ExtractErr()
 | 
			
		||||
	timeTaken := time.Since(startTime).Seconds()
 | 
			
		||||
	recordOpenstackOperationMetric("expand_volume", timeTaken, err)
 | 
			
		||||
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (os *OpenStack) OperationPending(diskName string) (bool, string, error) {
 | 
			
		||||
	volume, err := os.getVolume(diskName)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
@@ -274,6 +305,39 @@ func (os *OpenStack) DetachDisk(instanceID, volumeID string) error {
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ExpandVolume expands the size of specific cinder volume (in GiB)
 | 
			
		||||
func (os *OpenStack) ExpandVolume(volumeID string, oldSize resource.Quantity, newSize resource.Quantity) (resource.Quantity, error) {
 | 
			
		||||
	volume, err := os.getVolume(volumeID)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return oldSize, err
 | 
			
		||||
	}
 | 
			
		||||
	if volume.Status != VolumeAvailableStatus {
 | 
			
		||||
		// cinder volume can not be expanded if its status is not available
 | 
			
		||||
		return oldSize, fmt.Errorf("volume status is not available")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	volSizeBytes := newSize.Value()
 | 
			
		||||
	// Cinder works with gigabytes, convert to GiB with rounding up
 | 
			
		||||
	volSizeGB := int(k8s_volume.RoundUpSize(volSizeBytes, 1024*1024*1024))
 | 
			
		||||
	newSizeQuant := resource.MustParse(fmt.Sprintf("%dGi", volSizeGB))
 | 
			
		||||
 | 
			
		||||
	// if volume size equals to or greater than the newSize, return nil
 | 
			
		||||
	if volume.Size >= volSizeGB {
 | 
			
		||||
		return newSizeQuant, nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	volumes, err := os.volumeService("")
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return oldSize, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	err = volumes.expandVolume(volumeID, volSizeGB)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return oldSize, err
 | 
			
		||||
	}
 | 
			
		||||
	return newSizeQuant, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// getVolume retrieves Volume by its ID.
 | 
			
		||||
func (os *OpenStack) getVolume(volumeID string) (Volume, error) {
 | 
			
		||||
	volumes, err := os.volumeService("")
 | 
			
		||||
 
 | 
			
		||||
@@ -52,6 +52,7 @@ go_test(
 | 
			
		||||
        "//pkg/volume/testing:go_default_library",
 | 
			
		||||
        "//vendor/github.com/golang/glog:go_default_library",
 | 
			
		||||
        "//vendor/k8s.io/api/core/v1:go_default_library",
 | 
			
		||||
        "//vendor/k8s.io/apimachinery/pkg/api/resource:go_default_library",
 | 
			
		||||
        "//vendor/k8s.io/apimachinery/pkg/types:go_default_library",
 | 
			
		||||
        "//vendor/k8s.io/client-go/util/testing:go_default_library",
 | 
			
		||||
    ],
 | 
			
		||||
 
 | 
			
		||||
@@ -22,6 +22,7 @@ import (
 | 
			
		||||
	"testing"
 | 
			
		||||
 | 
			
		||||
	"k8s.io/api/core/v1"
 | 
			
		||||
	"k8s.io/apimachinery/pkg/api/resource"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/cloudprovider"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/volume"
 | 
			
		||||
	volumetest "k8s.io/kubernetes/pkg/volume/testing"
 | 
			
		||||
@@ -583,6 +584,10 @@ func (testcase *testcase) InstanceID() (string, error) {
 | 
			
		||||
	return testcase.instanceID, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (testcase *testcase) ExpandVolume(volumeID string, oldSize resource.Quantity, newSize resource.Quantity) (resource.Quantity, error) {
 | 
			
		||||
	return resource.Quantity{}, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (testcase *testcase) DeleteVolume(volumeID string) error {
 | 
			
		||||
	return errors.New("Not implemented")
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -55,6 +55,7 @@ type CinderProvider interface {
 | 
			
		||||
	DisksAreAttached(instanceID string, volumeIDs []string) (map[string]bool, error)
 | 
			
		||||
	ShouldTrustDevicePath() bool
 | 
			
		||||
	Instances() (cloudprovider.Instances, bool)
 | 
			
		||||
	ExpandVolume(volumeID string, oldSize resource.Quantity, newSize resource.Quantity) (resource.Quantity, error)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type cinderPlugin struct {
 | 
			
		||||
@@ -227,6 +228,31 @@ func (plugin *cinderPlugin) ConstructVolumeSpec(volumeName, mountPath string) (*
 | 
			
		||||
	return volume.NewSpecFromVolume(cinderVolume), nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var _ volume.ExpandableVolumePlugin = &cinderPlugin{}
 | 
			
		||||
 | 
			
		||||
func (plugin *cinderPlugin) ExpandVolumeDevice(spec *volume.Spec, newSize resource.Quantity, oldSize resource.Quantity) (resource.Quantity, error) {
 | 
			
		||||
	cinder, _, err := getVolumeSource(spec)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return oldSize, err
 | 
			
		||||
	}
 | 
			
		||||
	cloud, err := plugin.getCloudProvider()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return oldSize, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	expandedSize, err := cloud.ExpandVolume(cinder.VolumeID, oldSize, newSize)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return oldSize, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	glog.V(2).Infof("volume %s expanded to new size %d successfully", cinder.VolumeID, int(newSize.Value()))
 | 
			
		||||
	return expandedSize, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (plugin *cinderPlugin) RequiresFSResize() bool {
 | 
			
		||||
	return true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Abstract interface to PD operations.
 | 
			
		||||
type cdManager interface {
 | 
			
		||||
	// Attaches the disk to the kubelet's host machine.
 | 
			
		||||
 
 | 
			
		||||
@@ -152,6 +152,9 @@ func (pvcr *persistentVolumeClaimResize) checkVolumePlugin(pv *api.PersistentVol
 | 
			
		||||
	if pv.Spec.Glusterfs != nil {
 | 
			
		||||
		return true
 | 
			
		||||
	}
 | 
			
		||||
	if pv.Spec.Cinder != nil {
 | 
			
		||||
		return true
 | 
			
		||||
	}
 | 
			
		||||
	return false
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user