Skip to content
This repository was archived by the owner on Mar 22, 2018. It is now read-only.

Commit 8625286

Browse files
committed
Merge branch 'master' into upgrade_aliases_branch
2 parents 6edc12e + a81422a commit 8625286

5 files changed

Lines changed: 98 additions & 0 deletions

File tree

pkg/cloudprovider/providers/openstack/BUILD

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ go_library(
2929
"//vendor/github.com/golang/glog:go_default_library",
3030
"//vendor/github.com/gophercloud/gophercloud:go_default_library",
3131
"//vendor/github.com/gophercloud/gophercloud/openstack:go_default_library",
32+
"//vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/extensions/volumeactions:go_default_library",
3233
"//vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v1/volumes:go_default_library",
3334
"//vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v2/volumes:go_default_library",
3435
"//vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/attachinterfaces:go_default_library",
@@ -51,6 +52,7 @@ go_library(
5152
"//vendor/github.com/prometheus/client_golang/prometheus:go_default_library",
5253
"//vendor/gopkg.in/gcfg.v1:go_default_library",
5354
"//vendor/k8s.io/api/core/v1:go_default_library",
55+
"//vendor/k8s.io/apimachinery/pkg/api/resource:go_default_library",
5456
"//vendor/k8s.io/apimachinery/pkg/types:go_default_library",
5557
"//vendor/k8s.io/apimachinery/pkg/util/net:go_default_library",
5658
"//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library",

pkg/cloudprovider/providers/openstack/openstack_volumes.go

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,11 @@ import (
2424
"strings"
2525
"time"
2626

27+
"k8s.io/apimachinery/pkg/api/resource"
2728
k8s_volume "k8s.io/kubernetes/pkg/volume"
2829

2930
"github.com/gophercloud/gophercloud"
31+
volumeexpand "github.com/gophercloud/gophercloud/openstack/blockstorage/extensions/volumeactions"
3032
volumes_v1 "github.com/gophercloud/gophercloud/openstack/blockstorage/v1/volumes"
3133
volumes_v2 "github.com/gophercloud/gophercloud/openstack/blockstorage/v2/volumes"
3234
"github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/volumeattach"
@@ -39,6 +41,7 @@ type volumeService interface {
3941
createVolume(opts VolumeCreateOpts) (string, string, error)
4042
getVolume(volumeID string) (Volume, error)
4143
deleteVolume(volumeName string) error
44+
expandVolume(volumeID string, newSize int) error
4245
}
4346

4447
// Volumes implementation for v1
@@ -64,6 +67,8 @@ type Volume struct {
6467
Name string
6568
// Current status of the volume.
6669
Status string
70+
// Volume size in GB
71+
Size int
6772
}
6873

6974
type VolumeCreateOpts struct {
@@ -139,6 +144,7 @@ func (volumes *VolumesV1) getVolume(volumeID string) (Volume, error) {
139144
ID: volumeV1.ID,
140145
Name: volumeV1.Name,
141146
Status: volumeV1.Status,
147+
Size: volumeV1.Size,
142148
}
143149

144150
if len(volumeV1.Attachments) > 0 && volumeV1.Attachments[0]["server_id"] != nil {
@@ -162,6 +168,7 @@ func (volumes *VolumesV2) getVolume(volumeID string) (Volume, error) {
162168
ID: volumeV2.ID,
163169
Name: volumeV2.Name,
164170
Status: volumeV2.Status,
171+
Size: volumeV2.Size,
165172
}
166173

167174
if len(volumeV2.Attachments) > 0 {
@@ -188,6 +195,30 @@ func (volumes *VolumesV2) deleteVolume(volumeID string) error {
188195
return err
189196
}
190197

198+
func (volumes *VolumesV1) expandVolume(volumeID string, newSize int) error {
199+
startTime := time.Now()
200+
create_opts := volumeexpand.ExtendSizeOpts{
201+
NewSize: newSize,
202+
}
203+
err := volumeexpand.ExtendSize(volumes.blockstorage, volumeID, create_opts).ExtractErr()
204+
timeTaken := time.Since(startTime).Seconds()
205+
recordOpenstackOperationMetric("expand_volume", timeTaken, err)
206+
207+
return err
208+
}
209+
210+
func (volumes *VolumesV2) expandVolume(volumeID string, newSize int) error {
211+
startTime := time.Now()
212+
create_opts := volumeexpand.ExtendSizeOpts{
213+
NewSize: newSize,
214+
}
215+
err := volumeexpand.ExtendSize(volumes.blockstorage, volumeID, create_opts).ExtractErr()
216+
timeTaken := time.Since(startTime).Seconds()
217+
recordOpenstackOperationMetric("expand_volume", timeTaken, err)
218+
219+
return err
220+
}
221+
191222
func (os *OpenStack) OperationPending(diskName string) (bool, string, error) {
192223
volume, err := os.getVolume(diskName)
193224
if err != nil {
@@ -274,6 +305,39 @@ func (os *OpenStack) DetachDisk(instanceID, volumeID string) error {
274305
return nil
275306
}
276307

308+
// ExpandVolume expands the size of specific cinder volume (in GiB)
309+
func (os *OpenStack) ExpandVolume(volumeID string, oldSize resource.Quantity, newSize resource.Quantity) (resource.Quantity, error) {
310+
volume, err := os.getVolume(volumeID)
311+
if err != nil {
312+
return oldSize, err
313+
}
314+
if volume.Status != VolumeAvailableStatus {
315+
// cinder volume can not be expanded if its status is not available
316+
return oldSize, fmt.Errorf("volume status is not available")
317+
}
318+
319+
volSizeBytes := newSize.Value()
320+
// Cinder works with gigabytes, convert to GiB with rounding up
321+
volSizeGB := int(k8s_volume.RoundUpSize(volSizeBytes, 1024*1024*1024))
322+
newSizeQuant := resource.MustParse(fmt.Sprintf("%dGi", volSizeGB))
323+
324+
// if volume size equals to or greater than the newSize, return nil
325+
if volume.Size >= volSizeGB {
326+
return newSizeQuant, nil
327+
}
328+
329+
volumes, err := os.volumeService("")
330+
if err != nil {
331+
return oldSize, err
332+
}
333+
334+
err = volumes.expandVolume(volumeID, volSizeGB)
335+
if err != nil {
336+
return oldSize, err
337+
}
338+
return newSizeQuant, nil
339+
}
340+
277341
// getVolume retrieves Volume by its ID.
278342
func (os *OpenStack) getVolume(volumeID string) (Volume, error) {
279343
volumes, err := os.volumeService("")

pkg/volume/cinder/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ go_test(
5252
"//pkg/volume/testing:go_default_library",
5353
"//vendor/github.com/golang/glog:go_default_library",
5454
"//vendor/k8s.io/api/core/v1:go_default_library",
55+
"//vendor/k8s.io/apimachinery/pkg/api/resource:go_default_library",
5556
"//vendor/k8s.io/apimachinery/pkg/types:go_default_library",
5657
"//vendor/k8s.io/client-go/util/testing:go_default_library",
5758
],

pkg/volume/cinder/attacher_test.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222
"testing"
2323

2424
"k8s.io/api/core/v1"
25+
"k8s.io/apimachinery/pkg/api/resource"
2526
"k8s.io/kubernetes/pkg/cloudprovider"
2627
"k8s.io/kubernetes/pkg/volume"
2728
volumetest "k8s.io/kubernetes/pkg/volume/testing"
@@ -583,6 +584,10 @@ func (testcase *testcase) InstanceID() (string, error) {
583584
return testcase.instanceID, nil
584585
}
585586

587+
func (testcase *testcase) ExpandVolume(volumeID string, oldSize resource.Quantity, newSize resource.Quantity) (resource.Quantity, error) {
588+
return resource.Quantity{}, nil
589+
}
590+
586591
func (testcase *testcase) DeleteVolume(volumeID string) error {
587592
return errors.New("Not implemented")
588593
}

pkg/volume/cinder/cinder.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ type CinderProvider interface {
5555
DisksAreAttached(instanceID string, volumeIDs []string) (map[string]bool, error)
5656
ShouldTrustDevicePath() bool
5757
Instances() (cloudprovider.Instances, bool)
58+
ExpandVolume(volumeID string, oldSize resource.Quantity, newSize resource.Quantity) (resource.Quantity, error)
5859
}
5960

6061
type cinderPlugin struct {
@@ -227,6 +228,31 @@ func (plugin *cinderPlugin) ConstructVolumeSpec(volumeName, mountPath string) (*
227228
return volume.NewSpecFromVolume(cinderVolume), nil
228229
}
229230

231+
var _ volume.ExpandableVolumePlugin = &cinderPlugin{}
232+
233+
func (plugin *cinderPlugin) ExpandVolumeDevice(spec *volume.Spec, newSize resource.Quantity, oldSize resource.Quantity) (resource.Quantity, error) {
234+
cinder, _, err := getVolumeSource(spec)
235+
if err != nil {
236+
return oldSize, err
237+
}
238+
cloud, err := plugin.getCloudProvider()
239+
if err != nil {
240+
return oldSize, err
241+
}
242+
243+
expandedSize, err := cloud.ExpandVolume(cinder.VolumeID, oldSize, newSize)
244+
if err != nil {
245+
return oldSize, err
246+
}
247+
248+
glog.V(2).Infof("volume %s expanded to new size %d successfully", cinder.VolumeID, int(newSize.Value()))
249+
return expandedSize, nil
250+
}
251+
252+
func (plugin *cinderPlugin) RequiresFSResize() bool {
253+
return true
254+
}
255+
230256
// Abstract interface to PD operations.
231257
type cdManager interface {
232258
// Attaches the disk to the kubelet's host machine.

0 commit comments

Comments
 (0)